天天看點

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家介紹的是實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形。

  上一篇文章 《實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(有預取)》 裡痞子衡抓取了Cache關閉但Prefetch開啟下的AHB讀通路對應的Flash端時序波形圖,我們知道了FlexSPI的Prefetch功能确實在一定程度上改善了Flash通路效率,但是AHB RX Buffer最大僅1KB(對i.MXRT1050而言),不可拆分成更小粒度Buffer去緩存不同Flash位址處的資料(對于同一AHB master而言),這樣對于代碼中多個不同小資料塊重複的Flash空間通路,Prefetch機制并沒有明顯提升通路效率。

  針對這種不連續Flash位址空間頻繁通路低效情況,ARM Cortex-M7核心給出了解決方案,那就是L1 Cache技術,今天痞子衡就來繼續測一測開啟L1 Cache下的Flash AHB讀通路情形(本文主要針對D-Cache):

  對于Cortex-M系列家族(M0+/M3/M4/M7/M23/M33/M35P/M55)來說,L1 Cache僅在Cortex-M7和Cortex-M55核心上存在,說白了,L1 Cache是專為高性能核心配置的,而目前的i.MXRT1xxx系列微控制器都是基于Cortex-M7核心。

  下面是i.MXRT1050的核心系統框圖,可以看到它內建了32KB D-Cache,Cache經由AXI64總線連到SIM_M7和SIM_EMS子產品,最終轉成AHB總線連接配接到FlexSPI子產品,是以對于Flash的AHB讀通路是可以受到D-Cache加速的。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  關于D-Cache工作機制,可以在 ARM Cortex-M7 Processor Technical Reference Manual 手冊中找到詳細解釋。簡單地概括就是32KB D-Cache會被劃分成1024個Cache Line,每個Cache Line大小為32個位元組,四個Cache Line是一組(即所謂的4-way set associative),每一組Cache Line會有一個位址标簽,位址标簽用來記錄Cache所緩存的資料所在目标位址資訊。

  L1 D-Cache使能時,對目标存儲器的AHB讀通路總共有兩大類:Hit(要通路的資料在Cache裡面)、Miss(要通路的資料不在Cache裡面),Hit沒什麼好說的,直接從Cache裡取資料就行了;Miss後則會先把資料從目标存儲器中讀到Cache裡,然後再從Cache讀出資料(這就是所謂的Read-Allocate,實際上有另一個名詞Read-Through與之對應,Read-Through即直接從目标存儲器中讀出資料,一般是Cache不使能時的行為)。

  對目标位址空間的Cache政策控制主要是屬性配置(在核心MPU子產品裡)和開關控制(在核心SCB子產品裡),下面 BOARD_ConfigMPU() 函數即是典型的對FlexSPI位址映射空間所配置設定的Flash區域的Cache屬性配置,這個代碼裡将0x60000000開始的64MB空間屬性配成了Normal Memory,不共享,Cache使能并且寫通路行為是Write-Back(寫通路還有另一種政策Write-Through),讀通路行為不用配置(固定Read-Allocate)。

  最後再提一下跟本文主題不相幹的Cache使能下寫通路行為政策:

(Hit情形下)Write-Through模式: 直接寫到目标存儲器中并且也在Cache裡更新(無多Master通路造成的資料一緻性問題,但沒有提升寫通路性能) (Hit情形下)Write-Back模式: Cache line會被标為dirty,等到此行被invalidate時,才會執行實際的寫操作,将Cache Line裡面的資料寫到目标存儲器。(提升了寫通路性能,但有隐患,如果 Cache 命中,此時僅 Cache 更新了,目标存儲器沒有更新,其他Master從目标存儲器裡面讀出來的資料是錯誤的) (Miss情形下)Write-Allocate: 先把要寫的資料載入到Cache,然後再flush進目标存儲器。 (Miss情形下)no-Write-Allocate: 直接寫入目标存儲器。

  參考文章 《實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(無緩存)》 裡的第一小節 實驗準備,本次實驗需要做一樣的準備工作。

  參考文章 《實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(無緩存)》 裡的第二小節 實驗代碼,本次實驗代碼關于工程和連結檔案方面是一樣的設定,但是具體測試函數改成如下ramfunc型函數 test_cacheable_read()。關于D-Cache這次會有很多種不同測試,while(1)語句前的系統配置保持不變,while(1)裡面的語句可根據實際測試情況去調整:

  為了便于分辨IO[1:0]上的資料去幫助分析本系列測試用例結果,我們需要拓展下特殊const資料區.ahbRdBuffer設定如下:

  現在讓我們在開啟D-Cache的情況下重新做文章 《實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(無緩存)》 中全部實驗:

  當 AHB_ADDR_START 取值範圍在 [0x60002400 - 0x60002418] 中時,Flash端的時序波形圖都是如下同一個。因為有了D-Cache,現在我們看不到周期性的CS信号了,說明除了Flash新位址通路是必須要通過FlexSPI外設去讀取Flash之外,其後的同一Flash位址的重複通路都直接發生在D-Cache裡了。

  另外D-Cache起始緩存位址永遠是32位元組對齊的位址處,并且一次緩存32byte的資料(因為D-Cache Line大小就是32byte),是以波形結果裡看,起始位址都是0x60002400,一次讀取32byte資料(存在一個D-Cache Line裡),是以之前不開D-Cache和Prefetch下的AHB Burst Read政策導緻的通路不同對齊位址的波形差異測試結果在這裡就不存在了。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  當實際代碼中要讀取的Flash資料會橫跨兩個相鄰32位元組對齊的資料塊(0x60002400 - 0x6000241f, 0x60002420 - 0x6000243f),此時Flash端會出現兩次CS有效信号,每次均傳輸32byte資料,D-Cache一直在持續作用,這次動用了兩個D-Cache Line(D-Cache總大小有32KB,共有1024個Cache Line),是以在Flash端我們還是看不到周期性CS信号。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  當代碼循環讀取1KB資料時,波形圖上可以看到32個CS有效信号,每個CS有效期間傳輸32byte資料,總計1KB資料的傳輸,D-Cache這次派出了32個 Cache Line,在Flash端我們依然看不到周期性CS信号。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  現在讓我們在開啟D-Cache的情況下重新做文章 《實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(有預取)》 中全部實驗:

  這種情況下,Flash端實際波形與 《實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(有預取)》 中 4.1 裡的測試結果差不多,這裡就不再貼圖了。Prefetch機制做第一層緩存,D-Cache擷取Prefetch Buffer裡的結果做二次緩存,唯一的差異是因為D-Cache的存在,緩存起始位址可能會發生變化(從八位元組對齊變成了32位元組對齊):

  這種情況下,Flash端會有兩次完整的1KB Prefetch操作,第一次Prefetch操作讀取了0x60002400處的1KB,第二次Prefetch操作讀取了0x60002800處的1KB。因為有D-Cache的存在,第二次Prefetch操作有了足夠時間去完成,不用額外插入軟延時去避免其被while(1)循環回來的下一次通路需求打斷了:

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  這種情況下,即使有D-Cache存在,第一次CS期間的Prefetch操作(即memcpy((void *)0x20200000, (void *)0x60002400, 0x100);引發的)還是被第二次CS的Prefetch操作打斷了(即memcpy((void *)0x20200400, (void *)0x60002800, 0x100);),但是第二次CS期間的Prefetch操作不會再被打斷,因為接下來while(1)循環回來的Flash資料通路需求已經緩存在D-Cache裡:

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  前面測試了那麼多種情況,我們有沒有可能在Flash端看到周期性CS信号呢,即Flash持續地被讀取呢?當然可以,我們知道D-Cache總大小是32KB,我們隻要循環拷貝32KB以上資料,D-Cache就開始hold不住了,這不,下面代碼就能讓我們看到久違的周期時序波形圖了(小心,Flash持續工作會多耗電的,哈哈)。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  至此,實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形痞子衡便介紹完畢了,掌聲在哪裡~~~

文章會同時釋出到我的 部落格園首頁、CSDN首頁、知乎首頁、微信公衆号 平台上。

微信搜尋"痞子衡嵌入式"或者掃描下面二維碼,就可以在手機上第一時間看了哦。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  最後歡迎關注痞子衡個人微信公衆号【痞子衡嵌入式】,一個專注嵌入式技術的公衆号,跟着痞子衡一起玩轉嵌入式。

痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)
痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)
痞子衡嵌入式:實抓Flash信号波形來看i.MXRT的FlexSPI外設下AHB讀通路情形(全加速)

  衡傑(痞子衡),目前就職于恩智浦MCU系統部門,擔任嵌入式系統應用工程師。

  專欄内所有文章的轉載請注明出處:http://www.cnblogs.com/henjay724/

  與痞子衡進一步交流或咨詢業務合作請發郵件至 [email protected]

  可以關注痞子衡的Github首頁 https://github.com/JayHeng,有很多好玩的嵌入式項目。

  關于專欄文章有任何疑問請直接在部落格下面留言,痞子衡會及時回複免費(劃重點)答疑。

  痞子衡郵箱已被私信擠爆,技術問題不推薦私信,堅持私信請先掃碼付款(5元起步)再發。