1、 先简单介绍消息队列的结构体。因为FreeRTOS的二值信号量、计数信号量、互斥锁等都是基于消息队列实现的。
typedef struct QueueDefinition
{
int8_t *pcHead;/* 指向消息存储区的开始地址*/
int8_t *pcTail;/* 指向消息存储区的结束地址*/
int8_t *pcWriteTo;/* 指向队列消息存储区写地址*/
union
{
int8_t *pcReadFrom;/* 指向队列消息存储区读地址*/
UBaseType_t uxRecursiveCallCount;/* 用于计数,记录递归互斥量被“调用”的次数。 */
} u;
List_t xTasksWaitingToSend;/* 当存储区满时,发送数据的任务将被挂发送链表*/
List_t xTasksWaitingToReceive;/* 当存储区空时,接受数据的任务将被挂接受链表*/
volatile UBaseType_t uxMessagesWaiting;/*记录当前有多少条消息*/
UBaseType_t uxLength;/* 代表最大能存储多少条消息*/
UBaseType_t uxItemSize;/*< 表示单个消息的大小。 */
volatile int8_t cRxLock;/*< 队列上锁后,不能操作 xTasksWaitingToReceive 链表 */
volatile int8_t cTxLock;/*<队列上锁后,不能操作 xTasksWaitingToSend 链表 */
} Queue_t;
2、 创建任务和消息队列
void m_create_message_queue(void)
{
Test_Queue = xQueueGenericCreate((UBaseType_t ) QUEUE_LEN,
(UBaseType_t ) QUEUE_SIZE,queueQUEUE_TYPE_BASE);
if(NULL != Test_Queue)
{
LOG_BLE("Test_Queue = NULL\n");
}
xTaskCreate(send_task, "send_task", configMINIMAL_STACK_SIZE + 200, NULL, 2, &send_task_handle);
xTaskCreate(receive_task, "receive_task", configMINIMAL_STACK_SIZE + 200, NULL, 2, &receive_task_handle);
}
3、 编写内存的测试任务入口函数
#ifndef TAG_BLE
#define LOG_BLE(...)
#endif
static QueueHandle_t Test_Queue =NULL;
#define QUEUE_LEN 4
#define QUEUE_SIZE 4
static TaskHandle_t send_task_handle;
static TaskHandle_t receive_task_handle;
static void send_task (void * pvParameter)
{
BaseType_t xReturn = pdPASS;
uint32_t send_data = 0;
uint8_t button_sta=0;
while (true)
{
if (READ_BUTTON1_P11() == BUTTON_PUSH)
{
if (button_sta==0)
{
xReturn = xQueueSend( Test_Queue, &send_data,0 );
if(pdPASS == xReturn)
{
LOG_BLE("send data ok\n");
} else
{
LOG_BLE("send data error\n");
}
button_sta = 1;
send_data++;
}
} else
{
button_sta = 0;
}
vTaskDelay(20);
}
}
static void receive_task (void * pvParameter)
{
BaseType_t xReturn = pdTRUE;
uint32_t r_queue;
while (true)
{
xReturn = xQueueReceive( Test_Queue, &r_queue, portMAX_DELAY);
if(pdTRUE == xReturn)
{
LOG_BLE("receive ok,value:%d\n",r_queue);
TOGGLE_LED13();
TOGGLE_LED14();
TOGGLE_LED15();
TOGGLE_LED16();
} else
{
LOG_BLE("receive error,error code:0xx\n",xReturn);
}
}
}
3、实验说明和现象
①发送任务每检测一次按键按下,会发送一个值(这个值发送完后会自加一次),会打印发送状态。
②接受任务阻塞等待消息队列,每接受一次数据4个LED反转一次,且会打印接受值。