【IoT】蓝牙BLE基础:CC2541 BLE临界资源保护
【摘要】
1 临界区代码保护示例:
HAL_ENTER_CRITICAL_SECTION(intState); // 进入临界区 events = ac...
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
文章来源: blog.csdn.net,作者:简一商业,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/liwei16611/article/details/74010862
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
作者其他文章
评论(0)