
【IoT】蓝牙BLE基础:CC2541 BLE临界资源保护
发布日期:2021-05-08 10:08:51
浏览次数:19
分类:精选文章
本文共 2295 字,大约阅读时间需要 7 分钟。
1 临界区代码保护示例:
HAL_ENTER_CRITICAL_SECTION(intState); // 进入临界区 events = activeTask->events; activeTask->events = 0; // 清除任务的事件 HAL_EXIT_CRITICAL_SECTION(intState); // 退出临界区
2 相关宏定义如下:
#define st(x) do { x } while (__LINE__ == -1) 注: 1) __LINE__ 是个宏,它代表当前代码在源文件的行号,它是大于0的,所以__LINE__ == -1 等同于0, 上述宏等价于: #define st(x) do { x } while (0) // 表示执行x指令,注意x是一个完整的语句,需要加分号 2)do {} while (0)通常用于宏中, 为的是避免如下情况: #define st(x) x 那么我们在调用 if (0) st(a = b; b = c;) 时会被解释成 if(0) a = b; b = c; 此时 if 只对a = b;起作用 #define HAL_ENABLE_INTERRUPTS() st( EA = 1; ) // 使能总中断 #define HAL_DISABLE_INTERRUPTS() st( EA = 0; ) // 失能总中断 #define HAL_INTERRUPTS_ARE_ENABLED() (EA) typedef unsigned char halIntState_t; #define HAL_ENTER_CRITICAL_SECTION(x) st( x = EA; HAL_DISABLE_INTERRUPTS(); ) #define HAL_EXIT_CRITICAL_SECTION(x) st( EA = x; ) #define HAL_CRITICAL_STATEMENT(x) st( halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); x; HAL_EXIT_CRITICAL_SECTION(s); )1) cc2541芯片中的中断使能的特殊功能寄存器(SFRs): IEN0、IEN1和IEN2
这三个寄存器的不同的位控制了不同的硬件的中断使能,比如IEN2中的第五位WDTIE控制着看门狗时钟的中断使能
其中有一个比较特殊的位是IEN0的第7位,名称为EA,控制着所有中断的使能,为0时将没有中断相应,为1时每一个中断源的使能受相应的位的控制
上面的宏即是用芯片的EA=0来关中断实现临界资源的保护 2)HAL_ENABLE_INTERRUPTS()和HAL_DISABLE_INTERRUPTS()这两个宏分别实现了cc2541的所有中断的开和关 HAL_ENTER_CRITICAL_SECTION(x)宏首先将EA的值保存在变量x中,然后关闭所有中断,进行后面的临界资源处理 HAL_EXIT_CRITICAL_SECTION(x)宏则是恢复刚才保存在x中的EA的值HAL_CRITICAL_STATEMENT(x)宏的功能是将x作为临界代码执行,首先声明了用于保存EA值的变量,然后调用进入临界区宏,执行临界代码x,最后执行退出临
界区的宏
3) HAL_CRITICAL_STATEMENT(x)这个宏,因为st宏的实现中x是一些可以执行的完整c语句,更主要的是写在do{}while()中,它是一个子程序片段,因此x可以做很
多事,比如声明变量等
3 扩展:如何应用于其他平台代码设计
#include <stdio.h>
#define st(x)do{x}while(__LINE__==-1) #define enable()st(EA = 1;)//使能所有中断 #define disable()st(EA = 0;)//关闭所有中断 #define enter(x)st(x = EA; disable();) //进入临界区 #define exit(x)st(EA = x;)//退出临界区 //临界代码执行 #define critical(s)st(int temp; enter(temp); s; exit(temp);) //模拟控制所有中断的变量 int EA = 5; int main() { int a = 0; enter(a); printf("EA=%d, a=%d\n", EA, a); exit(a); critical(printf("hello world-first\n");); critical(printf("hello world-second\n");); // 上面的 critical(printf("hello world-first\n");) 等价代码如下 do { int temp; do { temp = EA; do{ EA = 0; } while(__LINE__==-1); } while(__LINE__==-1); printf("hello world\n"); do{ EA =temp; } while(__LINE__==-1); } while(__LINE__==-1); } 执行结果为: EA=0, a=5 hello world-first hello world-second hello world发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月19日 07时19分24秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
SNMP介绍及使用,超有用,建议收藏!
2021-05-09
SDUT2161:Simple Game(NIM博弈+巴什博弈)
2021-05-09
51nod 1596 搬货物(二进制处理)
2021-05-09
来自星星的祝福(容斥+排列组合)
2021-05-09
Hmz 的女装(递推)
2021-05-09
HDU5589:Tree(莫队+01字典树)
2021-05-09
不停机替换线上代码? 你没听错,Arthas它能做到
2021-05-09
sharding-jdbc 分库分表的 4种分片策略,还蛮简单的
2021-05-09
分库分表的 9种分布式主键ID 生成方案,挺全乎的
2021-05-09
MySQL不会丢失数据的秘密,就藏在它的 7种日志里
2021-05-09
Python开发之序列化与反序列化:pickle、json模块使用详解
2021-05-09
回顾-生成 vs 判别模型-和图
2021-05-09
采坑 - 字符串的 "" 与 pd.isnull()
2021-05-09
无序列表 - 链表
2021-05-09
SQL 查询强化 - 数据准备
2021-05-09
SQL 强化练习 (四)
2021-05-09
SQL 强化练习 (八)
2021-05-09
Excel 拼接为 SQL 并打包 exe
2021-05-09
Pandas数据分析从放弃到入门
2021-05-09