freeRTOS实时操作系统移植
FreeRtos(1)-----任务创建与管理
以上是历史FreeRtos博客。FreeRtos系列我会坚持更下去。

freeRTOS消息队列

先来看一下队列:先进先出
在这里插入图片描述
这个图可能画的有点问题,有大佬知道具体过程的欢迎指正。

我们先来看一下Freertos消息队列的API
API头文件:
#include "queue.h"
消息队列的创建

xQueueCreate((UBaseType_t)QUEUE_LEN,(UBaseType_t)QUEUE_SIZE);
参数:
	QUEUE_LEN  需要创建的队列的长度,最大可包含多少个消息
	QUEUE_SIZE 队列中每个消息大小(字节)
返回值:
	如果创建成功则返回一个队列句柄,用于访问创建的队列。如果创建
	不成功则返回 NULL,可能原因是创建队列需要的RAM无法分配成功。

消息队列发送函数

BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
参数:
	xQueue:消息队列句柄
	pvItemToQueue:指针,指向要发送到队列尾部的队列消息。
	xTicksToWait:
				0:不等待立即返回
				portMAX_DELAY:阻塞直到接收到消息
返回值:成功返回pdPASS
xQueueSend()用于向队列尾部发送一个队列消息。消息以拷贝的形式入队
而不是以引用的方式。
xQueueSend() 等同于 xQueueSendToBack()。该函数绝对不能在中断服务
程序里面被调用,中断中必须使用带有中断保护 功能的
xQueueSendFromISR()来代替。xQueueSend()其实就是
xQueueGenericSend()的封装

注意:
发送紧急消息的过程与发送消息几乎一样,唯一的不同是,当发送紧急消
息时,发送的位置是消息队列队头而非队尾,这样,接收者就能够优先接
收到紧急消息,从而及时进 行消息处理。

消息队列接收函数

BaseType_t xQueueReceive( QueueHandle_t xQueue, void * const pvBuffer, TickType_t xTicksToWait )
参数:
	xQueue:消息队列句柄
	pvBuffer:指针,指向接收到要保存的数据。
	xTicksToWait :
					0,立即返回
					portMAX_DELAY阻塞到有消息读出
返回值:成功返回pdPASS

xQueueReceive() 是 一个 宏, 宏展开是调用函数 xQueueGenericReceive()xQueueReceive()用于从一个队列中接收消息并把消息从队列中删除。接
收的消息是以拷贝 的形式进行的,所以我们必须提供一个足够大空间的
缓冲区。
该函数绝不能在中断服务程序里面被调用,而是 必须使用带有中断保护
功能的 xQueueReceiveFromISR ()来代替

消息队列删除函数

vQueueDelete()
参数:队列句柄

下面我们看一个例子:

按键按下向一个任务发送消息“1”

#include "stm32f10x.h"
#include "led.h"
#include "stdio.h"
#include "usart1.h"
#include "systick.h"
#include "delay.h"
#include "my_key.h"
//一下为FREERTOS头文件
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#define QUEUE_LEN 8
#define QUEUE_SIZE 8
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t server_Task_Handle = NULL;/* server 任务句柄 */
static TaskHandle_t client_Task_Handle = NULL;/* client 任务句柄 */
static void AppTaskCreate(void);/* 用于创建任务 */
static void server_Task(void* pvParameters);
static void client_Task(void* pvParameters);

QueueHandle_t queue_id=NULL;//队列句柄

int main(void)
{
 BaseType_t xReturn = pdPASS;//创建任务返回值
 NVIC_SetPriorityGrouping(3);
 usrat1_config();
 systick_config();
 key_init();
 led_config();
 printf("hello\r\n");
	
	
 //创建任务
 /* 创建 AppTaskCreate 任务 */
  xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate,/* 任务入口函数 */
												(const char *)"AppTaskCreate",/* 任务名字 */
												(uint16_t )512,
												(void *)NULL,
												(UBaseType_t )1,
												(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
	
 /* 启动任务调度 */
	if (pdPASS == xReturn) 
	{
	  vTaskStartScheduler(); 
	}
	else 
	{
	return -1; 
	}
	 
 while (1); /* 正常不会执行到这里 */
}
static void AppTaskCreate(void)
{
 BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值,默认为 pdPASS */
 taskENTER_CRITICAL();
	queue_id=xQueueCreate((UBaseType_t)QUEUE_LEN,(UBaseType_t)QUEUE_SIZE);//创建消息队列
	
	
 xReturn = xTaskCreate((TaskFunction_t )server_Task,/* 任务入口函数 */
												(const char *)"server_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )3,
												(TaskHandle_t* )&server_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("任务创建成功\r\n");
 }
 
  xReturn = xTaskCreate((TaskFunction_t )client_Task,/* 任务入口函数 */
												(const char *)"client_Task",/* 任务名字 */
												(uint16_t )128,
												(void *)NULL,
												(UBaseType_t )2,
												(TaskHandle_t* )&client_Task_Handle);/* 任务控制块指针 */
 if(pdPASS == xReturn)
 {
	printf("任务创建成功\r\n");
 }
 
vTaskDelete(AppTaskCreate_Handle); //删除 AppTaskCreate 任务 
taskEXIT_CRITICAL();//退出临界区

}
//定义一个任务
static void server_Task(void* parameter)
{
	BaseType_t xReturn = pdPASS;
	uint32_t s_queue=1;
 while(1)
 {
  if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)==0)
	{
		xReturn=xQueueSend(queue_id,&s_queue,0);
		if(xReturn==pdPASS)
		{
			printf("发送ok\r\n");
		}
	}
	vTaskDelay(20);
 }
}
static void client_Task(void* parameter)
{
	BaseType_t xReturn = pdPASS;
	uint32_t r_queue;
 while(1)
 {
	 xReturn=xQueueReceive(queue_id,&r_queue,portMAX_DELAY);
	 if(xReturn==pdPASS)
	 {
		 printf("接收到的内容为:%d\r\n",r_queue);
	 }
	 else
	 {
	 printf("接收出错\r\n");
	 }

 }
}

我们看一下运行结果
在这里插入图片描述
当按键按下后,一个任务接收到消息“1”.示例中其实我只按下了一次按键,但是发送了很多次。主要原因是我的按键实在是太太太太抖了,咋消抖也莫得办法!!!

-END-
感谢评阅,欢迎指正交流。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐