完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
来源 网络 原子读操作是在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位单字节数据的读写是单指令原子的,其中unsignedlong型在这样的架构下是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上经常用的,对中断通信接口的缓冲非常方便可靠。以此为基础,可跨平台实现。 |
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
2252个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11794 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5968 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11055 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4591 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4323 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1221浏览 1评论
841浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 09:03 , Processed in 0.588268 second(s), Total 41, Slave 33 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号