互斥锁不能在中断中使用?

电子说

1.2w人已加入

描述

互斥锁的概念

互斥锁是一种特殊的二值信号量,因为它解决了优先级翻转的问题。可以通过优先级继承机制来解决:当另外一个的任务试图获取同一个互斥锁时,已经获得互斥锁的任务将继承该任务的优先级。

互斥锁有一个比较明显的特点,即它必须哪一个线程申请,就由该线程来释放。而在二值信号量中,释放和获取token的线程可以不一致。因此,在处理线程之间占用同一硬件资源的问题时首先考虑使用互斥锁。

API Description 【互斥锁不能在中断中使用】

①创建互斥锁

在CMSIS-RTOS中,互斥锁通过 ***osMutexNew() *** 函数和配置结构体 *osMutexAttr_t *建立。

1)配置结构体osMutexAttr_t

osMutexAttr_t 中功能参数 *attr_bits ***用于配置互斥锁的功能特性,相当重要;参数相关定义包括: **

1.* osMutexRecursive * - 创建递归互斥锁。当上锁开锁的程序段递归时,会出现多重加锁的情况,并从深处向外解锁。此时应当引入对递归的支持。本参数配置了一个递归计数机制,允许同一个线程多重加锁;调用一次计数+1,释放-1;当计数回到0时此锁解开。

2.osMutexPrioInherit - 优先级继承机制。可以防止优先级翻转。

  1. *osMutexRobust * - 互斥锁回收机制。当加锁的线程被 osThreadExit() 或 *osThreadTerminate() *终止而未能解锁时,锁将会自动回收。

上述三个参数可以通过逻辑或( | )组合传入结构体。

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
  1. 通过 ***osMutexNew() ***创建目标互斥锁
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
*/


打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分