STM32F7系列芯片集成了L1高速緩存,即L1 CACHE,包括D-CACHE和I-CACHE。它能夠提升CPU訪問數據或指令的速度,改善MCU的性能。關于STM32F7 L1 CACHE的應用,有個數據一致性問題需要注意,不然編程時可能會遇到些奇怪的現象。 在聊這個話題之前,先說幾個基本概念或術語。 1、芯片復位后,I-CACHE,D-CACHE默認是關閉的。可以分別打開或關閉以及配置各自大小。 2、對于STM32F7來說,只有經過AXI總線接口訪問時才用到L1 CACHE。換句話,通過其它總線【TCM/AHBP/AHBS】做數據或指令訪問時是不涉及到L1 CACHE的。 3、回寫【WRITE BACK】:在寫數據時,只是把數據寫進D-CACHE而未寫入二級存儲器,并將緩存行里的數據標識為DIRTY,直到執行CACHE的清除操作才將D-CACHE里的內容寫進二級存儲器。 3、透寫【WRITE THROUGH】:在寫數據操作時同時將數據寫入D-CACHE和二級存儲器。這對于保持數據的一致性有好處,代碼編寫也相對簡單。不過它需要消耗更多的寫數據時間。當然,下次訪問相同內容時還是可以直接從緩存里讀取。跟回寫相比,算是一種折衷處理辦法。 4、STM32F7片內外各個存儲單元的存儲屬性是通過MPU來配置的。在芯片復位之后,MPU是默認關閉的,此時各存儲單元的存儲屬性遵照如下的默認配置。 
好,那什么時候會發生數據一致性問題? 當有CPU和其它主設備【如DMA】共同訪問某可緩存的二級存儲器比方SRAM1,同時該存儲器又具有回寫屬性,此時就可能發生數據一致性問題。因為該存儲器的回寫屬性,導致通過CPU欲寫入存儲器的數據只是緩沖在CACHE里,而沒有及時寫入存儲器。如果此時DMA訪問該二級存儲器的話,讀到的數據可能跟預期不一致。 為了避免數據不一致的問題,我們需要做D-CACHE維護操作。一般有如下四種方法: 1、當對一個可緩存的二級存儲器做了寫數據操作之后,通過軟件對D-CACHE進行清除操作,即運行SCB_CleanDCache()。這樣將CACHE里的緩存內容寫回到二級存儲器,比如把那些DIRTY CACHE行的數據寫進SRAM1。 2、通過MPU調整可緩存存儲器的存儲屬性,將其CACHE使用方式改為透寫模式。這樣保證每次寫入CACHE里的內容也同時寫入二級存儲器,比如寫進SRAM1。 3、通過MPU調整可緩存存儲器的存儲屬性,將其共享屬性改為可共享的【SHAREABLE】。此后該二級存儲器將變為不可緩存。 4、通過配置CACR寄存器中的D-CACHE位,強制將所有寫操作配置為透寫屬性。
當然,跟上面描述相對應的還有一種情形。那就是DMA更新了可緩存存儲器比如SRAM1的數據后,CPU再去讀SRAM1,此時也會發生數據不一致的問題。因為CPU此時讀的數據還是之前CACHE里的舊數據。為了避免這個問題,保證數據的一致,就得在CPU讀SRAM1之前通過軟件執行CACHE失效操作,這樣保證CPU直接從二級存儲器比方SRAM1讀取數據。 下面有個關于數據一致性的實例供大家思考。 首先CPU從片上FLASH存儲塊aSRC_Const_Buffer的128字節常量數據拷貝到SRAM1里的一個名為pBuffer的緩存區。 然后CPU配置并使能DMA執行從內存到內存的傳輸,將SRAM1里pBuffer緩存區的數據傳輸到DTCM RAM的另一個aDST_Buffer緩存區。 最后,CPU將aDST_Buffer緩存區的數據與flash存儲塊aSRC_Const_Buffer的常量數據進行比較是否一致。 
最后小結下,對于STM32F7系列MCU來說,可能發生數據一致性問題需要的幾個因素: 1、有CPU和DMA參與數據訪問; 2、有被CPU和DMA共同訪問的可緩存的帶回寫屬性的物理存儲塊; 3、開啟了D-CACHE;
往期話題鏈接:STM32CUBE相關技術手冊哪里找:http://www.zg4o1577.cn/bbs/dpj-50088-1.html |