MCU上的无锁原子读操作
时间:11-17
来源:互联网
点击:
原子读操作是在MCU并发编程中常用的操作,简单举个例子来阐述问题:
根据各位朋友提出情况,进行说明:
1、有朋友认为读操作没必要关中断.
这个显然不可能,当你读了32位变量任何一个字节的时候,剩下的7个字节都可能改变。
2、认为在中断函数建立数据拷贝
这个理由同上,无论如何复制,都难以避免读的瞬间数据被破坏
3、建立单字节原子锁
该体系必须支持测试清零指令,而且就算支持。如果中断里发现锁被占有了,那这个周期还能进行+1操作么?无论是用变量缓存还是丢弃,所记时间都不准了。
实现如下:
unsigned long get_jiffies(void)
{
unsigned long tmp;
do {
tmp = __jiffies;
} while(tmp != __jiffies);
return tmp
}
简单得大家可能都不相信,可以满足任何MCU架构完成如上对__jiffies变量的操作(必须单核),大家可以仔细想想。
无锁单读单写队列是MCU上经常用的,对中断通信接口的缓冲非常方便可靠。以此为基础,可跨平台实现。
我们使用RTOS或裸机状态编程时,必然需要一个全局时钟基准,通常是在一个定时器中断中累加实现,简化代码如下:
static unsigned long volatile __jiffies = 0; /* 全局时钟基准节拍累加器 */
ISR_TIMER() /* 定时中断服务函数 */
{
++__jiffies;
/* 其它代码...: */
}
对于其中的__jiffies变量,就是全局时间基准,程序中其它地方都会对其进行原子读操作来判断时间,典型的接口实现如下:
unsigned long get_jiffies(void)
{
unsigned long tmp;
CLOCK_IRQ_DIS(); /* 关定时中断 */
tmp = __jiffies;
CLOCK_IRQ_EN(); /* 开定时中断 */
return tmp;
}
请注意,其中关于对中断的开关是对该定时中断中所有代码会带来影响。如果在RTOS中,关中断的时间是一种重要性能指标,决定了整个系统的中断快速响应能力。
根据各位朋友提出情况,进行说明:
1、有朋友认为读操作没必要关中断.
这个显然不可能,当你读了32位变量任何一个字节的时候,剩下的7个字节都可能改变。
2、认为在中断函数建立数据拷贝
这个理由同上,无论如何复制,都难以避免读的瞬间数据被破坏
3、建立单字节原子锁
该体系必须支持测试清零指令,而且就算支持。如果中断里发现锁被占有了,那这个周期还能进行+1操作么?无论是用变量缓存还是丢弃,所记时间都不准了。
实现如下:
unsigned long get_jiffies(void)
{
unsigned long tmp;
do {
tmp = __jiffies;
} while(tmp != __jiffies);
return tmp
}
简单得大家可能都不相信,可以满足任何MCU架构完成如上对__jiffies变量的操作(必须单核),大家可以仔细想想。
无锁单读单写队列是MCU上经常用的,对中断通信接口的缓冲非常方便可靠。以此为基础,可跨平台实现。
MCU无锁原子读操 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)