概述
- ????模板说明
粤嵌鸿蒙 -- 学习笔记
内核篇:(1 2 3篇线程 定时器 事件笔记在上一章)
4.互斥锁
5.信号量
6.消息队列
- ????课前准备
- 参考资料 ---- 以下笔记中出现的代码可以在该网址的“四、BearPi-HM_Nano 案例开发”中查找
- BearPi-HM_Nano: 小熊派BearPi-HM Nano开发板基于HarmonyOS的源码 (gitee.com)
https://gitee.com/bearpi/bearpi-hm_nano
- 开发市场 (harmonyos.com)
https://repo.harmonyos.com/#/cn/solution/@bearpi%2Fbearpi_hm_nano ---- 小熊派开发板的源代码下载--涵盖例程
- BearPi-HM_Nano: 小熊派BearPi-HM Nano开发板基于HarmonyOS的源码 (gitee.com)
- 参考资料 ---- 以下笔记中出现的代码可以在该网址的“四、BearPi-HM_Nano 案例开发”中查找
- ????听课记录
- 4.mutex互斥锁 -- 理解:拥有锁的任务独占资源,其他任务阻塞等待
- 互斥锁的概念:
- 1.互斥锁又称互斥型信号量,是一种特殊的二值信号量,用于实现对共享资源的独占式处理。
- 2.任意时刻互斥锁的状态只有两种:开锁和闭锁。
- 3.当有任务持有时,互斥锁处于闭锁状态,这个任务获得该互斥锁的所有权。
- 4.当有任务释放时,该互斥锁被开锁,任务我失去该互斥锁的所有权。
- 5.当一个任务持有互斥锁时,其他任务将不能再对该互斥锁进行开锁或持有。
- 6.多任务环境下往往存在许多任务竞争同一共享资源的应用场景,互斥锁可被用于对该共享资源的保护从而实现独占式访问
- 另外,互斥锁可以解决信号量存在的优先级翻转问题。
- osMutexNew -- 创建互斥锁
- 互斥锁的概念:
- 4.mutex互斥锁 -- 理解:拥有锁的任务独占资源,其他任务阻塞等待
osMutexId_t osMutexNew(const osMutexAttr_t *attr)
-
-
-
- 描述:
-
-
函数osMutexNew创建并初始化一个新的互斥锁对象,并返回指向互斥锁对象标识符的指针,如果出现错误则返回NULL,可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,但不能在内核初始化 (调用 osKernelInitialize)之前调用该函数。 注意 :不能在中断服务调用该函数
-
-
-
- 参数:
- attr:互斥对象属性,这里我通常填NULL
- 代码设计:
- 参数:
-
-
osMutexId_t mutex_id; //定义全局变量 mutex_id = osMutexNew(NULL); //创建一个新的互斥锁,并返回指向互斥锁对象标识符的指针 if (mutex_id == NULL) //做一个简单的判断,是否创建互斥锁成功 { printf("Falied to create Mutex!n"); }
-
-
- osMutexAcquire -- 获取互斥锁
-
osStatus_t osMutexAcquire(osMutexId_t mutex_id,uint32_t timeout)
-
-
-
- 描述:
-
-
函数osMutexAcquire一直等待,直到参数mutex_id指定的互斥对象可用为止。如果没有其他线程获得互斥锁,该函数立即返回并阻塞互斥锁对象。 注意 :不能在中断服务调用该函数
-
-
-
- 参数:
- mutex_id:通过osMutexNew获得互斥锁ID.(这里是mutex_id )
- timeout:超时值.
- 参数:
-
-
osWaitForever -- 一直等待获取互斥锁
-
-
-
- 代码设计:
-
-
// try to acquire mutex osMutexAcquire(mutex_id, osWaitForever);
-
-
- osMutexRelease -- 释放互斥锁
-
osStatus_t osMutexRelease(osMutexId_t mutex_id)
-
-
-
- 描述:
-
-
函数osMutexRelease释放一个由参数mutex_id指定的互斥量。当前等待这个互斥锁的其他线程将被置于就绪状态。 注意 :不能从中断服务例程调用此函数。
-
-
-
- 参数:
- mutex_id:通过osMutexNew获得互斥锁ID.(这里是mutex_id )
- 代码设计:
- 参数:
-
-
osMutexRelease(mutex_id);
-
-
- osMutexDelete -- 删除互斥锁
-
osStatus_t osMutexDelete(osMutexId_t mutex_id)
-
-
-
- 描述:
-
-
函数osMutexDelete 删除一个由参数mutex_id指定的互斥量。
-
-
-
- 参数:
- mutex_id:通过osMutexNew获得互斥锁ID.(这里是mutex_id )
- 代码设计:
- 参数:
-
-
osMutexDelete(mid);
-
- 5.semp信号量 --理解:互斥锁差不多
- 信号量的概念:
- 1.信号量(Semaphore)是一种实现任务间通信的机制,实现任务间同步或临界资源的互斥访问(4.互斥锁就属于信号量的一种)。常用于协助一组相互竞争的任务来访问临界资源。(这里的具体应用就是互斥锁)
- 2.在多任务系统中,个任务之间需要同步或互斥实现临界资源的保护,信号量功能可以为用户提供这方面的支持。
- 3.通常一个信号量的计数值用于对应有效的资源数,表示剩下的可被占用的互斥资源数。其值的含义分两种情况:
- ① 0 ,表示没有积累下来的Post信号量操作,且有可能有在此信号量上阻塞的任务。
- ② 正值 ,表示有一个或多个Post信号量操作。
- 4.以同步为目的的信号量和以互斥为目的的信号量(互斥型看4.互斥锁)在使用有如下不同:
- ①用作互斥时:信号量创建后计数是满的,在需要使用临界资源时,先取信号量,使其变空,这样其他任务需要使用临界资源时就会因为无法取到信号量而阻塞,从而保证了临界资源的安全。--有信号量的独占资源
- ②用作同步时:信号量在创建后被置为空,任务1取到信号量而阻塞,任务2在魔种条件发生后,释放信号量,于是任务1得以进入READY或RUNNING,从而达到两个任务间同步。--相当于任务1就绪状态,等待任务2条件成立后任务1进行。
- osSemaphoreNew -- 创建信号量 == 理解:创建互斥锁
- 信号量的概念:
- 5.semp信号量 --理解:互斥锁差不多
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
-
-
-
- 描述:
-
-
函数osMessageQueueNew创建并初始化一个消息队列对象。该函数返回消息队列对象标识符,如果出现错误则返回NULL,可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,也可以在内核初始化 (调用 osKernelInitialize)之前调用该函数。 注意 :不能在中断服务调用该函数
-
-
-
- 参数:
- max_count:可用令牌的最大数量.
- initial_count:可用令牌的初始数量.
- attr:信号量的属性;空:默认值.
- 代码设计:
- 参数:
-
-
osSemaphoreId_t sem1; sem1 = osSemaphoreNew(4, 0, NULL); if (sem1 == NULL) { printf("Falied to create Semaphore1!n"); }
-
-
- osSemaphoreAcquire -- 获取(等待)信号量 == 理解:获取互斥锁
-
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
-
-
-
- 描述:
-
-
阻塞函数osSemaphoreAcquire一直等待,直到由参数semaphore_id指定的信号量对象的标记可用为止。如果一个令牌可用,该函数立即返回并递减令牌计数。 注意 :如果参数timeout设置为0,可以从中断服务例程调用。
-
-
-
- 参数:
- semaphore_id:由osSemaphoreNew获得的信号量ID.(这里是sem1 )
- timeout:超时值.(这里我通常填osWaitForever--一直等待)
- 代码设计:
- 参数:
-
-
//等待sem1信号量 osSemaphoreAcquire(sem1, osWaitForever);
-
-
- osSemaphoreRelease -- 释放信号量 == 理解:释放互斥锁
-
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
-
-
-
- 描述:
-
-
函数osSemaphoreRelease释放由参数semaphore_id指定的信号量对象的标记 注意 :该函数可以在中断服务例程调用
-
-
-
- 参数:
- semaphore_id:由osSemaphoreNew获得的信号量ID.
- 代码设计:
- 参数:
-
-
osSemaphoreRelease(sem1);
-
-
- osSemaphoreDelete -- 删除信号量 == 理解:删除互斥锁
-
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
-
-
-
- 描述:
-
-
函数osSemaphoreDelete 删除由参数semaphore_id指定的信号量
-
-
-
- 参数:
- semaphore_id:由osSemaphoreNew获得的信号量ID.
- 代码设计:
- 参数:
-
-
/删除信号量 osSemaphoreDelete(sem1); ----->图片的s_data是申请的信号量ID,这里换成我们创建的信号量ID--->sem1
-
- 6.message消息队列
- 消息队列的概念:
- 消息队列,是一种常用于任务间通信的数据结构,是西安了接收来自任务或中断的不固定长度的消息,病根选举不同的接口选择传递消息是否存放在自己空间.任务能够从队列里面读取消息,当队列中的消息是空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息.
- 用户在处理业务时,消息队列提供了异步处理机制,允许将一个消息放入队列,但并不立即处理它,同时队列还能起到缓冲消息作用.
- LiteOS中使用队列数据结构实现任务异步通信工作,具体由如下特性:
- 消息以先进先出方式排队,支持异步读写工作方式.
- 读队列和写队列都支持超时机制.
- 发送消息类型由通信双方约定,可以允许不同长度(不超过队列节点最大值)消息.
- 一个任务能够从任意一个消息队列接收和发送消息.
- 多个任务能够从同一个消息队列接收和发送消息.
- 当队列使用结束后,如果时动态申请的内存,需要通过释放内存函数回收.
- 消息队列运作原理:
- 消息队列的概念:
- 6.message消息队列
-
-
-
- 创建队列时,根据用户传入队列长度和消息节点大学校来开辟i想要的内存空间以提供该队列使用,返回队列ID
- 在队列控制块中维护一个消息头节点位置Head和一个消息为节点位置Tail来表示当前队列中消息存储情况.Head表示队列中被占用消息的位置.Tail表示队列中被空闲消息的起始位置.
- 写队列时,根据Tail找到被占用消息节点末尾的空闲节点作为数据写入对象.
- 读队列时,根据Head找到最先写入队列中的消息节点进行读取.
- 删除队列时,根据传入的队列ID寻找到对应的队列,把队列状态置为未使用,释放原队列所占的空间,对应的队列控制头置为初始状态.
- osMessageQueueNew -- 创建消息队列
-
-
osMessageQueueId_t osMessageQueueNew(uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr)
-
-
-
- 描述:
-
-
函数osMessageQueueNew创建并初始化一个消息队列对象。该函数返回消息队列对象标识符,如果出现错误则返回NULL,可以在RTOS启动(调用 osKernelStart)之前安全地调用该函数,也可以在内核初始化 (调用 osKernelInitialize)之前调用该函数。 注意 :不能在中断服务调用该函数
-
-
-
- 参数:
- msg_count : 队列中的最大消息数.
- msg_size : 最大消息大小(以字节为单位).
- attr : 消息队列属性;空:默认值.
- 代码设计:
- 参数:
-
-
osMessageQueueId_t mid_MsgQueue; //number of Message Queue Objects #define MSGQUEUE_OBJECTS 16 mid_MsgQueue = osMessageQueueNew(MSGQUEUE_OBJECTS, 100, NULL); if (mid_MsgQueue == NULL) { printf("Falied to create Message Queue!n"); }
-
-
- osMessageQueuePut -- 发送消息
-
osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id,const void *msg_ptr,uint8_t msg_prio,uint32_t timeout)
-
-
-
- 描述:
-
-
函数osMessageQueuePut将msg_ptr指向的消息放入参数mq_id指定的消息队列中。 注意 :如果参数timeout设置为0,可以从中断服务例程调用
-
-
-
- 参数:
- mq_id: 由osMessageQueueNew获得的消息队列ID.
- msg_ptr: 要发送的消息.
- msg_prio: 指优先级.
- timeout: 超时值.
- 代码设计:
- 参数:
-
-
typedef struct { //object data type char *Buf; uint8_t Idx; } MSGQUEUE_OBJ_t; MSGQUEUE_OBJ_t msg; void Thread_MsgQueue1(void *argument) //发送消息线程 { (void)argument; //do some work... msg.Buf = "Hello BearPi-HM_Nano!"; msg.Idx = 0U; while (1) { osMessageQueuePut(mid_MsgQueue, &msg, 0U, 0U); //suspend thread osThreadYield(); osDelay(100); } }
-
-
- osMessageQueueGet -- 获取消息
-
osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id,void *msg_ptr,uint8_t *msg_prio,uint32_t timeout)
-
-
-
- 描述:
-
-
函数osMessageQueueGet从参数mq_id指定的消息队列中检索消息,并将其保存到参数msg_ptr所指向的缓冲区中。 注意 :如果参数timeout设置为0,可以从中断服务例程调用。
-
-
-
- 参数:
- mq_id: 由osMessageQueueNew获得的消息队列ID.
- msg_ptr: 要发送的消息.
- msg_prio: 指优先级.
- timeout: 超时值.
- 代码设计:
- 参数:
-
-
void Thread_MsgQueue2(void *argument) { (void)argument; osStatus_t status; while (1) { //Insert thread code here... //wait for message status = osMessageQueueGet(mid_MsgQueue, &msg, NULL, 0U); if (status == osOK) { printf("Message Queue Get msg:%sn", msg.Buf); } } }
-
-
- osMessageQueueDelete -- 删除消息队列
-
osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id)
-
-
-
- 描述:
-
-
函数osMessageQueueDelete 删除mq_id指定的消息队列对象
-
-
-
- 参数:
- mq_id: 由osMessageQueueNew获得的消息队列ID.
- 代码设计:
- 参数:
-
-
osMessageQueueDelete (mid_MsgQueue ) //图片qid以创建获得的消息队列ID为主
最后
以上就是大气裙子为你收集整理的小熊派BearPi-HM nano开发板 -- 内核篇: 4.互斥锁 5.信号量 6.消息队列的全部内容,希望文章能够帮你解决小熊派BearPi-HM nano开发板 -- 内核篇: 4.互斥锁 5.信号量 6.消息队列所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复