- 简述
- 它是一种特殊的二进制信号量,支持互斥量所有权、递归访问以及防止优先级翻转,实现对临界资源的独占式处理
- 互斥量的状态:
- 开锁:任务释放这个互斥量时,该互斥量处于开锁状态,任务失去该互斥量的所有权
- 闭锁:-----获得----------------,---------------------闭锁------,该互斥量被任务持有
- 优先级翻转图解
- 优先级继承
- 互斥量函数
- OSMutexCreate(); 创建一个互斥信号量
- OSMutexDel(); 删除一个互斥信号量
- OSMutexPend(); 等待一个互斥信号量
- OSMutexPendAbort(); 取消等待
- OSMutexPost(); 释放一个互斥弄信号量
- 常用函数:创建、释放、等待
- 例程:
- 创建
//创建互斥量 OSMutexCreate((OS_MUTEX *)&TestMutex, //指向互斥量变量的指针 (CPU_CHAR *)"Test for Mutex", //信号量的名字 (OS_ERR *)&err); //返回错误类型
- 任务1
/************************************************** * 函数名:static void AppTaskLed1(void *p_arg) * 描述 :led应用 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ static void AppTaskLed1(void *p_arg) { OS_ERR err; static uint32_t i; (void)p_arg; for(;;) { printf("\r\n AppTaskLed1 获取互斥量 \r\n"); //获取二进制信号量 OSMutexPend((OS_MUTEX *)&TestMutex, //申请互斥信号量 (OS_TICK )0, //无期限等待 (OS_OPT )OS_OPT_PEND_BLOCKING, //如果没有信号量可以就等待 (CPU_TS *)0, //获取信号量最后一次被发布的时间戳 (OS_ERR *)&err); //返回错误类型 for(i=0;i<1000000;i++) //模拟低优先级任务占用信号量 { // ; OSSched();//发起任务调度 } printf("\r\n AppTaskLed1 释放互斥量 \r\n"); OSMutexPost((OS_MUTEX *)&TestMutex, //释放互斥信号量 (OS_OPT )OS_OPT_POST_NONE, //进行任务调度 (OS_ERR *)&err); LED1_TOGGLE; OSTimeDlyHMSM (0,0,1,0,OS_OPT_TIME_PERIODIC,&err); } }
- 任务2
/************************************************** * 函数名:static void AppTaskLed2(void *p_arg) * 描述 :led应用 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ static void AppTaskLed2(void *p_arg) { OS_ERR err; (void)p_arg; for(;;) { printf("\r\n AppTaskLed2 running \r\n"); OSTimeDlyHMSM (0,0,0,200,OS_OPT_TIME_PERIODIC,&err); } }
- 任务3
/************************************************** * 函数名:static void AppTaskLed3(void *p_arg) * 描述 :led应用 * 输入 :无 * 输出 :无 * 返回 :无 * 调用 :内部调用 **************************************************/ static void AppTaskLed3(void *p_arg) { OS_ERR err; (void)p_arg; for(;;) { printf("\r\n AppTaskLed3 获取互斥量 \r\n"); //获取二进制信号量 OSSemPend( (OS_SEM *)&TestMutex, //申请互斥量 (OS_TICK )0, //无期限等待 (OS_OPT )OS_OPT_PEND_BLOCKING, //如果没有信号量可以就等待 (CPU_TS *)0, //不想获得时间戳 (OS_ERR *)&err); //返回错误类型 LED2_TOGGLE; printf("\r\n AppTaskLed3 释放互斥量 \r\n"); OSSemPost((OS_SEM *)&TestMutex, //释放互斥量 (OS_OPT )OS_OPT_POST_NONE, //进行任务调度 (OS_ERR *)&err); OSTimeDlyHMSM (0,0,1,0,OS_OPT_TIME_PERIODIC,&err); } }
- 创建
- 下载验证
- 总结
- 互斥量适用于保护各个任务间对共享资源的互斥访问
- 参考资料:
- 正点原子《STM32F767 UCOS开发手册》
- 野火《uC/OS-III内核应用与开发》
- 《嵌入式实时操作系统 uC/OS-II原理及应用(第二版)》
- 官方源码
- 硬件平台:
- 正点原子阿波罗F767
- 软件平台:
- MDK5.2.5
- 库版本:
- TM32Cube_FW_F7_V1.4.0
- uC/OS-III版本
- UCOSIII 3.04