UCOSII操作系统的任务间通信

前言

在主程序里面做i++(i=10),在某个中断服务函数里面做i–,会出现主程序刚取出i的值得时候被中断打断,在中断里面做了i—(写回去的值为9),返回到断点后,主程会对i(已经取出的值)做加1操作,然后写回去(最终i=11;).------在主程序里面在对i操作之前先把中断关了,等操作完后再打开中断。
出现以上情况的原因是—打断。在Ucos中不可避免的会出现以上打断问题。因为ucos是以优先级作为调度原则,所以也存在打断问题。所以任务间间交换信息如果用全局变量,就存在以上问题。所以ucos任务间交换信息尽量的不要用全局变量。

Ucosii的任务间通信机制:信号量、互斥信号量、消息邮箱、消息队列、事件标志组

任务控制块:存放当前任务的相关信息(任务函数地址、任务优先级、任务栈、任务状态)

事件控制块:当成功创建一个事件(信号量、互斥信号量、消息邮箱、消息队列、事件标志组)后,系统就分配一段内存空间,这段空间就是事件控制块,存放这该事件的相关信息。

信号量

可以把信号量看成是一个计数器,表示当前资源的占用情况,当释放一个资源时信号量+1,如果占用一个资源,信号量-1。

  1. 要想使用信号量,必须先创建一个信号量,并且可以对这个信号量赋予一个初始值。
  2. 释放信号量,信号量就会+1
  3. 要想得到一个信号量,要先查看信号量是否为0,如果大于0表示当前可以去占用一个信号量,如果为 0表示当前信号量被用光了,可以死等其他任务释放信号量,也可以不等。
    函数原型:OS_EVENT *OSSemCreate(INT16U value);
    函数作用:建立并初始化一个信号量
    参数说明:建立的信号量的初始值,可以取 0 到 65535 之间的任何值。
    返回值:指向成功创建的信号量的事件控制块地址

函数原型:void OSSemPend (OS_EVENT *pevent,
INT32U timeout,
INT8U *perr);
函数作用:申请一个信号量(挂起任务等待信号量)。

函数原型:INT16U OSSemAccept(OS_EVENT *pevent);
函数作用:无等待查看信号量是否为0。

函数原型:INT8U OSSemPost(OS_EVENT *pevent);
函数作用:释放一个信号量,把信号值加 1

函数原型:void OSSemSet(OS_EVENT *pevent,
INT16U cnt,
INT8U *perr);
函数作用:改变当前信号量的计数值

消息邮箱

顾名思义,可以往邮箱里存放消息,这个消息的内容比信号量要更加丰富。
这个邮箱只能存放一则消息。
如果这个邮箱里存在消息没有被读取,然后再往里面存放消息,就会失败。

在消息邮箱里面,如果发送方能力比较强(发送速度快),接受方能力比较弱(接受得慢),那么就会丢失新的消息。

消息队列

消息邮箱只能存放一则消息,而消息队列则可以存放一队(多则)消息,相当于增强了接受方的能力
消息队列存放消息的方式是先进先出

创建一个消息队列:
OS_EVENT *OSQCreate (void **start,INT16U size)
start:指向用户创建一个存储区(数组),这个存储空间(数组)存放的是消息的地址。成功创建了消息队列后,创建的这个存储区(数组)就交由UCOSII去管理。
size:消息内存区的大小

发送一则消息
INT8U OSQPost (OS_EVENT *pevent,void *pmsg);
pmsg:消息的地址
发送多则不同消息需要发送不同的消息地址。

互斥信号量

对于互斥信号量: 二值,要么为0,要么为1
Pend/Accept: 想取得互斥信号量的控制权
Post: 释放互斥信号量的控制权。只有取得互斥信号量的任务post才有效
优先级翻转问题:
低优先级的任务取得了互斥信号量后,高优先的任务也想取得互斥信号量的控制权。这个时候高优先级的任务得不到互斥信号量,并且还会把低优先级的任务的优先级提升到一个设定的优先级(提升到的优先级在创建互斥信号量的时候已经指定,一般设置的优先级比想取得此互斥信号量的任务中最高的优先级还高)。

低优先级的任务和高优先级的任务同时都想要获取同一个互斥信号量,假如低优先级的任务先得到了这个互斥信号量,然后高优先级的任务就需要等待低优先级的任务释放该信号量才能得到。如果在低优先级释放信号量之前被其他不参与竞争这个互斥信号量的中等优先级任务抢走了CPU,就有可能发生低优先级的任务释放不了这个互斥信号量,使得在等待该信号量的高优先级任务真的等到死了。
所以,为了避免这种事情的发生,在低优先级的任务得到了互斥信号量后,高优先级的任务也想去获取而获取不到时,就会把得到该互斥信号量的低优先级任务的优先级提升到一个预定的比较高的优先级。当低优先级任务释放了互斥信号量后,就会把优先级回复到原来的级别。

如果高优先级的任务先的到了互斥信号量,而这时候低优先级的任务也想去获取,只能死等。

发布了65 篇原创文章 · 获赞 36 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_40860986/article/details/93669196