蓝牙BLE基础:CC2541 BLE临界资源保护
来源:互联网 发布:淘宝怎么装修模板 编辑:程序博客网 时间:2024/05/17 21:49
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
阅读全文
1 0
- 蓝牙BLE基础:CC2541 BLE临界资源保护
- 蓝牙BLE基础:CC2541通信系列之模拟IIC协议
- 蓝牙BLE基础:CC2541通信系列之模拟SPI协议
- 蓝牙BLE基础:CC2541通信系列之模拟UART协议
- <蓝牙BLE>cc2541发现服务与特征值
- 【TI BLE】CC2541串口控制蓝牙详解
- 蓝牙Ble基础
- Android中BLE蓝牙资源
- BLE蓝牙
- CC2541 BLE上层架构
- 【BLE】CC2541之notify
- BLE CC2541串口调试
- 【BLE】CC2541之按键
- 【BLE】CC2541之RSSI
- 【BLE】CC2541之OLED
- 【BLE】CC2541之indicate
- 【BLE】CC2541之timer3
- 【BLE】CC2541之看门狗
- bzoj 1010: [HNOI2008]玩具装箱toy(斜率dp)
- LeetCode53. Maximum Subarray一种很好的做法
- picasso 源码解析
- python seek() 有条件的打印出末尾几行
- 【资源共享】《RK3399 VR Sensor 开发指南》
- 蓝牙BLE基础:CC2541 BLE临界资源保护
- 第十一章 字符串和字符串函数
- View绘制流程
- shiro 用户权限管理(1)----配置 (springmvc+jpa+hibernate+maven环境)
- solr进阶
- ubuntu16.04 64位编译安装qt4.8.0和qt creator2.4.1
- 点击元素弹出弹框后,背景不能滚动,关闭弹窗时,恢复滚动,背景元素位置保持不变
- iOS10App如何跳转到系统Wi-Fi设置
- java多线程面试题,三个线程顺序打印ABC