【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
 

上一篇:【IoT】TI BLE CC2541 串口控制蓝牙详解
下一篇:【企业】海底捞,知多少? 学什么?

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月19日 07时19分24秒