在單片機(jī)或者是嵌入式編程中,通常軟件和硬件是緊密相連的。編程者需要同時擁有硬件思維和軟件技巧,才能使程序更高效、更穩(wěn)定的運(yùn)行在嵌入式系統(tǒng)中。在機(jī)器人系統(tǒng)中,各個模塊間的通信就像人的神經(jīng),往往需要很高帶寬與實(shí)時性,借助DMA和FIFO能夠極大程度的發(fā)揮出外設(shè)的性能。本文將介紹使用FIFO和DMA搭配的方式,并且詳細(xì)介紹其運(yùn)作的原理。? ? ? ??
作業(yè)無人機(jī)的通鏈路 ▌本文所述FIFO都是軟件FIFO,不包括部分DMA控制器中自帶的FIFO功能。
FIFO
FIFO是“先進(jìn)先出”的縮寫,是一種常用的數(shù)據(jù)結(jié)構(gòu)和算法。它是一種隊(duì)列(Queue)的實(shí)現(xiàn)方式,即先進(jìn)入隊(duì)列的數(shù)據(jù)項(xiàng)先被處理,后進(jìn)入隊(duì)列的數(shù)據(jù)項(xiàng)則后被處理。 環(huán)形隊(duì)列是一種特殊的FIFO數(shù)據(jù)結(jié)構(gòu),其中隊(duì)列被表示為一個環(huán)形結(jié)構(gòu)。在環(huán)形隊(duì)列中,隊(duì)列的頭部和尾部被視為相鄰的元素,因此當(dāng)尾部元素到達(dá)隊(duì)列的末尾時,它會回到隊(duì)列的開頭。這樣,隊(duì)列看起來像一個環(huán),因此稱為環(huán)形隊(duì)列。環(huán)形隊(duì)列可以使用數(shù)組實(shí)現(xiàn),但需要特殊處理插入和刪除元素的操作,以確保它們在隊(duì)列頭部和尾部之間循環(huán)。
FIFO可以用于緩存數(shù)據(jù),當(dāng)輸入數(shù)據(jù)的速度超過處理的速度時,F(xiàn)IFO可以作為一個緩沖區(qū),暫時存儲多余的數(shù)據(jù),以平滑數(shù)據(jù)的輸入和輸出速度。另外,當(dāng)需要頻繁地訪問內(nèi)存或外設(shè)時,F(xiàn)IFO可以作為一個臨時緩存區(qū),將數(shù)據(jù)暫時存儲在隊(duì)列中,以減少對內(nèi)存或外設(shè)的頻繁訪問,提高系統(tǒng)的效率。
DMA
DMA(Direct Memory Access,直接內(nèi)存訪問)。常規(guī)情況下,我們對外設(shè)的操作都是由CPU直接處理,但面向與一些低速的傳輸手段,如:IIC、UART、SPI,為了保證時序,使用CPU操作寄存器的方法去處理無疑浪費(fèi)了大量的運(yùn)算時間。而DMA的出現(xiàn),可以使數(shù)據(jù)可以在主存儲器和外設(shè)之間自動傳輸,而不需要CPU的干預(yù)。這可以使CPU在數(shù)據(jù)傳輸期間執(zhí)行其他任務(wù),提高整個系統(tǒng)的效率。
如上圖所示兩條通道中,CPU只需要和DMA進(jìn)行一些指令通信,DMA就能替CPU完成對外設(shè)到內(nèi)存的數(shù)據(jù)搬運(yùn)。 ▌DMA也可完成內(nèi)存到內(nèi)存等多種方式的通信,不同的廠商的芯片通常會有一些專用的DMA控制器例如:DMA2D、MDMA等,但本質(zhì)都是對內(nèi)存的直接訪問。
傳輸過程
DMA的傳輸大致分為如下三個步驟:
預(yù)處理:由CPU完成一些必要的準(zhǔn)備工作。首先,CPU執(zhí)行幾條I/O指令,用以測試I/O設(shè)備狀態(tài),向DMA控制器的有關(guān)寄存器置初值,設(shè)置傳送方向、啟動該設(shè)備等。然后,CPU繼續(xù)執(zhí)行原來的程序,直到I/O設(shè)備準(zhǔn)備好發(fā)送的數(shù)據(jù)(輸入情況)或接受的數(shù)據(jù)(輸出情況)時,I/O設(shè)備向DMA控制器發(fā)送DMA請求,再由DMA控制器向CPU發(fā)送總線請求(統(tǒng)稱為DMA請求),用以傳輸數(shù)據(jù)。
數(shù)據(jù)傳送:DMA的數(shù)據(jù)傳輸可以以單字節(jié)(或字)為基本單位,對于以數(shù)據(jù)塊為單位的傳送,DMA占用總線后的數(shù)據(jù)輸入和輸出操作都是通過循環(huán)來實(shí)現(xiàn)。需要特別之處的是,這一循環(huán)也是由DMA控制器(而不是通過CPU執(zhí)行程序)實(shí)現(xiàn)的,即數(shù)據(jù)傳送階段是完全由DMA(硬件)來控制的。
后處理:DMA控制器向CPU發(fā)送中斷請求,CPU執(zhí)行中斷服務(wù)程序做DMA結(jié)束處理,包括檢驗(yàn)送入主存的數(shù)據(jù)是否正確,測試傳送過程中是否出錯(錯誤則轉(zhuǎn)入診斷程序)和決定是否繼續(xù)使用DMA傳送其他數(shù)據(jù)塊等。
由此可以看出,整個過程中,CPU只需要介入預(yù)處理和后處理的少量指令環(huán)節(jié)。在一些特殊情況下,例如ADC數(shù)據(jù)的DMA傳輸,只需要在初始化時進(jìn)行配置,DMA設(shè)置為循環(huán)模式,后續(xù)的過程完全不需要CPU介入,極大的節(jié)約了CPU時間。
快遞員與快遞站
在實(shí)際生活中,我們隨處可見DMA和FIFO的身影,為了能更加方便的理解DMA和FIFO的作用,我們可以用快遞員和快遞站來做比喻:
FIFO(先進(jìn)先出隊(duì)列)是一個快遞站,快遞員將快遞按照到達(dá)時間順序放在一個隊(duì)列中,當(dāng)需要發(fā)貨時,按照隊(duì)列順序一個一個地取出快遞進(jìn)行發(fā)貨,保證了快遞的順序性??爝f站如果太小,如果收發(fā)快遞數(shù)量太多,快遞站就會爆滿堵塞,快遞丟失。如果快遞站過大,則占用過多土地,得不償失。
DMA(直接內(nèi)存訪問)是一名任勞任怨的快遞員,他可以直接到發(fā)貨地點(diǎn)取出快遞并將其送到目的地,中間的驛站可以視為內(nèi)存或者緩存。在這個過程中,快遞員可以不停歇地工作,而不需要等待驛站的確認(rèn),同時也不需要用戶的干預(yù),可以大大提高快遞的效率和速度。
DATA(數(shù)據(jù)),數(shù)據(jù)則是快遞,快遞的尺寸數(shù)量要考慮快遞員的能力,不能過大過多。
無論是現(xiàn)實(shí)還是嵌入式系統(tǒng),人和內(nèi)核不可能時時刻刻都帶等待快遞和數(shù)據(jù)。數(shù)據(jù)的處理和接收并不一定是同時進(jìn)行的,內(nèi)核對數(shù)據(jù)的等待造成了系統(tǒng)的阻塞,但數(shù)據(jù)的不及時處理會造成了數(shù)據(jù)的丟包,以上兩個原因促使了DMA和FIFO的相互補(bǔ)充使用。
更高的效率
以上用具體的例子比喻了DMA和FIFO的應(yīng)用場景,實(shí)際應(yīng)用也當(dāng)如此。以下會介紹詳細(xì)的使用方法和具體的應(yīng)用場景,同時開發(fā)者也要認(rèn)清,并不是所有的場景都適合使用DMA,使用時要考慮實(shí)際的穩(wěn)定性和必要性。
應(yīng)用場景
下面將列舉幾種場景,分別是DMA與軟件FIFO配合、DMA以及不適合DMA場景的應(yīng)用。
▌DMA-FIFO
DMA-FIFO最適合數(shù)據(jù)量大、不定長的數(shù)據(jù)包的場景,典型應(yīng)用為串口通信,無論是串口的接收還是發(fā)送,使用DMA-FIFO都能極大的增加芯片的運(yùn)行效率,且在絕大多數(shù)情況下都能提高串口外設(shè)的性能。PWM、GPIO操作算是DMA應(yīng)用中一個比較冷門的應(yīng)用,使用DMA操作此類外設(shè),能零堵塞、高時序精度去實(shí)現(xiàn)W2812全彩燈、DSHOT協(xié)議等功能。
▌DMA
單用DMA適合數(shù)據(jù)量大、定長、定周期的場景,典型應(yīng)用為SPI-LCD數(shù)據(jù)傳輸、攝像頭DCMI傳輸、ADC傳輸、內(nèi)存-內(nèi)存?zhèn)鬏敚祟悅鬏斕攸c(diǎn)大多數(shù)為大塊數(shù)據(jù)周期性傳輸,傳輸速度要求高,數(shù)據(jù)量比較大。例如在攝像頭數(shù)據(jù)的傳輸過程中,攝像頭數(shù)據(jù)固定以30FPS進(jìn)行傳輸,配合DMA的雙緩存功能能很好的實(shí)現(xiàn)數(shù)據(jù)的傳輸與處理同時進(jìn)行,此外像DMA2D這種專用的圖像顯示DMA也是相同的道理。
▌不適用場景
雖然DMA在許多情況下可以提高數(shù)據(jù)傳輸?shù)男屎退俣?,但并不是所有情況都適合使用DMA。下面是一些不適合使用DMA的場合:
數(shù)據(jù)一致性場合:DMA傳輸過程中不需要CPU干預(yù),所以實(shí)際上CPU并不知道內(nèi)存中數(shù)據(jù)發(fā)生了變動,尤其是在啟用了cache的情況下,數(shù)據(jù)一致性問題就變得尤其嚴(yán)重。例如一些加密、解密、固件寫入等場合,對數(shù)據(jù)一致性要求較高、需要實(shí)時校驗(yàn),不建議使用DMA傳輸。
時序一致性場合:DMA也不適合對于數(shù)據(jù)包時序要求嚴(yán)格的場合,例如在SPI寫入LCD數(shù)據(jù)指令前,需要先寫入控制指令并操作DC引腳,在這種情況下,如果不能將傳輸與中斷的邏輯進(jìn)行妥善處理,則會造成嚴(yán)重的數(shù)據(jù)沖突,所以SPI-LCD屏一般只有在數(shù)據(jù)階段采用DMA傳輸。還有在初始化階段,程序?qū)τ谛仕俣鹊囊蟛桓撸珪r序與穩(wěn)定性要求較高的時候,不建議使用DMA傳輸。
數(shù)據(jù)傳輸量較小:由于DMA傳輸存在預(yù)處理和后處理階段,例如僅傳輸幾個字節(jié)的數(shù)據(jù),那么使用DMA可能不會帶來很大的性能提升。相反CPU可能需要反復(fù)進(jìn)入中斷進(jìn)行處理,增加了額外的復(fù)雜性和成本。
技巧與細(xì)節(jié)
在DMA的使用過程中,也存在很多的使用技巧,例如利用好DMA的全傳輸中斷、半傳輸中斷與雙緩存,能使DMA的傳輸性能得到進(jìn)一步的提高。熟悉DMA的基本屬性,需要仔細(xì)的去閱讀相應(yīng)芯片廠商的技術(shù)手冊,避免其在傳輸中發(fā)生沖突,數(shù)據(jù)發(fā)生覆蓋等問題的發(fā)生。
總結(jié)
FIFO和DMA的應(yīng)用只是嵌入式系統(tǒng)中優(yōu)化的一小部分,對于開發(fā)者來說,在開發(fā)過程中,“能用”并不是調(diào)好一個外設(shè)的標(biāo)準(zhǔn)。在項(xiàng)目調(diào)試工程中,往往會遇到因?yàn)榇蛴×藥仔腥罩尽⒆兏藚f(xié)議格式、更改了通信速率,就發(fā)現(xiàn)程序就不能正常運(yùn)行了,不嚴(yán)謹(jǐn)、不規(guī)范的開發(fā)方式容易使項(xiàng)目陷入Bug越改越多的開發(fā)陷阱中。
審核編輯:劉清
-
單片機(jī)
+關(guān)注
關(guān)注
6067文章
44989瀏覽量
650345 -
嵌入式
+關(guān)注
關(guān)注
5150文章
19665瀏覽量
317427 -
fifo
+關(guān)注
關(guān)注
3文章
401瀏覽量
44806 -
uart
+關(guān)注
關(guān)注
22文章
1276瀏覽量
103911 -
dma
+關(guān)注
關(guān)注
3文章
576瀏覽量
103206
原文標(biāo)題:數(shù)據(jù)[快遞站]——探索FIFO與DMA
文章出處:【微信號:雨飛工作室,微信公眾號:雨飛工作室】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
DMA產(chǎn)生FIFO error interrupt錯誤的原因?
關(guān)于FIFO DMA
請問F28M35x ADC結(jié)果使用DMA方式傳輸時DMA模塊有緩沖區(qū)(FIFO)可用嗎?
STM32F765+SN8000+DMA FIFO錯誤
dma+空閑中斷加fifo實(shí)現(xiàn)串口的高效收發(fā)
LabVIEW FPGA模塊實(shí)現(xiàn)FIFO深度設(shè)定

以太網(wǎng)基礎(chǔ)介紹:MAC地址,FIFO, DMA
STM32F429芯片帶FIFO的DMA傳輸實(shí)現(xiàn)過程

MZ7035系列開發(fā)板XILINX FPGA DMA和VDMA的應(yīng)用教程

DMA通信編程與STM32串口中斷方式

STM32采用串口DMA方式向上位機(jī)連續(xù)發(fā)送數(shù)據(jù)

AN3109_用STM32F10x微控制器的DMA和DMA超時仿真通信外設(shè)FIFO

評論