STM32網路控制器框圖如下:

?
前面的文章我們已經講解了:
①External PHY Intereface:《STM32網路電路設計》
②MAC控制器:《STM32MAC控制器》
下面我們講解第③部分,STM32網路的DMA控制器,
01、DMA控制器操作
DMA具有自主的發送和接收引擎,還有一個CSR(控制和狀態暫存器)空間,發送引擎將資料從系統存盤器傳送到 TxFIFO,而接收引擎將資料從Rx FIFO傳送到系統存盤器,
控制器(也就是DMA)利用描述符有效的將資料從源地址移動到目的地,很小的CPU干預,DMA專為面向包的資料傳送(如以太網中的幀)而設計,
控制器可以編程去打斷CPU,例如完成幀發送和接收傳送操作時以及其它正常/錯誤條件下,
DMA和STM32F20x 和STM32F21x通過以下兩種資料結構進行通信:
-
控制和狀態暫存器 (CSR)
-
描述符串列和資料緩沖區,
DMA控制器發送接收到的資料幀到STM32F20x的接收快取中和STM32F21x存盤器中,也可以發送資料幀從STM32F20x的存盤器的發送快取,位于STM32F20x存盤器的描述符指向這些快取,
這里有兩個描述符串列:一個用于接收,一個用于發送,
DMA描述符如下圖,左邊是環形結構,右邊是鏈式結構,

?
02、DMA描述符
在ST提供的以太網驅動庫stm32f2x7_eth.c中使用是鏈接結構,鏈接結構如下:

?
描述符注意事項:
1、一個以太網資料包可以跨越一個或多個DMA描述符
2、一個DMA描述符只能用于一個以太網資料包
3、DMA描述符串列中的最后一個描述符指向第一個,形成鏈式結構!
描述符有分為增強描述符和常規描述符,我們只講常規描述符!因為我們的網路例程只使用到了常規描述符,常規描述符和增強描述符的結構體成員變數不同,常規描述符只使用了描述符的前4個成員變數,
注意:這里說的描述符,沒有硬體結構,不是暫存器,它完全是純軟體的概念,
那么描述符怎么和硬體關聯的呢?
描述符的本質就是我們自己用結構體來實作這個描述符,然后將描述符的首地址寫入到【ETH_DMATDLAR】暫存器中,STM32就知道這片記憶體是用來作為發送描述符了,
常規描述符和增強描述符又有發送描述符和接收描述符兩種,
下圖是常規TxDMA描述符:

?
TDES0主要用來表示描述符的狀態和控制資訊,
TDES1表示該描述符緩沖區資料的有效長度,
TDES2表示描述符緩沖區的地址,我們要發送的資料,就是放在這個地址所指向的記憶體中,
TDES3表示下一個描述符的地址,
重要的資訊有:
TDES 0中的OWN位:
0:表示CPU占有描述符,CPU可以從DMA中提取資料,但是DMA不能從FIFO從接收資料,
1:表示DMA占有描述符,CPU不可以從DMA中提取資料,DMA可以從FIFO從接收資料,
DMA在傳輸完整個幀或者這個快取里的資料全部讀出以后把該位清0',每個幀的第一個快取描述符的占有位,必須在后面快取描述符的占有位全部置'1'以后,才能置"1',
發送程序:
1、當OWN位為0的時候,表示CPU可以將要發送的資料拷貝到描述符中,拷貝完成以后,我們手動將描述符的OWN位設定為1,以此來告訴DMA控制器,我已經拷貝完資料了,你可以從描述符中取出資料進行發送了,
2、這時候DMA就會取出描述符中的資料,將資料發送出去,DMA在操作完描述符以后,自動將OWN位設定為0,告訴CPU,我DMA已經發送完資料啦,你可以拷貝下一幀資料到描述符上了,
3、這個時候OWN為0了,重復步驟1
整個發送的程序就是這樣配合的,這樣DMA和CPU之間就不會搶占資料了,
DES 0中的位20 TCH:鏈接的第二個地址(Second address chained)
用來表示描述符中的第二個地址是用來保存下一個描述符地址還是第二個緩沖區的地址,
該位置1時,表示描述符中的第二個地址是下一個描述符地址,而非第二個緩沖區地址,也就是上ST使用的鏈式結構,
常規RxDMA描述符如下

?
常規RxDMA描述符中RDES1的bit14用來表示描述符中的第二個地址是用來保存一個描述符地址還是第二個緩沖區的地址,
描述符在代碼中的表現,在stm32f2x7_eth.h檔案中,
/**--------------------------------------------------------------------------**/ /** * @brief DMA descriptors types */ /**--------------------------------------------------------------------------**/ /** * @brief ETH DMA Descriptors data structure definition */ typedef struct { __IO uint32_t Status; /*!< Status */ uint32_t ControlBufferSize; /*!< Control and Buffer1, Buffer2 lengths */ uint32_t Buffer1Addr; /*!< Buffer1 address pointer */ uint32_t Buffer2NextDescAddr; /*!< Buffer2 or next descriptor address pointer */ /* Enhanced ETHERNET DMA PTP Descriptors */ #ifdef USE_ENHANCED_DMA_DESCRIPTORS uint32_t ExtendedStatus; /* Extended status for PTP receive descriptor */ uint32_t Reserved1; /* Reserved */ uint32_t TimeStampLow; /* Time Stamp Low value for transmit and receive */ uint32_t TimeStampHigh; /* Time Stamp High value for transmit and receive */ #endif /* USE_ENHANCED_DMA_DESCRIPTORS */ } ETH_DMADESCTypeDef;
03、ST提供的庫中描述符
ST官方以太網庫stm32f2x7中使用鏈接結構的DMA描述符,那么在以太網描述符結構體ETH_DMADESCTypeDef中Buffer1Addr就是緩沖區的地址,Buffer2NextDescAddr就是下一個描述符的地址,
如下圖,

?
在stm32f2x7_eth.c中定義了兩個DMA描述符陣列,一個用于DMA接收,一個用于DMA發送,如下:

?
接收和發送描述的大小通過宏ETH_RXBUFNB和ETH_TXBUFNB來定義,默認都為5,
我們知道以鏈接結構太網描述符的Buffer1Addr成員用來存放緩沖區地址,那么資料緩沖區在哪里?這個資料緩沖區也是定義為陣列的,如下:

?
把他們聯系在一起的代碼,把描述符和緩沖區聯系起來,也就是下面的函式把描述符標構成鏈式結構,
在ethernetif.c的low_level_init函式中

?
決議如下

?
全域描述符指標,用來記錄當前使用的描述符

?
描述資料包的描述符(英文:用于保存最后一個接收的包描述符資訊的結構,)

?
結構體

?
第一個表示資料包的第一個描述符,第二個表示資料包的最后一個描述符,第三個表示資料包描述符的個數,
最終的效果如下:

?
04、FIFO
從STM32網路控制器框圖中可以看到兩個2KB的FIFO,一個發送FIFO,一個接收FIFO,
發送FIFO
提供兩種FIFO資料模式用于幀傳輸
-
閾值模式:當達到閾值后,盡快傳輸資料,
-
Store-and-Forward mode:FIFO中會存盤一個完整的幀結構,
STM32的發送FIFO采用Store-and-Forwardmode模式,

?
接收FIFO
接收FIFO采用Store-and-Forwardmode模式,

?
點擊查看本文所在的專輯,STM32F207網路開發
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/273094.html
標籤:嵌入式
