天天看點

DMA/TCM/Cache的了解1.DMA2.TCM3.Cache

目錄

1.DMA

2.TCM

2.1 對ARM禁止記憶體TCM的了解

3.Cache

1.DMA

DMA=Direct Memory Access。這是一種通過硬體實作的資料傳輸機制。簡單的說,就是不在CPU的參與下完成資料的傳輸。

DMA是一種硬體裝置。這種裝置的工作原理是這樣的:

——首先CPU告訴DMA裝置,要有一堆資料需要傳輸,為了效率而請它出馬。(DMA請求)

——DMA收到CPU的消息,開始準備。此時CPU把資料源位址、資料目标位址、傳輸資料量、傳輸模式等等參數告訴它。(DMA初始化)

——DMA初始化完,向CPU發送消息“借你的總線用一用,我要開始傳輸資料了!”(總線出借,DMA啟動)

——CPU收到消息後,暫時切斷自己與總線的聯系。DMA開始傳輸資料。(DMA資料)

——DMA傳輸完資料之後,向CPU發送消息“搞定了!總線還給你。”(總線歸還)

——CPU說:“幹得好!老将出馬一個頂倆!辛苦了,你先歇着吧。”DMA裝置停止。CPU該幹啥幹啥。

由于是硬體實作的,是以DMA的速度非常快。快到什麼程度呢?在DS上,尤其是資料量非常大的時候,相比于CPU當中介,效率能夠提高一百萬倍以上。

由于DMA的速度是如此之快,是以大量的資料傳輸,一般都要求使用DMA。

2.TCM

TCM=Tightly Coupled Memory,是一種高速緩存,據說是被直接內建在CPU晶片中。DS有兩種TCM,分别是ITCM(Instruction TCM)和DTCM(Data TCM)。

注意:

1.記憶體支援清單中,記憶體詳細參數裡,SS指的是單面記憶體,DS指的是雙面記憶體。記憶體一共有兩面,根據記憶體總容量和記憶體晶片的存儲容量,記憶體廠家會生産雙面記憶體和單面記憶體,也就是記憶體的兩面都有存儲晶片,或者隻有一面有存儲晶片。單雙面記憶體在相容性上有一定差別,是以會單獨列出來。

2。ITCM是cortex核心中指令傳輸總線,DTCM是cortex核心中資料傳輸總線

是cpu核心同flash及sram之間傳輸指令和資料的通道,指令的取指和執行及資料的讀寫在性能及管理上存在差異性,因而需要予以區分。

由于是高速緩存,是以這兩塊記憶體區域被當做特殊的用途。比如某些對時間要求非常嚴格的代碼,就可以被放到ITCM中執行。這可以有效地提高運作速度。某些需要頻繁存取的資料,也可以放到DTCM中以節省存取時間。

怎麼樣把代碼放到ITCM中?有兩種方法。一種是使用gcc特有的“屬性标簽”,将指定代碼賦予“ITCM”屬性,此時該代碼會被載入ITCM中執行。還有一種方法是直接将.c源檔案改成.itcm.c,此時源檔案會被直接編譯成在ITCM中運作的目标檔案。

而DTCM就友善得多了。雖然兩個TCM都是可映射的,也就是說,它們的位址并非固定,但是一般會将其分别映射到固定位址。既然已經有了固定位址,那麼就可以很輕松地通路了。不過,正如剛才所說的,這兩塊記憶體空間都是有特殊用途的,是以不建議直接通路。相比于ITCM來說,DTCM更加重要。因為在這塊記憶體中,存在着一個非常重要的對象——棧。局部變量和函數調用的參數,就是靠棧進行傳遞的。由于DMA無法通路TCM,是以也就無法通路棧。又由于局部變量是被開辟到棧中,是以DMA也無法對局部變量進行傳遞。

2.1 對ARM禁止記憶體TCM的了解

摘自對ARM緊緻記憶體TCM的了解

ARM 的ram包括靜态ram,動态ram,TCM。

TCM是一個固定大小的RAM,緊密地耦合至處理器核心,提供與cache相當的性能,相比于cache的優點是,程式代碼可以精确地控制什麼函數或代碼放在那兒(RAM裡)。當然TCM永遠不會被踢出主存儲器,是以,他會有一個被使用者預設的性能,而不是象cache那樣是統計特性的性能提高。

TCM對于以下幾種情況的代碼是非常有用、也是需要的:可預見的實時處理(中斷處理)、時間可預見(加密算法)、避免cache分析(加密算法)、或者隻是要求高性能的代碼(編解碼功能)。随着cache大小的增加以及總線性能的規模,TCM将會變得越來越不重要,但是他提供了一個讓你權衡的機會

那麼,哪一個更好呢?他取決于你的應用。Cache是一個通用目的的加速器,他會加速你的所有代碼,而不依賴于存儲方式。TCM隻會加速你有意放入TCM的代碼,其餘的其他代碼隻能通過cache加速。Cache是一個通用目的解決方案,TCM在某些特殊情況下是非常有用的。假如你不認為需要TCM的話,那麼你可能就不需要了,轉而加大你的cache,進而加速運作于核心上的所有軟體代碼

緊緻記憶體是指片上快速存儲區,與片上緩存具有同等的性能,但因為程式可完全控制緊緻記憶體,因而比統計複用的緩存有更好的可預測性。這是ARM5TE引入的特性,目的是通過這一快速的存儲區,一方面提高某些關鍵代碼(如中斷處理函數)的性能,另方面使存儲通路延遲保持一緻,這是實時性應用所要求的。ARM6對TCM操作做了進一步的規範。

TCM的應用領域:可預測的實時處理(中斷處理)、避免緩存分析(加密算法)、或單純的性能提高(處理器側編解碼)等。

如同緩存的哈佛結構,指令TCM和資料TCM是分開的。TCM有兩種使用方式:作為快緩存使用,和作為本地記憶體使用。

本地記憶體

這時,TCM被用作更快速的記憶體,如同一般的RAM。因為指令段有時也是資料通路的對象,指令TCM實際上是指令資料一體化TCM。對TCM寫操作後和後續對此寫操作的依賴指令之間必須跟一個阻塞操作。

快緩存(smartcache)

TCM可以配置成當作外部RAM的緩存使用,對應的外部RAM也要設定可緩存标志。如果被緩存的外部RAM可以由多處理器共享,那麼TCM是否與共享資料保持一緻并沒有規定,而由具體實作廠家決定。

TCM與緩存的内容不會自動保持一緻,這意味着TCM映射到的記憶體區域必須是不緩存的區域。如果一個位址同時落在緩存和TCM内,那麼通路這一位址的結果是不能預測的。另一個限制是各個TCM必須要配置成不相交的。

TCM的配置

通過CP15的0、1、9号寄存器進行:

0号寄存器

讀CP15的0号寄存器,opcode2為2:

MRC p15, 0, Rd, C0, C0, 2

傳回TCM狀态寄存器的内容,其中,16-18位代表資料TCM個數,0-3代表指令TCM個數。

1号寄存器

ARM6之前,1号寄存器的16位和18位用于使能資料TCM和指令TCM(ARM946,ARM966),ARM6因為可以使用9号寄存器控制每一塊TCM的使能狀态,是以1号寄存器的這兩個位就過時了,應該置1。

9号寄存器

每個TCM都有一個TCM區域寄存器,設定這個寄存器就可以設定TCM的基址和大小。在設定TCM區域寄存器前,需要設定TCM選擇寄存器。

下面是通路這些相關寄存器的指令:

ARM Instruction                             TCM Region Register

MRC/MCR P15, 0, Rd, C9, C1, 0      Data TCM Region Register

MRC/MCR P15, 0, Rd, C9, C1, 1      Instruction/Unified TCM Region Register

MRC/MCR P15, 0, Rd, C9, C2, 0      TCM Selection Register

TCM區域寄存器的結構:

Base Address (Physical Address)[31-12] SBZ/UNP[11-7] Size[6-2] SC[1] En[0]

其中:

En位是使能位,置1時使能此TCM;

SC位置位表示此TCM被用作快緩存(smartcache),清零表示本地記憶體;

Size字段是隻讀的,含義如下:

Size         Memory     Size             Memory

filed        size             field            size

0b00000     0K            0b01101     4M

0b00011     4K            0b01110     8M

0b00100     8K            0b01111     16M

0b00101     16K          0b10000     32M

0b00110     32K          0b10001     64M

0b00111     64K          0b10010     128M

0b01000     128K        0b10011     256M

0b01001     256K        0b10100     512M

0b01010     512K        0b10101     1G

0b01011     1M           0b10110     2G

0b01100     2M           0b10111     4G

3.Cache

衆所周知CPU的速度非常快。當CPU通路外設的時候,有些外設速度比較慢,響應CPU比較遲鈍。此時CPU要麼等外設響應,要麼繼續幹它的活等外設的中斷信号。但是有些外設是沒有中斷的。此時CPU就必須等了。最典型的例子就是記憶體。當CPU通路記憶體的時候,并非像你想象的那樣,CPU立刻就能通路到它想通路的記憶體空間,而是有一個“WaitState”的過程。想想看吧,每通路一次記憶體都要等上幾個機器周期,這可不是個好事~~~尤其是,這個“幾”可不是簡單的一位數,有些時候甚至能達到3位數。

那麼這個問題又該怎麼解決呢?那就是Cache了。

Cache是內建在CPU内部的極高速的緩存。注意關鍵詞“極高速”。一般來說,它的通路速度幾乎可以媲美CPU。這就意味着,CPU在通路Cache的時候幾乎不會浪費多少時間。不過,速度的提升是用容量作為代價的。Cache的容量很小。

那麼,我們把常用的資料放到Cache中,CPU在通路的時候直接通路Cache就行了,不用耗費時間去通路記憶體了。

事實上CPU就是這麼做的。在讀記憶體的時候,CPU首先讀Cache,看看有沒有它想要的資料的“副本”,有的話那就太好了,直接拿過去用。沒有的話就隻好費點功夫去讀記憶體了。而在寫記憶體的時候,CPU直接寫到Cache中,而非直接寫到記憶體中。Cache寫滿了之後,此時才将Cache中的資料更新到記憶體,同時清空Cache。就像寄信一樣,所有的信件會首先攢到郵局,到達一定數量之後才會送出去。

不過這又出現一個問題:假如Cache中有某個記憶體資料的“副本”,那麼CPU在讀該記憶體的時候就會直接使用該副本而不用去讀記憶體。那萬一記憶體中的資料被改寫,此時CPU再讀該記憶體,讀出來的豈不是那個舊的副本而不是最新的記憶體資料?同樣,假如我想DMA一些資料,誰能保證此時記憶體中的資料就是最新的資料?很可惜,Cache是完全的黑箱。你不知道它的位址。你也無法直接通路它,但一般系統會提供函數進行cache回寫和clear操作,比如

//将整個Data Cache更新到記憶體

void DC_FlushAll()

// 清空整個Data Cache

void DC_InvalidateAll()

那麼,什麼時候使用這些函數呢?

在DMA之前,我需要保證資料源記憶體中的資料是最新的。是以此時需要Flush,進而使DC中的副本能夠更新到記憶體中。

在DMA之後,我需要保證DC中的副本和記憶體中的資料是相同的。但是NDSLIB沒有更新DC的函數,是以沒辦法,我們隻能把DC中的副本殺掉。此時如果CPU通路記憶體,由于DC中沒有副本,是以就隻能直接從記憶體通路并将通路到的值作為DC中副本了。是以此時需要Invalidate