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