STM32 Ethernet for H7 Series
前言
Ethernet在ST高規格MCU中存在該Funtion,但都沒有機會認真研究,這次剛好有客戶提出問題在於Ethernet如果在開機狀態下不接上,事後在接上線路會無法連上ethernet,藉由這次機會來研讀該Function的使用方式與詳細細則
STM32CubeMX設定
先設定ETH設定RMII,這邊可以參考圖設計或英文文字設定
- The LEFT hardware uses the RMII pinout, while the RIGHT one is using MII pinout.
- On the LEFT one we have the option to choose the PHY Address. This should be set to 0, if you are using the on board LAN Port, and it should be 1 in case of the external module.
- On the RIGHT side, the MCU is letting us configure the memory for DMA descriptors, and the Rx Buffer.
- Assuming that each DMA Descriptor takes 32 bits (MAXIMUM Possible), the RX Descriptor and Tx Descriptor have the size of 128 Bytes (32×4).
- The Memory between them is spaced accordingly.
- The Rx Buffer have the size of 1524×4 (Rx DMA Descriptor Length).
- The memories are allocated in the SRAM region, where we can modify the properties later in the MPU.
另外開啟LWIP,這邊是以10KB為一個單位的the Heap
注意一定要把LWIP_NETIF_LINK_CALLBACK選上,不然連線狀態改變不能進入拔下或插入網路線回呼函數
Cortex-M7設定
Lwip使用DMA傳遞訊息,對應的DMA記憶體定義在sram。 H7的sram分為好幾段,高速段為cpu獨享,通俗點說就是這段允許使用者寫的程式使用,但不允許DMA使用。 所以為DMA定義的記憶體或數組要避開這一段。 另外Lwip使用DMA時有互動存取問題,避開這段後,也不能讓cpu像使用普通cache那樣亂序使用,否則將可能出現嚴重問題。
(1)Lwip不被允許使用cpu專用的高速L1快取(DTCM),只能用D2 Sram區域;
(2)cpu可以無序存取cache,為防止這種情況,Lwip的DMA段必須是device類型或Strongly-ordered類型,保證有序;
(3)透過MPU配置這段cache,其中一段允許share、允許buffer,長度為256Byte,放置TXRX互動存取頭;另外一段不share,不buffer,不cache;長度32k
Coding (添加簡單的 Hello UDP )
在 main.c 的開頭新增以下包含檔案:
#include “lwip/udp.h”
#include <string.h>
在 main.c 寫入
/* USER CODE BEGIN 5 */
const char* message = "Hello UDP message!\n\r";
osDelay(1000);
ip_addr_t PC_IPADDR;
IP_ADDR4(&PC_IPADDR, 192, 168, 1, 1);
struct udp_pcb* my_udp = udp_new();
udp_connect(my_udp, &PC_IPADDR, 55151);
struct pbuf* udp_buffer = NULL;
/* Infinite loop */
for (;;) {
osDelay(1000);
/* !! PBUF_RAM is critical for correct operation !! */
udp_buffer = pbuf_alloc(PBUF_TRANSPORT, strlen(message), PBUF_RAM);
if (udp_buffer != NULL) {
memcpy(udp_buffer->payload, message, strlen(message));
udp_send(my_udp, udp_buffer);
pbuf_free(udp_buffer);
}
}
/* USER CODE END 5 */