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;
}
相關文章
- javascript中的資料型別
- 資料多次分攤方案二
- 最新 Swift5 常見資料型別
- C語言 列舉資料型別
- Tensorflow的資料輸入模組tf.data模組
- python讀取txt文字資料進行分詞並生成詞雲圖片
- mybatis 多資料來源動態切換
- mongodb核心原始碼實現、效能調優系列-為何要對開源mongodb資料庫核心做二次開發
- 質量視覺化-讓質量為資料說話演講稿 _美柚孔令雲_20201121
- SQL Server 批量生成資料庫內多個表的表結構
- React學習筆記之雙向資料繫結
- Java網路程式設計--UDP傳送接收資料
- el-table 合併相同資料的列
- Spring Cloud 終結篇之訊息驅動--stream 大集合
- ClickHouse資料庫資料定義手記之資料型別
- ehcarts擴充套件優秀的資料表
- 23 大資料之hive(第四部 hive基礎)
- C語言練習——資料加密
- RocketMQ的事務訊息處理【half-message】
- 分散式事務解決方案-RocketMQ實現可靠訊息最終一致性