stm32DMA+訊息佇列實現串列埠資料接收不丟包
前提:有一個專案一直使用DMA+串列埠空閒中斷接收資料,最近發現串列埠資料丟包。
經過檢查發現串列埠傳送機在傳送資料過程中本來應該是連續傳送,但是中間有某一個位元組與下一個位元組之間的間距大於一個位元組,MCU端會認為產生了一個空閒中斷,便觸發,這時候如果軟體直接讀取資料,很有可能後面的資料就直接丟失,並且原程式設計時候在處理過程中是關閉DMA的,這就會導致串列埠資料堵塞後面的資料也進不了,表現為串列埠接不到資料。
為了解決這個問題:修改程式邏輯,將DMA的兩個中斷(接收完成中斷,和接收一半中斷使能),在超過一半時即開始接收資料,存入另一個緩衝區,然後DMA繼續執行,不影響後續資料接收。
之所以設定接收一半中斷是為了加快資料流轉,避免佔用過多資源。下面看程式碼。
//定義一個fifo迴圈裡面不斷查詢是否有資料,並處理
經過試驗即使傳送端發生資料傳送中斷,後續資料正常傳送時也能保證資料被完整的接收,不會出現丟包現象。
typedef struct
{
uint8_t f_cnt;
uint8_t r_cnt;
uint8_t msgcnt;
uint8_t pock;
uint8_t usartbuff[USART2_MSG_MAX];
}ST_UartBuffFIFO;
//資料包進入佇列
uint8_t Sdk_Usart_BuffQueueInsertData(ST_UartBuffFIFO *pDataQueue , uint8_t *pDatabuff,uint32_t datasize)
{
if(pDataQueue->msgcnt <USART2_MSG_MAX)
{
pDataQueue->pock = 1;
pDataQueue->msgcnt+= datasize;
memcpy(&pDataQueue->usartbuff[pDataQueue->r_cnt],pDatabuff,datasize);
if(pDataQueue->r_cnt >= (USART2_MSG_MAX -1))
{
pDataQueue->r_cnt = 0;
}
else
{
pDataQueue->r_cnt+=datasize ;
}
pDataQueue->pock = 0;
return 1;
}
return 0;
}
//資料包移除佇列
uint8_t Sdk_Usart_BuffQueueDeleteData(ST_UartBuffFIFO *pDataQueue, uint8_t *pData )
{
if (pDataQueue->pock == 0)
{
if(pDataQueue->msgcnt >0)
{
pDataQueue->msgcnt--;
*pData = pDataQueue->usartbuff[pDataQueue->f_cnt];
if(pDataQueue->f_cnt >= (USART2_MSG_MAX -1))
{
pDataQueue->f_cnt = 0;
}
else
{
pDataQueue->f_cnt++;
}
return 1;
}
else
{
//pDataQueue->f_cnt = pDataQueue->r_cnt;
pDataQueue->f_cnt = 0;
pDataQueue->r_cnt = 0;
return 0;
}
return 0;
}
相關文章
- Redis實現訊息佇列Redis佇列
- Redis實現簡單訊息佇列Redis佇列
- QT串列埠助手(三):資料接收QT串列埠
- ros中使用serial包實現串列埠通訊ROS串列埠
- 如何實現MQ佇列訊息監控MQ佇列
- Redis 竟然能用 List 實現訊息佇列Redis佇列
- 使用Spring Boot實現訊息佇列Spring Boot佇列
- 訊息佇列系列一:訊息佇列應用佇列
- 訊息佇列佇列
- 阿里二面:要保證訊息不丟失,又不重複,訊息佇列怎麼選型?阿里佇列
- Go中使用Redis實現訊息佇列教程GoRedis佇列
- PHP基於Redis訊息佇列實現的訊息推送的方法PHPRedis佇列
- Redis 使用 List 實現訊息佇列能保證訊息可靠麼?Redis佇列
- Java實現RS485串列埠通訊Java串列埠
- Python中執行緒的MQ訊息佇列實現以及訊息佇列的優點解析Python執行緒MQ佇列
- 訊息佇列(MQ)佇列MQ
- Kafka訊息佇列Kafka佇列
- RabbitMQ訊息佇列MQ佇列
- kafka 訊息佇列Kafka佇列
- POSIX訊息佇列佇列
- 訊息佇列(一)佇列
- 訊息佇列(二)佇列
- 訊息佇列二佇列
- [Redis]訊息佇列Redis佇列
- [訊息佇列]rocketMQ佇列MQ
- [訊息佇列]RabbitMQ佇列MQ
- 離線資料推送問題(訊息佇列)佇列
- RabbitMQ 訊息佇列之佇列模型MQ佇列模型
- 用訊息佇列和socket實現聊天系統佇列
- 串列埠資料抓取及串列埠通訊模擬串列埠
- MQ不丟訊息,究竟是怎麼實現的?MQ
- 鏈式佇列—用連結串列來實現佇列佇列
- 全面理解Handler-1:理解訊息佇列,手寫訊息佇列佇列
- 別再用 Redis List 實現訊息佇列了,Stream 專為佇列而生Redis佇列
- 基於訊息佇列(RabbitMQ)實現延遲任務佇列MQ
- Redis使用ZSET實現訊息佇列使用總結二Redis佇列
- Redis使用ZSET實現訊息佇列使用總結一Redis佇列
- MQ訊息佇列_RabbitMQMQ佇列