STM32工作笔记0087---时间标志组和同时等待多个内核对象

技术交流QQ群【JAVA,C++,Python,.NET,BigData,AI】:170933152

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第1张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第2张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第3张图片

两个任务之间的同步,咱们一般用信号量,但是

一个任务和多个事件之间的同步可以用或同步,和 与同步.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第4张图片

先看看这个或同步,比如有4个事件,那么只要有一个事件发生,那么对应的任务5就会同步.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第5张图片

这个与同步,意思就是,当所有时间都发生了,才去同步任务5,

 

下面说的这个标志事件组,就相当于与同步

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第6张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第7张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第8张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第9张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第10张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第11张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第12张图片

可以看到他是个无符号的,32位的整形.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第13张图片

这个是什么意思呢?

他的意思是,一共32位,那么每位代表一个事件.

所以最多可以表示32个事件

我们要判断,某个bit位如果是1的时候,说明这个事件发生了.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第14张图片

 STM32工作笔记0087---时间标志组和同时等待多个内核对象_第15张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第16张图片

先看这个OSFlagCreate()这个创建事件标志组.

第一个参数是事件标志组

第二个是事件标志组名字

第三个是:是事件标志组的,32个事件,初始化值,一般就赋值 一个0

如果你有个事件默认就是执行的,可以把某一位设置为1,那么至于

哪一位对应哪个事件,一会会说.

 

第四个是错误码

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第17张图片

再看这个事件标志组的请求,这里

第一个参数是 事件标志组

第二个参数是 要请求哪个事件,比如要请求第0个,和第1个,那么就传入 0x03也就是0000 0011 ,再前面全是0

第三个参数,超时时间

第四个参数是 opt  是选项.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第18张图片

这个opt选项有四个

OS_OPT_PEND_FLAG_CLR_ALL 这个是表示,所有的flag中的32个位都清0了,就说明请求到,标志事件组了

OS_OPT_PEND_FLAG_CLR_ANY 这个是表示,所有的flag中的32个位,只要有一个位清0了,就表示,请求到标志事件组了

OS_OPT_PEND_FLAG_SET_ALL 这个是表示,所有的flag中的32个位,都设置成了1了,就表示,请求到标志事件组了

OS_OPT_PEND_FLAG_SET_ANY 这个表示,,所有的flag中的32个位,只要有一个设置成了1了,就表示,请求到标志事件组了

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第19张图片

后面是一个时间戳和一个错误码

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第20张图片

然后这里,看看这个

OSFlagPost 这个标志事件组的 释放事件

这里p_grp是,哪个标志事件组

flags这个是,要操作具体的哪个事件,32位中的哪个事件,哪一位是1就选中了哪个事件

然后 opt这个意思是,是要对选中的事件,是置1,还是置0

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第21张图片

这个

OS_OPT_POST_FLAG_SET 是置1

然后

OS_OPT_POST_FLAG_CLR这个是清零

然后去看一下这个案例:

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第22张图片

首先由三个任务

START_TASK_PRIO这个任务

MAIN_TASK_PRIO这个任务

 STM32工作笔记0087---时间标志组和同时等待多个内核对象_第23张图片

还有

FLAGSPROCESS_TASK_PRIO这个是按键处理任务

 这里定义了这个KEY0_FLAG 0X01就是 0X0000 0001

KEY1_FLAG 0X02 就是0X0000 0010

这两个就分别对应的,事件标志组的,第0位和低1位. 32位中的这两位

然后

KEYFLAGS_VALUE 这个0X00 这个就是设置为0,把默认值

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第24张图片

main函数中,创建事件标志组

然后创建两个任务,一个主任务

一个是按键处理任务

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第25张图片

再去看看

主任务

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第26张图片

主任务中去扫描按键,然后,这里

扫描key0的时候,

可以看到向事件标志组发送EventFlags标志

然后KEY0_FLAG是占用第0位.

然后OS_OPT_POST_FLAG_SET是把上面对应的KEY0位设置为1

然后key可以看到也是这样,是把KEY1对应的位设置为1.

这里是释放事件标志组.

然后

看看事件标志组处理任务

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第27张图片

这里,可以看到, 去请求KEY0_FLAG+KEY1_FLAG 去请求key0和key1

然后这里设置,当OS_OPT_PEND_FLAG_SET_ALL也就是,key0和key1都置1的时候

才算是请求成功

那么

OS_OPT_PEND_FLAG_CONSUME这个是什么意思呢

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第28张图片

可以看到上面的解释就是,OS_OPT_PEND_FLAG_CONSUME,就是请求完了以后

要对对应的位要清0,这里就是选择清0,请求完以后.

所以这个就是这个事件标志组,

也就是,只有key0和key1,全部按下的时候,才会执行下面的操作

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第29张图片

这里这个按键处理任务,就请求了事件标志组,要求

在key0,和key1 都按下的时候才显示填充和显示内容.

LCD

下载到开发版看看

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第30张图片

刚启动的时候可以看到EventFlags value是0

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第31张图片

然后按下key0的时候可以看到

EventFlags value是1

然后,再按下key1的时候可以看到就有颜色了显示了,并且

EventFlags value是0了,也就是被请求到了,key0,和key1都按下了.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第32张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第33张图片

可以看到,屏幕变了颜色以后,可以看到对应的值

也变成0了,也就说

OS_OPT_PEND_FLAG_CONSUME,请求完毕以后要把对应的事件的位都设置为0

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第34张图片

看看串口的输出,可以看到按下key0这个值是1

也就0x01  写开 0000  0001

然后按下key1以后,因为key1是0x10写开0000 0010

所以放到一起,就是0x11 写开:0000 0011

也就是3,然后,当按键处理任务请求,事件标志组的时候,请求了以后,接着因为

OS_OPT_PEND_FLAG_CONSUME 这个就把3,又清为0了.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第35张图片

然后再看看,前面咱们说了,信号量,互斥信号量,消息队列和事件标志组

那么实际上是可以实现,

任务同时等待多个信号量和多个消息队列

注意这里只能同时等待多个信号量和多个消息队列

不能同时等待多个事件标志组,或互斥信号量

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第36张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第37张图片

去看看代码

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第38张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第39张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第40张图片

可以看看,第一个是个数组,也就是,要等待的信号量和消息队列都要放到这里.

,然后tbl_size这个是,上面那个数组的长度

然后timeout是超时时间片

然后选项

然后错误码

看看选项

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第41张图片

选项是阻塞还是不阻塞

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第42张图片

然后这里主要看一下这个数组是什么东西,

OS_PEND_DATA

咱们通过看案例来说

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第43张图片

可以看到这里,这里等待多个内核对象,这里是

等待信号量1,信号量2,消息队列

然后内核对象个数是3也就是上面这个3个

然后消息队列长度是10

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第44张图片

然后main函数中,去创建信号量1,信号量2,消息队列

可以看到这里,没有创建等待多个内核对象,这个是不需要创建的.

然后看看task1

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第45张图片

可以看到在任务1中发送了信号量1,和发送了信号量2

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第46张图片

然后这里任务2中按键扫描,

这里做了发送消息队列.

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第47张图片

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第48张图片

这里,请求等待多个内核对象

multi_task这个函数中,可以看到,把上面的信号量1,信号量2,

和消息队列,都放到结构体中.

然后通过

OSPendMulti,去等待,多个内核对象

这个等待多个内核对象,就相当于或同步

可以看到这里

下载到开发版以后

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第49张图片

开始的时候,显示ObjRdy_NUM:0

这个时候,如果我按下key0,这里就显示1

同时屏幕也刷新了,也就是这里,只要这个三个信号量1,信号量2,

消息队列,只要有一个请求等待多个内核对象,只要有一个执行, 就会被捕获到.

屏幕就会刷新了.,

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第50张图片

当然,也可以,比如同时按下信号量1,信号量2,还有消息队列的发送,这样值就会增加了.

这里多按下几次key0比如,也可以,这个值也会增加

ObjRdy_NUM:3

STM32工作笔记0087---时间标志组和同时等待多个内核对象_第51张图片

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(硬件嵌入式)