#include "main.h"
#include "MessageBuffer.h"
static RingBuffer msgQueue = {0};
// 初始化队列
void InitQueue(void) {
msgQueue.head = 0;
msgQueue.tail = 0;
msgQueue.count = 0;
}
// 检查队列状态
type_usart_queue_status GetQueueStatus(void) {
if (msgQueue.count == 0) {
return USART_QUEUE_EMPTY;
} else if (msgQueue.count >= (QUEUE_SIZE - MAX_MSG_LEN - sizeof(uint16_t))) {
return USART_QUEUE_FULL;
}
return USART_QUEUE_OK;
}
// 中断安全的推送消息到队列
type_usart_queue_status PushMsgData(type_Msg *pMsg) {
uint32_t primask;
type_usart_queue_status result = USART_QUEUE_ERR;
if (pMsg == NULL || pMsg->Length == 0 || pMsg->pData == NULL) {
return USART_QUEUE_ERR;
}
// 检查消息长度是否有效
if (pMsg->Length > MAX_MSG_LEN) {
return USART_QUEUE_ERR;
}
// 进入临界区(关闭中断)
primask = __get_PRIMASK();
__disable_irq();
// 检查是否有足够空间
if ((QUEUE_SIZE - msgQueue.count) >= (pMsg->Length + sizeof(uint16_t))) {
// 写入消息长度(小端格式)
msgQueue.buffer[msgQueue.head] = (uint8_t)(pMsg->Length & 0xFF);
msgQueue.head = (msgQueue.head + 1) % QUEUE_SIZE;
msgQueue.buffer[msgQueue.head] = (uint8_t)((pMsg->Length >> 8) & 0xFF);
msgQueue.head = (msgQueue.head + 1) % QUEUE_SIZE;
// 写入消息数据
for (uint16_t i = 0; i < pMsg->Length; i++) {
msgQueue.buffer[msgQueue.head] = pMsg->pData[i];
msgQueue.head = (msgQueue.head + 1) % QUEUE_SIZE;
}
msgQueue.count += (pMsg->Length + sizeof(uint16_t));
result = USART_QUEUE_OK;
} else {
result = USART_QUEUE_FULL;
}
// 退出临界区(恢复中断状态)
__set_PRIMASK(primask);
return result;
}
// 从队列弹出消息(主程序中使用)
type_usart_queue_status PopMsgData(type_Msg *pMsg) {
uint32_t primask;
type_usart_queue_status result = USART_QUEUE_ERR;
if (pMsg == NULL || pMsg->pData == NULL) {
return USART_QUEUE_ERR;
}
// 进入临界区(关闭中断)
primask = __get_PRIMASK();
__disable_irq();
if (msgQueue.count == 0) {
result = USART_QUEUE_EMPTY;
} else {
// 读取消息长度(小端格式)
uint16_t msgLength = msgQueue.buffer[msgQueue.tail];
msgQueue.tail = (msgQueue.tail + 1) % QUEUE_SIZE;
msgLength |= (uint16_t)(msgQueue.buffer[msgQueue.tail] << 8);
msgQueue.tail = (msgQueue.tail + 1) % QUEUE_SIZE;
// 检查消息长度是否有效
if (msgLength <= MAX_MSG_LEN) {
// 读取消息数据
for (uint16_t i = 0; i < msgLength; i++) {
pMsg->pData[i] = msgQueue.buffer[msgQueue.tail];
msgQueue.tail = (msgQueue.tail + 1) % QUEUE_SIZE;
}
pMsg->Length = msgLength;
msgQueue.count -= (msgLength + sizeof(uint16_t));
result = USART_QUEUE_OK;
} else {
// 无效长度,重置队列
InitQueue();
result = USART_QUEUE_ERR;
}
}
// 退出临界区(恢复中断状态)
__set_PRIMASK(primask);
return result;
}
#ifndef __MESSAGEBUFFER_H__
#define __MESSAGEBUFFER_H__
#define QUEUE_SIZE 1024*3 // 环形队列缓冲区大小
#define MAX_MSG_LEN 1024 // 单条消息最大长度
typedef struct {
uint16_t Length;
uint8_t *pData;
} type_Msg;
typedef struct {
uint8_t buffer[QUEUE_SIZE];
volatile uint16_t head; // 使用volatile确保中断和主程序都能正确访问
volatile uint16_t tail;
volatile uint16_t count;
} RingBuffer;
//typedef enum
//{
// USART_QUEUE_EMPTY = 0,
// USART_QUEUE_FULL = 1,
// USART_QUEUE_OK = 2,
// USART_QUEUE_ERR = 3,
//} type_usart_queue_status;
void MessageBufferInitFunc(void);
type_usart_queue_status PopMsgData(type_Msg *pMsg);
type_usart_queue_status PushMsgData(type_Msg *pMsg);
#endif
中断压入:
type_Msg RevMsg; //接收消息
RevMsg.Length = counter;
RevMsg.pData = RevBuff;
PushMsgData(&RevMsg);
主程序取出:
if (PopMsgData(&RevMsg) == USART_QUEUE_OK)
{
SendFlag = 1;
SendUartDataFunc(USART1, RevMsg.pData, RevMsg.Length);
}