0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

冬至子 来源:ITRelief 作者:Sachefgh Xu 2023-07-25 15:36 次阅读

互斥锁的概念

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

互斥锁有一个比较明显的特点,即它必须哪一个线程申请,就由该线程来释放。而在二值信号量中,释放和获取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
*/


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

    关注

    68

    文章

    18288

    浏览量

    222176
  • RTOS
    +关注

    关注

    20

    文章

    776

    浏览量

    118796
  • ISR
    ISR
    +关注

    关注

    0

    文章

    38

    浏览量

    14296
收藏 人收藏

    评论

    相关推荐

    关于FreeRTOS互斥量的用法求解

    会引起死,比如当同一个任务多次抢占时, 最后还是得换到互斥量, 基于串口中断发送模式, 希望使用互斥量来访问串口的话 , 该如何释放发送完成信号呢? 在
    发表于 04-24 08:03

    Linux高级编程---互斥

    在Linux系统里,有很多的应用,包括互斥,文件,读写等等,信号量其实也应该是的一种。
    发表于 01-13 10:07

    【MiCOKit试用体验】庆科MiCO系统篇(3)MiCO RTOS互斥

    本帖最后由 gjianw217 于 2015-10-25 15:45 编辑 在本帖子中,主要分析一下庆科MiCO RTOS的互斥,具体包括:OS互斥MiCO
    发表于 10-24 17:02

    信号量、互斥、自旋

    信号量、互斥、自旋http://bbs.edu118.com/forum.php?mod=viewthread&tid=488&fromuid=231(出处: 信盈达IT技术社
    发表于 08-29 09:48

    小熊派华为物联网操作系统LiteOS内核教程05-互斥

    :开锁和闭锁。当有任务持有时,互斥处于闭锁状态,这个任务获得该互斥的所有权。当该任务释放它时,该互斥
    发表于 01-19 11:02

    BearPi-HM_Nano开发板鸿蒙OS内核编程开发——互斥

    :不能在中断服务调用该函数参数:[td]名字描述attr互斥对象的属性.osMutexAcquire()osStatus_t osMutexAcquire(osMutexId_t mutex_id
    发表于 04-09 10:02

    互斥量源码分析测试

    文章目录互斥量源码分析测试参考资料:RTT官网文档关键字:分析RT-Thread源码、stm32、RTOS、互斥量。互斥量在其他书籍中的名称:mutex :互斥
    发表于 08-24 06:01

    uCOS-III互斥量的概念是什么

    ,用于实现对临界资源的独占式处理。当一个任务持有互斥量时,其他任务将不能再对该互斥量进行开锁或持有。持有该互斥量的任务也能够再次获得这个
    发表于 01-20 08:19

    关于RT-Thread中断、调度与死锁的相关知识介绍

    。应用场合与注意事项中断是最强大的和最高效的同步方法,使用中断来操作临界区的方法可以应用于任何场合,其他几类同步方式(如信号量、互斥量等
    发表于 05-25 15:17

    如何在RK2206上使用鸿蒙LiteOS-M内核接口进行互斥编程开发

    注意的是,互斥不能在中断服务程序中使用。API分析LOS_MuxCreate()UINT32 LOS_MuxCreate(UINT32 *
    发表于 08-05 16:28

    RT-Thread实现的互斥属性包括哪些

    * lock);函数返回 lock无效返回EINVAL,否则返回0或EPERM。互斥属性RT-Thread实现的互斥属性包括互斥
    发表于 08-12 15:06

    很多变量多线程读写是使用关中断好还是使用互斥进行保护呢?

    会打断当前线程去获取同一个互斥量,由于被占,高优先级挂起,低优先级继续执行,释放互斥后高优先级执行。这样会有多两次线程切换开销。 2.如果在读写的时候进入
    发表于 05-05 14:14

    使用Linux互斥体实现互斥点灯

    互斥访问是指一次只有一个线程可以访问共享资源,不能递归申请互斥体。使用互斥体时要注意如下几点。
    的头像 发表于 04-13 15:13 666次阅读
    使用Linux<b class='flag-5'>互斥</b>体实现<b class='flag-5'>互斥</b>点灯

    Linux互斥锁的作用 互斥锁是什么

    锁。如果释放互斥锁时有一个以上的线程阻塞,那么这些阻塞的线程会被唤醒,它们都会尝试对互斥锁进行加锁,当有一个线程成功对互斥锁上锁之后,其它线程就不能再次上锁了,只能再次陷入阻塞,等待下
    的头像 发表于 07-21 11:13 568次阅读

    互斥锁和自旋锁的区别 自旋锁临界区可以被中断吗?

    互斥锁和自旋锁的区别 自旋锁临界区可以被中断吗? 互斥锁和自旋锁是在多线程编程中常用的锁机制,它们用于保护共享资源的并发访问,但在实现和使用方式上存在一些区别。 互斥锁是一种阻塞式的锁
    的头像 发表于 11-22 17:41 404次阅读