架构范式转移:DeepSeek-Coder-V2如何重构企业级代码智能的ROI模型
2026/5/13 15:28:27
我来为你详细分析UCOS 消息队列的原理、使用方法、典型问题及高频应用案例,帮助你全面掌握这一核心通信机制。
UCOS 的消息队列由以下关键数据结构组成:
typedef struct { OS_OBJ_TYPE Type; // 对象类型(队列) CPU_CHAR *NamePtr; // 队列名称 OS_MSG_Q MsgQ; // 消息队列(存储消息指针) OS_Q *NextPtr; // 下一个队列指针 OS_Q *PrevPtr; // 上一个队列指针 OS_PEND_LIST PendList; // 等待该队列的任务列表 CPU_TS TS; // 时间戳 } OS_Q;typedef struct os_msg { void *MsgPtr; // 消息数据指针 OS_MSG_SIZE MsgSize; // 消息长度 OS_MSG *NextPtr; // 下一个消息指针 } OS_MSG;OSQPost()或OSQPostFront()向队列发送消息。OSQPend()从队列接收消息。OS_Q *OSQCreate(CPU_CHAR *p_name, OS_MSG_QTY max_qty, OS_ERR *p_err)p_name:队列名称(字符串)。max_qty:队列最大可存储的消息数量。p_err:返回错误码(如OS_ERR_NONE表示成功)。NULL。void OSQPost(OS_Q *p_q, void *p_void, OS_MSG_SIZE msg_size, OS_OPT opt, OS_ERR *p_err)p_q:队列控制块指针。p_void:消息数据指针。msg_size:消息数据长度(字节数)。opt:发送选项(如OS_OPT_POST_FIFO表示尾部插入,OS_OPT_POST_FRONT表示头部插入)。p_err:返回错误码。void *OSQPend(OS_Q *p_q, OS_TICK timeout, OS_OPT opt, OS_MSG_SIZE *p_msg_size, CPU_TS *p_ts, OS_ERR *p_err)p_q:队列控制块指针。timeout:等待超时时间(时钟节拍数,0表示无限等待)。opt:接收选项(如OS_OPT_PEND_BLOCKING表示阻塞等待,OS_OPT_PEND_NON_BLOCKING表示非阻塞等待)。p_msg_size:返回消息数据长度。p_ts:返回消息发送时间戳。p_err:返回错误码。OS_OBJ_QTY OSQDel(OS_Q *p_q, OS_OPT opt, OS_ERR *p_err)p_q:队列控制块指针。opt:删除选项(如OS_OPT_DEL_NO_PEND表示只有在没有任务等待时才删除,OS_OPT_DEL_ALWAYS表示强制删除)。p_err:返回错误码。1)。OS_OPT_POST_NO_SCHED,可能导致消息丢失。OSQIsFull())。OS_OPT_POST_FIFO并确保队列长度足够。10个时钟节拍)。OSQIsEmpty())。// 采集任务 void SensorTask(void *p_arg) { OS_ERR err; uint16_t data; while (1) { data = Sensor_Read(); // 读取传感器数据 OSQPost(MyQueue, &data, sizeof(data), OS_OPT_POST_FIFO, &err); OSTimeDlyHMSM(0, 0, 1, 0, OS_OPT_TIME_HMSM_STRICT, &err); // 延时1秒 } } // 处理任务 void ProcessTask(void *p_arg) { OS_ERR err; uint16_t data; OS_MSG_SIZE msg_size; while (1) { void *p_msg = OSQPend(MyQueue, 0, OS_OPT_PEND_BLOCKING, &msg_size, NULL, &err); if (err == OS_ERR_NONE) { data = *(uint16_t *)p_msg; // 处理数据 OSMsgPoolFree(p_msg, &err); // 释放消息内存 } } }void USART1_IRQHandler(void) { OS_ERR err; uint8_t data = USART1->DR; // 读取串口数据 OSQPostFromISR(MyQueue, &data, sizeof(data), OS_OPT_POST_FIFO, &err); } void UartTask(void *p_arg) { OS_ERR err; uint8_t data; OS_MSG_SIZE msg_size; while (1) { void *p_msg = OSQPend(MyQueue, 0, OS_OPT_PEND_BLOCKING, &msg_size, NULL, &err); if (err == OS_ERR_NONE) { data = *(uint8_t *)p_msg; // 处理串口数据 OSMsgPoolFree(p_msg, &err); } } }void InitTask(void *p_arg) { OS_ERR err; // 初始化硬件 Hardware_Init(); OSQPost(MyQueue, NULL, 0, OS_OPT_POST_FIFO, &err); // 发送空消息表示初始化完成 while (1) { // 其他工作 } } void WorkTask(void *p_arg) { OS_ERR err; OS_MSG_SIZE msg_size; // 等待初始化完成 OSQPend(MyQueue, 0, OS_OPT_PEND_BLOCKING, &msg_size, NULL, &err); while (1) { // 开始工作 } }✅推荐实践:
OSMem)管理消息数据,避免动态内存分配导致的内存碎片。OSQ)提高性能。