这会想了想,在复习资料后,最后再做个核心代码分析
ucos中使用信号量、消息邮箱、消息队列,这些数据结构来作为通信中间媒介。这些数据结构会影响任务的程序流程,因此也叫做事件。
一、信号量
是进行任务通信的最基本事件
二值信号可以实现共享资源的独占,也叫互斥信号量。
注意:使用信号量的时候要,高优先级的任务等待接受信号量的时候,高优先级的任务在等待接受信号量的时候,如果低优先级的任务没有释放信号量,那就会一直等待下去,那低优先级的任务就没有机会运行了,系统就出现死机的状况了。 解决方法:加个超时等待.
在使用信号量同步时:一个任务能否运行取决于2个条件-----1是优先级 2是是否获得信号量。相当于串联关系。这也引起了一个优先级反转的问题。
二、消息邮箱:
多任务进行通信的时候,消息邮箱是用来传递消息缓冲区指针的数据结构。
三、消息队列
多任务进行通信的时候,消息队列是用来传递多个消息邮箱的数据结构。
四、事件的等待任务列表
对于正在等待的多个任务、需要对其进行记录和按照优先级排序;还要制定任务等待的最大时间,避免低优先级的任务永远无法运行。
下面对等待任务的记录和排序的处理:
一个 INT8U 类型的数组 OSEventTbl
[],作为记录等待事件任务的记录表。
一个 INT8U 类型的变量 OSEventGrp 来表示组。
其实和就绪表原理一样,这个等待任务表中仍然是以任务的优先级别为顺序, 令系统中的每个任务都在表中占据一位, 并用该位为
1 来表示这一位对应的任务为事件的等待任务, 否则不是等待任务。
下面是等待任务的等待时限的处理:
记录在等待任务的任务控制块TCB的成员OSTCBDly中,并在每个时钟节拍中断服务程序中对该数据进行维护。每当有任务的等待时限已到时,则将该任务从事件等待任务表中删除,并使它进入就绪状态。
五、事件控制块
为了把事件的数据结构统一起来,就定了了事件控制块ECB,专门用来描述消息邮箱、消息队列、信号量这些事件的。
OSEventType 可取的值
OS_EVENT_TYPE_MUTEX 表明事件是互斥型信号量
OS_EVENT_TYPE_MBOX 表明事件是消息邮箱
OS_EVENT_TYPE_Q 表明事件是消息队列
OS_EVENT_TYPE_UNUSED 空事件控制块(未被使用的事件控制块)
六、事件控制块的几个操作函数
EventWaitListInit () 事件控制块初始化函数:清楚表中的数据为0
在创建事件时被调用
OS_EventTaskWait() 请求事件不能成功 ,使一任务进入等待状态,在等待列表登记任务,并在任务控制块中设置为
等待状态,最后还要在就绪表中,设置为非就绪状态。
OS_EventTaskRdy ()使一个等待的任务进入就绪状态,
OS_EventTO() 使一个等待超时的任务进入就绪状态
事件控制块链表也有空和工作中的2种区分,类似于任务控制块,就不多说了
七、信号量详细
重要组成:类型 cnt 信号量指针为空 控制块
1.创建信号量
OSSemCreat(cnt)------------设置类型 设置初始化计数 设置指向缓冲区为空 初始化事件控制块 返回信号量指针
2.请求信号量
OSSemPend(信号量指针 时限 错误信息) 信号量无效时,任务会等待
OSsemAccept(信号量) 信号量无效时,任务直接继续运行
3.释放信号量
OSSemPost(信号量指针)
4.删除信号量
OSSemDel(信号量名、条件选项、错误信息)
5.查询信号量状态
OSSemQuery()
八、优先级反转和互斥量
优先级反转:ab等待状态,c运行;c最低优先级,在c没有释放信号量的情况下,a运行了,那a会等待,然后c运行了在释放信号量之前有个任务b运行了,那b只得在a之前运行了。好像b的优先级比a高了。
出现这种情况是因为低优先级的任务使用信号量的过程中被打断,不能释放信号量。
解决方法就是c使用信号量的时候提高优先级(因为在使用信号量比a的优先级要高),释放信号量再恢复原来的优先级。
九、互斥量
任务可用互斥量,来实现对资源的独占
数据类型要为互斥量类型 cnt分为高8字节和低8字节,低8位0xff表示信号有效,高8位记录了临时的提升的优先级。
1.创建互斥量
OSMutexCreat(提升的优先级 错误信息)
2.请求互斥量
OSMutexPend(互斥量指针 超时 错误信息)
OSMutexAccept(互斥量指针 错误信息) 互斥量无效任务会继续运行
3.释放互斥量
OSMutexPost(互斥量指针)
4.获取互斥量的当前状态
OSMutexQuery(互斥量指针 存储的数据结构)
5.删除互斥量
OSMutexDel(互斥量指针 直接删除还是等待任务执行完删 错误信息)
十、消息邮箱
1.OSMboxCreat(msg)
消息邮箱 :设置类型为消息邮箱类型;设置指针为空,或指向缓冲区;设置cnt为0;初始化ECB
2.OSMboxPost(消息邮箱的指针, 消息缓冲区指针)
发送消息邮箱