电子说
互斥锁的概念
互斥锁是一种特殊的二值信号量,因为它解决了优先级翻转的问题。可以通过优先级继承机制来解决:当另外一个的任务试图获取同一个互斥锁时,已经获得互斥锁的任务将继承该任务的优先级。
互斥锁有一个比较明显的特点,即它必须哪一个线程申请,就由该线程来释放。而在二值信号量中,释放和获取token的线程可以不一致。因此,在处理线程之间占用同一硬件资源的问题时首先考虑使用互斥锁。
API Description 【互斥锁不能在中断中使用】
①创建互斥锁
在CMSIS-RTOS中,互斥锁通过 ***osMutexNew() *** 函数和配置结构体 *osMutexAttr_t *建立。
1)配置结构体osMutexAttr_t
在osMutexAttr_t 中功能参数 *attr_bits ***用于配置互斥锁的功能特性,相当重要;参数相关定义包括: **
1.* osMutexRecursive * - 创建递归互斥锁。当上锁开锁的程序段递归时,会出现多重加锁的情况,并从深处向外解锁。此时应当引入对递归的支持。本参数配置了一个递归计数机制,允许同一个线程多重加锁;调用一次计数+1,释放-1;当计数回到0时此锁解开。
2.osMutexPrioInherit - 优先级继承机制。可以防止优先级翻转。
上述三个参数可以通过逻辑或( | )组合传入结构体。
typedef struct {
const char *name; ///名称,仅标识用
uint32_t attr_bits; ///功能参数;重要
void *cb_mem; /// memory for control block;Default ==NULL
uint32_t cb_size; /// Default==0U
} osMutexAttr_t;
@param attr_bits: -参数配置;可通过逻辑或 输入复数的参数
/ osMutexPrioInherit -使用优先级继承
/ osMutexRecursive -递归互斥锁
/ osMutexRobust -自回收;当线程终止时自动释放持有的token
osMutexId_t osMutexNew (const osMutexAttr_t *attr);/*创建互斥锁
@param *attr -osMutexAttr_t互斥锁配置结构体
@retval -句柄(地址)
==NULL 创建失败*/
**②删除互斥锁 **osMutexDelete()
osStatus_t osMutexDelete( osMutexId_t mutex_id );/*删除互斥锁
@retval: -osOK //成功
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorResource: the mutex is in an invalid state.(其他错误)
-osErrorISR: 在中断调用导致的错误
*/
③获取互斥锁token osMutexAcquire()
互斥锁token的获取与二值信号量基本一致。 线程调用该函数时,当锁中无token时,线程进入BLOCK状态等待消息量被放入token;。在此期间当任务检测到消息量放入token时,将自动由****BLOCK态转移为READY态。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从阻塞态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误**。**
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);/*取得token;
@param timeout 阻塞等待时间
@retval -osOK: the mutex has been obtained.
-osErrorTimeout: the mutex could not be obtained in the given time.
-osErrorResource: the mutex could not be obtained when no timeout was specified.
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorISR: cannot be called from interrupt service routines.
*/
timeout参数:
== 0U //不设置阻塞超时时间,若出现异常函数将直接报错返回
== osWaitForever //任务将一直阻塞直到锁中token被相应线程归还
== Ticks //设置具体等待时间,单位为RTOS心跳数(Ticks)
④归还互斥锁tokenosMutexRelease() ****
注意互斥锁的token归还只能由获取的线程进行,否则系统会报Resource错误。
osStatus_t osMutexRelease (osMutexId_t mutex_id);/*归还互斥锁
@retval -osOK: 成功
-osErrorResource: 无法归还(当前token没有被获取 或 本线程不持有互斥锁的token)
-osErrorParameter: parameter mutex_id is NULL or invalid.
-osErrorISR: 在中断中调用了本函数
*/
```**⑤查询当前互斥锁token的拥有者(线程)**** ***osMutexGetOwner()*********
osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)/*
@retval -持有互斥锁token的线程句柄(ID);
若token未被持有或 发生错误,则返回NULL
*/
全部0条评论
快来发表一下你的评论吧 !