打印
[STM32F1]

单片机中,如果主程序和中断都要读写全局变量, 是不是加上volatile也不可靠?

[复制链接]
4585|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yaoyutaoTom|  楼主 | 2016-3-3 09:43 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机中,如果主程序和中断都要读写全局变量, 是不是加上volatile也不可靠?如果想可靠,一定要实现原子操作吗?
沙发
neeringstu| | 2016-3-3 16:05 | 只看该作者
主程序和中断在读写这个全局变量的时候在时间点上能分开吗?

使用特权

评论回复
板凳
zzu65| | 2016-3-3 19:21 | 只看该作者
主程序与中断都要读,或者一个读一个写都无所谓,只有都需要写的时候需要互斥访问。
主程序在写之前关中断,写完再开中断,这个操作不能太长,否则影响中断响应。
如果跑操作系统的话,可以用信号量。

使用特权

评论回复
地板
戈卫东| | 2016-3-3 19:42 | 只看该作者
不行就关中断吧。主程序访问时关中断就没有问题了,完了再开。

使用特权

评论回复
5
戈卫东| | 2016-3-3 19:43 | 只看该作者
不过很多时候不需要这么麻烦。比如说中断会给出一个信号然后一定的时间内不会再次访问这个变量那就可以不需要关中断。

使用特权

评论回复
6
zhlcd| | 2016-3-3 20:38 | 只看该作者
"主程序和中断都要读写全局变量"

这样为什么就不可靠呢?   难度CPU 会进入硬件 异常? 呵呵






使用特权

评论回复
7
zchong| | 2016-3-4 08:32 | 只看该作者
这个要根据使用场景具体分析才行

使用特权

评论回复
8
airwill| | 2016-3-4 18:11 | 只看该作者
楼主考虑得很详细. 确实是这样的
Cotrex M3 内核已经摈弃了原来的原子操作指令, 使用 LDREX 系列指令来实现.

使用特权

评论回复
9
yaoyutaoTom|  楼主 | 2016-3-7 15:05 | 只看该作者
airwill 发表于 2016-3-4 18:11
楼主考虑得很详细. 确实是这样的
Cotrex M3 内核已经摈弃了原来的原子操作指令, 使用 LDREX 系列指令来实现 ...

可平时,也没见出过啥问题?

使用特权

评论回复
10
wang1216| | 2016-3-7 16:27 | 只看该作者
加voltile只不过是告诉编译器不要把这个 变量优化没了,其它作用没有

使用特权

评论回复
11
airwill| | 2016-3-7 20:49 | 只看该作者
yaoyutaoTom 发表于 2016-3-7 15:05
可平时,也没见出过啥问题?

那也就是平时咯, 怎么说呢, 也许你的软件玩得还不够多, 或者有些问题你还没有注意到吧

使用特权

评论回复
12
yaoyutaoTom|  楼主 | 2016-3-8 08:41 | 只看该作者
airwill 发表于 2016-3-7 20:49
那也就是平时咯, 怎么说呢, 也许你的软件玩得还不够多, 或者有些问题你还没有注意到吧 ...

通常怎么实现原子操作,关中断不用考虑,是再设个全局变量做开关吗?考虑起来好像有点复杂?

使用特权

评论回复
13
airwill| | 2016-3-8 09:15 | 只看该作者
再设个全局变量做开关? 那这个全局变量又存在同样的原子操作问题了!
如果是 STM32,  你可以使用 STREX, LDREX 指令来实现. 这是 ARM 官方给出的最佳解决方案.

使用特权

评论回复
14
R2D2| | 2021-2-9 15:20 | 只看该作者
zzu65 发表于 2016-3-3 19:21
主程序与中断都要读,或者一个读一个写都无所谓,只有都需要写的时候需要互斥访问。
主程序在写之前关中断 ...

一读一写一样会出问题。举个栗子,在8位单片机中,int是16位的。那么int i++会分解成如下操作
①i.low++
②if overflow carry=1
③i.high+carry
如果上述操作是在主函数里面被调用的,设i=0xff,那么在③之前,①之后发生中断,读取i的值,会读到0x00这个完全不合理的值,中断程序会进入到异常状态。就需要在i++之前关中断,在i++之后开中断。

对于stm32来说,8位、16位、32位操作都是原子的,不需要关中断。但是对于数组操作呢???就需要在操作数组之前置标志位,表示数据不可用,等写数组完毕之后清标志位,表示数据有效。

不光是单片机中断要注意原子操作,电脑上编程,多线程通过全局变量共享数据,也要注意原子操作。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

96

帖子

2

粉丝