有人使用STM32H743做產(chǎn)品開發(fā), DMA 傳輸待發(fā)送的數(shù)據(jù)到 UART 發(fā)送寄存器做后續(xù)UART通信。在開啟D-Cache的情況下,發(fā)現(xiàn)UART沒法發(fā)送更新過的數(shù)據(jù)。
具體應(yīng)用場(chǎng)景是這樣的,源數(shù)據(jù)放在STM32H743片內(nèi)D1域的AXI-SRAM區(qū),數(shù)據(jù)會(huì)不定期地被CPU修改,然后讓DMA將數(shù)據(jù)傳輸?shù)経SART3的發(fā)送寄存器進(jìn)行后續(xù)UART通信。結(jié)合手冊(cè)可以查得USART3位于D2域。[下面截圖來自STM32H7芯片參考手冊(cè)]
目前開啟了D-Cache/I-Cache。我基于現(xiàn)有場(chǎng)景寫了一段簡(jiǎn)單的如下測(cè)試代碼【編譯環(huán)境使用STM32CubeIDE】:
__attribute__((section(".Source"))) uint8_t Source[5];
uint32_t TimeOut;
uint8_t Variable=0;
基于上面測(cè)試代碼,也重現(xiàn)了相同現(xiàn)象。即盡管CPU在不停修改源端數(shù)據(jù),可目的端UART3的TDR寄存器的數(shù)據(jù)總保持0不變。【注:我這里的DMA使用的Memory to Memory方式,并非要一定這樣操作。你完全可以基于UART事件使用Memory to Peripheral的方式。】
這里排除了其它方面的原因,該現(xiàn)象是因?yàn)殚_啟了D-Cache并使用write back策略而導(dǎo)致的不同主設(shè)備訪問同一內(nèi)存而產(chǎn)生的數(shù)據(jù)不一致的問題。
現(xiàn)在CPU不時(shí)修改AXI-SRAM1指定區(qū)域的數(shù)據(jù),DMA到同一位置讀取數(shù)據(jù)送到UART發(fā)送寄存器。畫個(gè)圖示意下:
對(duì)于STM32H743片內(nèi)AXI-SRAM1區(qū)域,其默認(rèn)的存儲(chǔ)屬性為write back及writeallocate。【下圖來自STM32H7參考手冊(cè)】
此時(shí)CPU對(duì)該區(qū)域進(jìn)行寫操作發(fā)生Cache分配,數(shù)據(jù)會(huì)先寫到Cache里。要等到Cache重分配或手動(dòng)刷新Cache時(shí)才會(huì)將Cache里的新數(shù)據(jù)寫到RAM內(nèi)存。
這里有三種方案可選用來解決這個(gè)問題:
第一種方案就是,CPU做數(shù)據(jù)更新操作后,對(duì)相應(yīng)存儲(chǔ)區(qū)執(zhí)行Cache清除操作,讓Cache的新數(shù)據(jù)及時(shí)寫到RAM內(nèi)存,即添加下面打紅勾的代碼。
第二種方案就是針對(duì)CPU修改的數(shù)據(jù)存儲(chǔ)區(qū)進(jìn)行MPU設(shè)置,配置為write through或關(guān)閉該區(qū)域Cacheable特性。下面將其配置為Writethrough屬性。【下面截圖來自ARM相關(guān)技術(shù)手冊(cè)。C:Cacheable,B:Bufferable,S:Shareable】
使用STM32圖形化配置工具CubeMx進(jìn)行MPU相關(guān)配置【參見下圖】:
第三種方案,簡(jiǎn)單粗暴且有效,那就是關(guān)閉芯片D-Cache的使用。如果對(duì)開啟D-Cache不在乎或者只是前期功能調(diào)試先關(guān)掉無妨,后面再去調(diào)整也可以。
上面簡(jiǎn)單介紹了在開啟D-Cache情況下,CPU不定期修改Cacheable內(nèi)存數(shù)據(jù),DMA讀取相應(yīng)內(nèi)存而發(fā)生的數(shù)據(jù)不一致問題的解決方案,以供參考。
最后提醒下,當(dāng)我們使用SCB_CleanDCache_by_Addr()函數(shù)清除Cache時(shí),需注意給定地址要遵循32字節(jié)對(duì)齊的原則。【注:上面截圖來自STM32H7Cube庫。】
審核編輯:湯梓紅
-
Cache
+關(guān)注
關(guān)注
0文章
129瀏覽量
28772 -
uart
+關(guān)注
關(guān)注
22文章
1249瀏覽量
102612 -
dma
+關(guān)注
關(guān)注
3文章
569瀏覽量
101913 -
STM32H743
+關(guān)注
關(guān)注
0文章
24瀏覽量
2050
原文標(biāo)題:開啟Cache后UART無法發(fā)送新數(shù)據(jù)
文章出處:【微信號(hào):stmcu832,微信公眾號(hào):茶話MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
ZYNQ進(jìn)階:PL端UART 發(fā)送設(shè)計(jì)案例

STM32h7開啟Cache后,串口發(fā)送DMA會(huì)導(dǎo)致中斷觸發(fā)如何解決?
為什么無法使用Lpuart_Uart_Ip_ 發(fā)送任何數(shù)據(jù)回調(diào)中的AsyncSend?
cc2530為什么在休眠喚醒后無法發(fā)送數(shù)據(jù)?
怎么用UART發(fā)送和接收數(shù)據(jù)?
am335x裸機(jī)開啟mmu和cache后,ucos2任務(wù)不能調(diào)度如何排查?
CH573 TMOS開啟sleep后串口異常怎么解決?
UART 發(fā)送數(shù)據(jù)丟失最后一個(gè)字節(jié)
關(guān)于UART發(fā)送數(shù)據(jù)丟失最后一個(gè)字節(jié)問題的詳細(xì)解析-pdf
什么是 Cache? Cache讀寫原理
如何根據(jù)UART傳輸協(xié)議將數(shù)據(jù)發(fā)送出去呢?

UART發(fā)送數(shù)據(jù)丟失最后一個(gè)字節(jié)

評(píng)論