本文以stm32为硬件平台,浅谈一下变量访问的互斥。

假设是裸板,主程序和中断服务程序都对某个变量进行修改,那么很可能造成数据的不一致。查了一下,主要有两种解决方法:第一种是关中断,在访问公共资源的时候,先把中断关掉,等访问完毕,再打开中断。这样就避免了中断程序和主程序的竞态。第二种是自己做一个互斥锁。

怎么做互斥锁呢?其实互斥是要依赖与硬件的,如果硬件没有相关的指令或者机制,那就不好办了。

在x86上,可以用汇编指令XCHG做一个互斥锁,但是stm32上就没有这个指令。在翻阅了《Cortex-M3权威指南》后,我有个发现。下面总结一下:

互斥访问分为加载和存储,对应的指令对是LDREX/STREX,LDREXH/STREXH,LDREXB/STREXB,分别对应字,半字,字节。

LDREX/STREX的语法格式为:

LDREX    Rxf,    [Rn, #offset]    ; 把 (Rn+offset)地址处的内容加载到寄存器 Rxf里

STREX    Rd, Rxf, [Rn, #offset] ;把Rxf的值存储到(Rn+offset)地址处,这个操作是可以被驳回的(也就是不被执行),如果驳回,Rd的值为1,如果操作成功,Rd的值为0.

在什么情况下会被驳回呢?在执行STREX的时候,仅当在这之前执行过LDREX指令,且在执行过LDREX指令之后没有其他的STR/STREX指令执行过的时候,才允许执行这个指令。也就是说只有在LDREX执行后的第一条STREX才能成功执行。

这个道理是易于理解的,在读,改,写的过程中,我们希望读的数据是最新的,也就是读过之后,这个数据不能被别人更新,只能被我更新。如果操作被驳回,说明别人已经修改过了,所以我读出的数据不是最新的,已经“脏了”。

关于例子文中有,这里就不赘述了。

用这对指令,就可以做一个互斥锁。怎么做呢?还是以《Cortex-M3权威指南》中的一个例子来说明。

记DeviceALocked是一个位于内存中的R/W变量,用于指示设备A是否已经在使用中。任何一个任务,若欲使用设备A,都必须先检查这个变量的值。如果它的值为零,则表示设备可以使用。在任务获取到设备A后,它要把DeviceALocked的值改为1,表示设备A已经被占用。在设备A使用完毕后,该任务通过重新清零DeviceALocked来释放设备A,从而使其它任务可以使用此设备。

TryToLockDeviceA
LDR   R1, =DeviceALocked

LDREX R2, [R1]

CMP   R2, #0          ;检查是否已被锁住

BNE LockDeviceAFailed

DeviceAIsNotLocked
MOV   R0, #1           ;准备锁住设备A
STREX R2, R0, [R1]     ;互斥写

CMP   R2, #0
BNE LockDeviceAFailed  ;STREX失败,设备A可能已被锁; 准备返回成功值

LockDeviceASucceed
MOV   R0, #0

POP   {R1, R2, PC}     ;子程序返回

LockDeviceAFailed
MOV   R0, #1

POP   {R1, R2, PC}     ;子程序返回

浅谈单片机中变量访问的互斥相关推荐

  1. 浅谈单片机程序设计中的“分层思想”!

    浅谈单片机程序设计中的"分层思想",并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用.看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种 ...

  2. python命名规则数字开头的成语_浅谈Python中带_的变量或函数命名

    搜索热词 Python 的代码风格由 PEP 8 描述.这个文档描述了 Python 编程风格的方方面面.在遵守这个文档的条件下,不同程序员编写的 Python 代码可以保持最大程度的相似风格.这样就 ...

  3. python中 是什么类型_浅谈python中的变量默认是什么类型

    浅谈python中的变量默认是什么类型 1.type(变量名),输出的结果就是变量的类型: 例如 >>> type(6) 2.在Python里面变量在声明时,不需要指定变量的类型,变 ...

  4. linux中sh+$0,浅谈linux中shell变量$#,$@,$0,$1,$2的含义解释

    摘抄自:ABS_GUIDE 下载地址:http://www.tldp.org/LDP/abs/abs-guide.pdf linux中shell变量$#,$@,$0,$1,$2的含义解释: 变量说明: ...

  5. 浅谈linux中shell变量$#,$@,$0,$1,$2,$?的含义解释

    浅谈linux中shell变量$#,$@,$0,$1,$2,$?的含义解释 下面小编就为大家带来一篇浅谈linux中shell变量$#,$@,$0,$1,$2的含义解释.小编觉得挺不错的,现在就分享给 ...

  6. python sys模块作用_浅谈Python中的模块

    模块 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很多编程语言都采用这种组织代码的方式.在Python中,一个.py文件就称之为一个模块(Mod ...

  7. Linux先发送条件变量,浅谈Linux条件变量的使用

    Linux线程同步之间存在多种机制,条件变量是一种类似操作系统里提到的生产者-消费者算法的同步机制,允许线程以无竞争的方式等待特定条件的发生. 示例伪代码: void* Thread1(void){ ...

  8. python文件路径拼接多出斜杠_浅谈python中拼接路径os.path.join斜杠的问题

    浅谈python中拼接路径os.path.join斜杠的问题 调试程序的过程中,发现通过os.path.join拼接的路径出现了反斜杠 directory1='/opt/apps/upgradePac ...

  9. Linux先发送条件变量,linux 条件变量 浅谈Linux条件变量的使用

    想了解浅谈Linux条件变量的使用的相关内容吗,在本文为您仔细讲解linux 条件变量的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:linux,条件变量,下面大家一起来学习吧. Linu ...

最新文章

  1. SAP Fiori + Vue = ?
  2. Scala样例类及密封类
  3. 计算机屏幕显示电缆借口,电脑关机后显示器显示请检查电缆接口怎么办成功解决...
  4. linux安装trac+svn+apache+wike,windos中Trac+apache+svn的安装与配置
  5. Spring Security-- 验证码功能的实现
  6. linux vim debugger,Vim 调试:termdebug 入门
  7. 【安卓开发】项目的目录结构分析
  8. CentOS 8安装Redis的两种方式
  9. 华为向emui输入鸿蒙,新颜值/新功能/新体验!EMUI 11上手:手机鸿蒙OS的提前预演...
  10. CSUOJ 1010: Water Drinking
  11. 从0到1亿美元 ---- PopCap创始人John Vechey自述
  12. DG449 High Voltage Single SPDT Analog Switch in SOT23-8
  13. 日常维护SQL以及脚本
  14. 部分选主元matlab,列选主元的高斯消去法-matlab
  15. 资深架构师推荐Spring技术内幕:深入了解Spring的底层机制
  16. 「Do.024」如何更高效使用MacBook
  17. linux安装.rpm包及rpm命令
  18. 2022年机器人工程毕业设计选题情况
  19. uniapp获取微信小程序openid
  20. 能改变你一生的五句话

热门文章

  1. 代码审计之CVE-2018-7600-Drupal远程代码执行漏洞-Render API
  2. 生成模型与判别模型区别
  3. cmd命令大全 DOS窗口命令
  4. Siverlight5新功能/改进总结
  5. 在PowerDesigner中设置字段唯一约束 --相当于unique
  6. MSDN演练时发现的SqlServer2005数据库连接问题
  7. 双指针解决数组排序问题
  8. Python学习笔记:web开发3
  9. 多进程与多线程的区别 - jihite
  10. [云炬创业基础笔记]第四章测试21