您的位置 首页 软件

MCU上的无锁原子读操作

原子读操作是在MCU并发编程中常用的操作,简单举个例子来阐述问题:我们使用RTOS或裸机状态编程时,必然需要一个全局时钟基准,通常是在一…

原子读操作是在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中,关中止的时刻是一种重要性能指标,决议了整个系统的中止快速呼应才能。

在此假定一个最困难的架构,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上经常用的,对中止通讯接口的缓冲十分便利牢靠。以此为基础,可跨渠道完结。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/ruanjian/268342.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部