原子读操作是在MCU并发编程中常用的操作,简略举个例子来论述问题:
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中,关中止的时刻是一种重要性能指标,决议了整个系统的中止快速呼应才能。
在此假定一个最困难的架构,8位机(AVR、51等等),其上只要8位单字节数据的读写是单指令原子的,其间unsigned long型在这样的架构下是32位8字节。
依据各位朋友提出状况,进行阐明:
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上经常用的,对中止通讯接口的缓冲十分便利牢靠。以此为基础,可跨渠道完结。