自编STM32轻量级操作系统(六)------消息队列

时间:2021-09-09 20:10:34

你好,这里是风筝的博客,

欢迎和我一起交流。


上一章讲了互斥量,自编STM32轻量级操作系统(五)------互斥量

今天,最后一章,就是消息队列了。

消息队列,能够使得任务与任务、或者任务与中断之间进行通信。

何为队列?先进先出为队列。

何为消息?打开你的QQ你就知道......


现在看一下消息队列怎么实现的。

首先,创建消息队列:

自编STM32轻量级操作系统(六)------消息队列

这里注意了,在ECB事件控制块新增了两个成员:Addr和Size:

typedef struct OS_Ecb  
{
unsigned int Cnt;//计数器
unsigned char OSEventTbl;//事件等待表
unsigned int Prio;//优先级
void **Addr;//地址
unsigned int Size;//消息队列大小

}ECB; //事件控制块


注意了,这里Addr是个二级指针,指向存放消息的指针(一个指针数组,存放消息)。Size是存放消息队列的大小,最多有Size长度的消息队列。


接下来肯定是申请消息队列:

自编STM32轻量级操作系统(六)------消息队列


这里面的传参,time和opt,当然也是按照ucos的来玩了:

自编STM32轻量级操作系统(六)------消息队列

里面说有,timeout为等待事件,0为死等;opt为选择是否阻塞。


申请消息队列里,实际上也是和申请信号量类似,如果不清楚,感觉还是可以回去看看:自编STM32轻量级操作系统(四)------信号量的实现

如果opt传参为1.则阻塞。

接着,写到这,我觉得写队列有点麻烦,,,,,,囧,还是栈比较舒服,后进先出,所以这里我就按栈的写法了,有兴趣的小伙伴可以自己试试写个队列。

基本就是返回消息数组的地址(因为是指针数组)就行了。


最后就是发送消息函数和删除函数,没啥好说的,和信号量那一章一样:

自编STM32轻量级操作系统(六)------消息队列


乏味,基本就是搬砖式写代码了,只需注意下二级指针的用法而已罢了,没啥好说的。


删除消息队列函数:

自编STM32轻量级操作系统(六)------消息队列


还是老话题,删除之后千万不要在使用了!!!大忌啊!

好了,终于结束了,最后给你例程:

//#include "stm32f10x.h"
#include "led.h"
#include "os.h"
#include "lcd.h"
#include "delay.h"
#include "malloc.h"
#include "stdio.h"

#define TASK_1_STK_SIZE 512
#define TASK_2_STK_SIZE 512

unsigned int TASK_1_STK[TASK_1_STK_SIZE];
unsigned int TASK_2_STK[TASK_2_STK_SIZE];

//ECB * s_msg; //信号量
//ECB * m_msg; //互斥信号量
ECB * q_msg; //消息队列
void * MsgGrp[255]; //消息队列存储地址,最大支持255个消息

void Task1(void)//高优先级
{
while(1)
{
LCD_ShowString(160,100,210,24,24,OS_QPend(q_msg,0,1));
LED0=!LED0;
OSTimeDly(150);
}
}
void Task2(void)//中优先级
{
void *p;
OSTimeDly(250);
p=my_malloc(8);

while(1)
{
sprintf(p,"By_KITE");//7个字节
OS_QPost(q_msg,p);
//LED1=!LED1;
OSTimeDly(50);
}
}

int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init();
Task_Create(Task1,&TASK_1_STK[TASK_1_STK_SIZE-1],0);
Task_Create(Task2,&TASK_2_STK[TASK_2_STK_SIZE-1],1);
malloc_init();//内存初始化
delay_init();
LCD_Init();
POINT_COLOR=RED;
LCD_Clear(WHITE);
LCD_ShowString(30,40,210,24,24,(u8*)"This is a system!");
//s_msg=OS_SemCreate(0);//开始时,信号量计数器为0
//m_msg =OS_MutexCreate(); //创建互斥信号量
q_msg=OS_QCreate(MsgGrp,255);//创建消息队列
OS_Start();
return 0;
}


因为用的消息队列,涉及到传递信息,所以添加了LCD屏幕,不再是led的天下了......

这里我用的是正点原子的开发板。

老规矩,给个例程下载:消息队列例程下载


至此,最后一章也码完了,基于STM32的操作系统系列文章到此也就告一段落了。

最初,写这个只是为了兴趣,觉得好玩而已,到现在有半年了,也没用来写过什么大的项目,稳定性不做绝对保证,仅仅是为了做学习用途,后来码这篇文章时也发现了一些不成熟的思想,也重写了部分代码,最后我会给完整的程序,喜欢的小伙伴可以用来试试,有bug欢迎提交给我。


最后,提交最终Demo,添加了调度锁、任务挂起与唤醒,增加了条件编译。

最终代码下载如下:基于STM32的嵌入式操作系统