一欢搜、ETH簡介
STM32F4xx 系列控制器內(nèi)部集成了一個以太網(wǎng)外設牛曹,它實際是一個通過 DMA 控制器進行介質(zhì)訪問控制(MAC),它的功能就是實現(xiàn) MAC 層的任務瓢娜。借助以太網(wǎng)外設挂洛,STM32F4xx 控制器可以通過 ETH 外設按照 IEEE 802.3-2002 標準發(fā)送和接收 MAC 數(shù)據(jù)包。ETH 內(nèi)部自帶專用的 DMA 控制器用于 MAC眠砾,ETH 支持兩個工業(yè)標準接口介質(zhì)獨立接口(MII)和簡化介質(zhì)獨立接口(RMII)用于與外部 PHY 芯片連接虏劲。MII 和 RMII 接口用于 MAC 數(shù)據(jù)包傳輸,ETH 還集成了站管理接口(SMI)接口專門用于與外部 PHY 通信,用于訪問 PHY 芯片寄存器柒巫。
物理層定義了以太網(wǎng)使用的傳輸介質(zhì)励堡、傳輸速度、數(shù)據(jù)編碼方式和沖突檢測機制堡掏,PHY 芯片是物理層功能實現(xiàn)的實體应结,生活中常用水晶頭網(wǎng)線+水晶頭插座+PHY 組合構成了物理層。
ETH 有專用的 DMA 控制器泉唁,它通過 AHB 主從接口與內(nèi)核和存儲器相連鹅龄,AHB 主接口用于控制數(shù)據(jù)傳輸,而 AHB 從接口用于訪問“控制與狀態(tài)寄存器”(CSR)空間亭畜。在進行數(shù)據(jù)發(fā)送是扮休,先將數(shù)據(jù)有存儲器以 DMA 傳輸?shù)桨l(fā)送 TX FIFO 進行緩沖,然后由 MAC 內(nèi)核發(fā)送拴鸵;接收數(shù)據(jù)時肛炮,RX FIFO 先接收以太網(wǎng)數(shù)據(jù)幀,再由 DMA 傳輸至存儲器宝踪。ETH 系統(tǒng)功能框圖見下圖侨糟。
二、LwIP簡介
LwIP 是 Light Weight Internet Protocol 的縮寫瘩燥,是由瑞士計算機科學院 Adam Dunkels等開發(fā)的適用于嵌入式領域的開源輕量級 TCP/IP 協(xié)議棧秕重。它可以移植到含有操作系統(tǒng)的平臺中,也可以在無操作系統(tǒng)的平臺下運行厉膀。由于它開源溶耘、占用的 RAM 和 ROM 比較少、支持較為完整的 TCP/IP 協(xié)議服鹅、且十分便于裁剪凳兵、調(diào)試,被廣泛應用在中低端的 32 位控制器平臺企软。
針對 LwIP 應用開發(fā)了測試平臺庐扫,其中有一個是在 STM32F4x7 系列控制器運行的
(文件編號為:STSW-STM32070)。
- LwIP官網(wǎng):http://savannah.nongnu.org/projects/lwip/
2.1 靜態(tài)IP
靜態(tài)IP地址(又稱固定IP地址)是長期分配給一臺計算機或網(wǎng)絡設備使用的 IP 地址仗哨。一般來說形庭,一般是特殊的服務器或者采用專線上網(wǎng)的計算機才擁有固定的 IP 地址而且需要比較昂貴的費用。靜態(tài)IP是二級路由必須用到的厌漂。
靜態(tài)IP是可以直接上網(wǎng)的IP段萨醒,該IP在ISP裝機時會劃分一個IP地址給你,讓計算機在連接網(wǎng)絡時不再自動獲取網(wǎng)絡地址苇倡,避免了網(wǎng)絡連接上的困擾富纸,寬帶運營商會提供一根一個IP地址囤踩、子網(wǎng)掩碼、網(wǎng)關和DNS服務器地址給用戶晓褪。在未使用路由器的情況下高职,只需要把這根入戶網(wǎng)線連接到電腦上,并且手動設置電腦上的IP地址辞州,這樣電腦才能上網(wǎng)怔锌。靜態(tài)IP地址不會改變,并且主要用于互聯(lián)網(wǎng)上的網(wǎng)站應用或服務变过。一些游戲者和使用VOIP的人往往也傾向于選擇靜態(tài)IP地址埃元,因為溝通更容易。
動態(tài)IP地址和靜態(tài)IP地址相比媚狰。
- 其一:為了節(jié)省lP資源岛杀,通過電話撥號、ADSL虛擬撥號等方式上網(wǎng)的機器是不分配固定IP地址的崭孤。而是由ISP動態(tài)臨時分配类嗤,提高lP地址利用率;
- 其二:在局域網(wǎng)中為了客戶機設置簡便辨宠,也常采用動態(tài)分配IP地址遗锣,這意味著您每次連接互聯(lián)網(wǎng)時得到的lP地址是不同的。盡管這不影響您訪問互聯(lián)網(wǎng)嗤形,但是您的朋友精偿、用戶卻不能訪問到您。因為赋兵,他們不知道您的計算機在哪里笔咽。這就像每個人都有一部電話,但您的電話號碼天天都在改變霹期。
三叶组、LAN8720A簡介
LAN8720A 是 SMSC 公司(已被 Microchip 公司收購)設計的一個體積小、功耗低历造、全能型 10/100Mbps 的以太網(wǎng)物理層(PHY)收發(fā)器甩十。LAN8720A 總共只有 24Pin,
僅支持 RMII 接口
帕膜。由它組成的網(wǎng)絡結構見下圖
LAN8720A 通過 RMII 與 MAC 連接枣氧。RJ45 是網(wǎng)絡插座溢十,在與 LAN8720A 連接之間還需要一個變壓器垮刹,所以一般使用帶電壓轉換和 LED 指示燈的 HY911105A 型號的插座。一般來說张弛,必須為使用 RMII 接口的 PHY 提供 50MHz 的時鐘源輸入到 REF_CLK 引腳
荒典,不過LAN8720A 內(nèi)部集成 PLL酪劫,可以將 25MHz 的時鐘源陪頻到 50MHz 并在指定引腳輸出該時鐘,所以我們可以直接使其與 REF_CLK 連接達到提供 50MHz 時鐘的效果
寺董。
PHY 芯片地址設置
LAN8720A 可以通過 PHYAD0 引腳來配置覆糟,該引腳與 RXER 引腳復用,芯片內(nèi)部自帶下拉電阻遮咖,當硬復位結束后滩字, LAN8720A 會讀取該引腳電平,作為器件的 SMI 地址御吞,接下拉電阻時(浮空也可以麦箍,因為芯片內(nèi)部自帶了下拉電阻),設置 SMI 地址為 0陶珠,當外接上拉電阻后挟裂,可以設置為 1。-
nINT/REFCLKO 引腳功能配置
nINT/REFCLKO 引腳用于 RMII 接口中 REF_CLK 信號線-
當 nINTSEL 引腳為低電平時
揍诽,它也可以被設置成 50MHz 時鐘輸出诀蓉,這樣可以直接與 STM32F4xx 的 REF_CLK 引腳連接為其提供 50MHz 時鐘源,這種模式要求為 XTAL1 與 XTAL2 之間或為 XTAL1/CLKIN 提供 25MHz 時鐘
暑脆,由 LAN8720A 內(nèi)部 PLL 電路陪頻得到 50MHz 時鐘渠啤,此時 nIN/REFCLKO 引腳的中斷功能不可用,用于 50MHz 時鐘輸出添吗。 -
當 nINTSEL 引腳為高電平時
埃篓,LAN8720A 被設置為時鐘輸入,即外部時鐘源直接提供 50MHz 時鐘
接入 STM32F4xx 的 REF_CLK 引腳和 LAN8720A 的 XTAL1/CLKIN 引腳根资,此時 nINT/REFCLKO 可用于中斷功能
架专。
nINTSEL 與 LED2 引腳共用,一般使用下拉玄帕,LAN8720A 外接 25MHz 石英晶振部脚,通過內(nèi)部陪頻到 50MHz,然后通過 REFCLKO 引腳裤纹,輸出 50MHz 參考時鐘給 MAC 控制器委刘。這種方式,可以降低 BOM 成本鹰椒。
-
如果不外接晶振锡移,需要通過板子的MCO1或者MCO2通過分頻倍頻操作來輸出50Mhz來驅動網(wǎng)口。
-
四漆际、引腳分布
ETH 相關硬件在 STM32F4xx 控制器分布情況如下:
接口 | ETH | GPIO |
---|---|---|
MII | MII_TX_CLK | PC3 |
MII_TXD0 | PB12/PG13 | |
MII_TXD1 | PB13/PG14 | |
MII_TXD2 | PC2 | |
MII_TXD3 | PB8/PE2 | |
MII_TX_EN | PB11/PG11 | |
MII_RX_CLK | PA1 | |
MII_RXD0 | PC4 | |
MII_RXD1 | PC5 | |
MII_RXD2 | PB0 | |
MII_RXD3 | PB1 | |
MII_RX_ER | PB10 | |
MII_RX_DV | PA7 | |
MII_CRS | PA0 | |
MII_COL | PA3 | |
RMII | RMII_TXD0 | PB12/PG13 |
RMII_TXD1 | PB13/PG14 | |
RMII_TX_EN | PG11 | |
RMII_RXD0 | PC4 | |
RMII_RXD1 | PC5 | |
RMII_CRS_DV | PA7 | |
RMII_REF_CLK | PA1 | |
SMI | MDIO | PA1 |
MDC | PC1 | |
其他 | PPS_OUT | PB5/PG8 |
五淆珊、新建工程
1. 打開 STM32CubeMX 軟件,點擊“新建工程”
2. 選擇 MCU 和封裝
3. 配置時鐘
RCC 設置奸汇,選擇 HSE(外部高速時鐘) 為 Crystal/Ceramic Resonator(晶振/陶瓷諧振器)
選擇 Clock Configuration施符,配置系統(tǒng)時鐘 SYSCLK 為 168MHz
修改 HCLK 的值為 168 后往声,輸入回車,軟件會自動修改所有配置
4. 配置調(diào)試模式
非常重要的一步戳吝,否則會造成第一次燒錄程序后續(xù)無法識別調(diào)試器
SYS 設置浩销,選擇 Debug 為 Serial Wire
六、ETH
6.1 參數(shù)配置
在 Connectivity
中選擇 ETH
設置听哭,模式選擇 RMII
使用簡化版MII(介質(zhì)獨立接口)慢洋。
-
MII: Medium Independent Interface(介質(zhì)獨立接口),用于連接介質(zhì)訪問控制層(MAC)子層和物理層(PHY)之間的標準以太網(wǎng)接口陆盘,提供數(shù)據(jù)傳輸路徑且警。由于 MII
需要多達16根信號線
,由此產(chǎn)生的 I/O 口需求及功耗較大礁遣。對于 MII 接口斑芜,一般是外部為 PHY 提供 25MHz 時鐘源
,再由 PHY 提供 TX_CLK 和 RX_CLK 時鐘祟霍,不需要與 MAC 層時鐘一致杏头。
-
RMII: Reduced Medium Independent Interface,RMII 接口是 MII 接口的簡化版本沸呐,MII 需要 16 根通信線醇王,RMII
只需 7 根通信
,在功能上是相同的崭添。對于 RMII 接口寓娩,一般需要外部直接提供 50MHz 時鐘源
,同時接入 MAC 和 PHY呼渣。需與MAC層時鐘一致棘伴,通常從 MAC 層獲取該時鐘源。現(xiàn)在一般都用RMII模式屁置。
在 Parameter Settings
進行具體參數(shù)配置焊夸。
Advanced : Ethernet Media Configuration(以太網(wǎng)媒體配置):
-
Auto Negotiation(自適應功能): 選擇
Enabled
,一般選擇使能自適應功能蓝角,系統(tǒng)會自動尋找最優(yōu)工作方式阱穗,包括選擇 10MBit/s 或者 100MBit/s 的以太網(wǎng)速度以及全雙工模式或半雙工模式。LAN8720A支持自適應功能
-
Speed(以太網(wǎng)速度): 可選 10MBit/s 或 100MBit/s使鹅,它設定 ETH_MACCR 寄存器的 FES 位的值揪阶,
一般設置 100MBit/s,但在使能自適應功能之后該位設置無效
患朱。 -
Duplex Mode(以太網(wǎng)工作模式): 可選全雙工模式或半雙工模式鲁僚,它設定 ETH_MACCR 寄存器 DM 位的值。
一般選擇全雙工模式,在使能了自適應功能后該成員設置無效
蕴茴。
General : Ethernet Configuration(以太網(wǎng)配置):
- Ethernet MAC Address(以太網(wǎng)MAC地址): 默認即可
-
PHY Address(PHY芯片地址):
0
注意:LAN8720A 可以通過 PHYAD0 引腳(如PHY芯片引腳10)來配置劝评,該引腳與 RXER 引腳復用姐直,芯片內(nèi)部自帶下拉電阻倦淀,當硬復位結束后, LAN8720A 會讀取該引腳電平声畏,作為器件的 SMI 地址撞叽,接下拉電阻時(浮空也可以,因為芯片內(nèi)部自帶了下拉電阻)插龄,設置 SMI 地址為 0愿棋,當外接上拉電阻后,可以設置為 1均牢。
本硬件 RXER 引腳浮空糠雨,其 PHY 芯片地址為 0
。
Ethernet Basic Configuration(以太網(wǎng)基本配置):
-
Rx Mode(接收模式): 選擇
Polling Mode
輪詢方法徘跪。ST 官方例程文件包含了中斷引腳的相關配置甘邀,主要用于指示接收到以太網(wǎng)幀,我們這里不需要使用垮庐。 -
TX IP Header Checksum Computation(發(fā)送數(shù)據(jù)校驗和): 選擇
By hardware
使能發(fā)送數(shù)據(jù)硬件校驗和松邪。這個需要硬件支持,STM32F4xx 控制器是支持的
哨查。
在 Advanced Parameters
進行高級參數(shù)配置逗抑。
-
PHY: 選擇
user PHY
,因為沒有我的 PHY 芯片型號 LAN8720A - PHY name: 可改為 PHY 芯片型號 LAN8720A
-
PHY special control/status register Offset(特殊控制/狀態(tài)寄存器): 按照芯片手冊填寫寒亥,
0x1F
-
PHY Speed mask(以太網(wǎng)速度狀態(tài)位): 按照芯片手冊填寫邮府,
0x0004
-
PHY Speed mask(以太網(wǎng)工作模式狀態(tài)位): 按照芯片手冊填寫,
0x0010
- 其他保持默認
6.2 引腳配置
GPIO 設置溉奕,在右邊圖中找到 ETH 對應引腳挟纱,將引腳配置成跟原理圖上的一致
七、LwIP
7.1 參數(shù)配置
在 Middleware
中選擇 LWIP
設置腐宋,勾選 Enabled
使能協(xié)議棧紊服。
在 General Settings
進行通用參數(shù)配置。
IPv4 - DHCP Options:
-
LWIP_DHCP(DHCP Module): 選擇
Disabled
胸竞。使用固定IP地址欺嗤。
IP Address Settings:
- IP_ADDRESS(IP Address): 填寫IP地址。
- NETMASK_ADDRESS(Netmask Address): 填寫掩碼地址卫枝。
- GATEWAY_ADDRESS(Gateway Address): 填寫網(wǎng)關地址煎饼。
Protocols Options:
-
LWIP_ICMP(ICMP Module Activation)控制報文協(xié)議: 選擇
Enabled
。主要用于網(wǎng)絡的調(diào)試與維護校赤,ping 的時候用吆玖。 -
LWIP_IGMP(IGMP Module)互聯(lián)網(wǎng)組管理協(xié)議: 選擇
Disabled
筒溃。可以實現(xiàn)多播數(shù)據(jù)的接收沾乘。 -
LWIP_DNS(DNS Module)域名解析: 選擇
Disabled
怜奖。通過域名解析用戶就可以在知道服務器域名的情況下,獲得該服務器的 IP 地址翅阵。 -
LWIP_UDP(UDP Module)用戶數(shù)據(jù)報協(xié)議: 選擇
Enabled
歪玲。看需求掷匠,一般選擇用 TCP 協(xié)議滥崩。 - MEMP_NUM_UDP_PCB(Number of UDP Connections): UDP協(xié)議控制塊數(shù)量,決定 UDP 協(xié)議控制塊需要的 POOL 資源讹语。
-
LWIP_TCP(TCP Module)傳輸控制協(xié)議: 選擇
Enabled
钙皮。 - MEMP_NUM_TCP_PCB(Number of TDP Connections): 同時活動的TCP連接數(shù)。
在 Key Options
進行關鍵選項配置顽决。
Infrastructure - OS Awarness Option:
-
NO_SYS(OS Awarness):
OS Not Used
表示無操作系統(tǒng)模擬層短条,這個宏非常重要,因為無操作系統(tǒng)與有操作系統(tǒng)的移植和編寫是完全不一樣的擎值,我們現(xiàn)在是無操作系統(tǒng)移植慌烧。
Infrastructure - Timers Options:
-
LWIP_TIMERS(Use Support For sys_timeout): 默認
Enabled
。使用 LwIP 提供的定時器鸠儿,用于超時機制屹蚊。
Infrastructure - Core Locking and MPU Options:
-
SYS_LIGHTWEIGHT_PROT(Memory Functions Protection): 默認
Disabled
。平臺鎖进每,保護關鍵區(qū)域內(nèi)緩存的分配與釋放汹粤。
Infrastructure - Heap and Memory Pools Options:
-
MEM_SIZE(Heap Memory Size): 默認
1600 Byte(s)
。堆內(nèi)存的大小田晚。如果應用程序將發(fā)送很多需要復制的數(shù)據(jù)應該設置得大一點嘱兼。
Infrastructure - Internal Memory Pool Sizes:
-
MEMP_NUM_PBUF(Number of Memory Pool struct Pbufs): 默認
16
。memp 結構的 pbuf 數(shù)量贤徒,如果應用從 ROM 或者靜態(tài)存儲區(qū)發(fā)送大量數(shù)據(jù)時芹壕,這個值應該設置大一點。 -
MEMP_NUM_RAW_PCB(Number of Raw Protocol Control Blocks): 默認
4
接奈。 原始連接(就是應用程不經(jīng)過傳輸層直接到IP層獲取數(shù)據(jù))PCB 的數(shù)目踢涌,該項依賴 LWIP_RAW 項的開啟。 -
MEMP_NUM_TCP_PCB(Number of Listening TCP Connections): 默認
8
序宦。 同時建立激活的 TCP 連接的數(shù)目(要求參數(shù) LWIP_TCP 使能)睁壁。 -
MEMP_NUM_TCP_SEG(Number of TCP Segments simultaneously queued): 默認
16
。 最多同時在隊列的 TCP_SEG 的數(shù)目。
Pbuf Options:
-
PBUF_POOL_SIZE(Number of Buffers in the Pbuf Pool): 默認
16
潘明。 內(nèi)存池大小行剂。 -
PBUF_POOL_BUFSIZE(Size of each pbuf in the pbuf pool): 默認
592 Byte(s)
。 每個 pbuf 內(nèi)存池大小钳降。
IPv4 - ARP Options:
-
LWIP_ARP(ARP Functionality): 選擇
Enabled
厚宰。 地址解析協(xié)議,通過目標設備的 IP 地址牲阁,查詢目標設備的 MAC 地址固阁,以保證通信的
順利進行壤躲。
Callback - TCP Options:
-
TCP_TTL(Number of Time-To-Live Used by TCP Packets): 默認
255 Node(s)
城菊。TCP TTL時間。 -
TCP_WND(TCP Receive Window Maximum Size): 默認
2144 Byte(s)
碉克。TCP 窗口長度凌唬。 -
TCP_QUEUE_OOSEQ(Allow Out-Of-Order Incoming Packets): 默認
Enabled
。TCP隊列到達順序漏麦。如果設備內(nèi)存不足客税,則定義為0。 -
TCP_MSS(Maximum Segment Size): 默認
536 Byte(s)
撕贞。最大 TCP 報文段更耻,TCP_MSS = MTU - IP 報頭大小 - TCP 報頭大小。 -
TCP_SND_BUF(TCP Sender Buffer Space): 默認
1072 Byte(s)
捏膨。TCP 發(fā)送緩沖區(qū)大醒砭(字節(jié))。 -
TCP_SND_QUEUELEN(TCP Sender Buffer Space): 默認
1072 Byte(s)
号涯。TCP 發(fā)送緩沖區(qū)隊列的最大長度目胡。
Network Interfaces Options:
-
LWIP_NETIF_STATUS_CALLBACK(Callback Function on Interface Status Changes): 默認
Disabled
。當 netif 狀態(tài)設置為 up 或 down 時調(diào)用此函數(shù)链快。 -
LWIP_NETIF_LINK_CALLBACK(Callback Function on Interface Link Changes): 默認
Enabled
誉己。當 netif 鏈接設置為 up 或 down 時,將調(diào)用此函數(shù)域蜗。
NETIF - Loopback Interface Options:
-
LWIP_NETIF_LOOPBACK(NETIF Loopback): 默認
Disabled
巨双。支持發(fā)送數(shù)據(jù)包的目的地 IP。
Thread Safe APIs - Socket Options:
-
LWIP_SOCKET(Socket API): 默認
Disabled
霉祸。Socket API筑累。
八、生成代碼
輸入項目名和項目路徑
選擇應用的 IDE 開發(fā)環(huán)境 MDK-ARM V5
每個外設生成獨立的
’.c/.h’
文件不勾:所有初始化代碼都生成在 main.c
勾選:初始化代碼生成在對應的外設文件脉执。 如 GPIO 初始化代碼生成在 gpio.c 中疼阔。
點擊 GENERATE CODE 生成代碼
九、修改main.c
在 main()
的死循環(huán)中添加 MX_LWIP_Process()
函數(shù)。
然后加入以下代碼不斷打印 IP 地址婆廊。
extern struct netif gnetif;
struct dhcp *dhcp;
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_LWIP_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
printf("lwip test\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
MX_LWIP_Process();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
dhcp = netif_dhcp_data(&gnetif);
printf("Static IP address: %s\n", ip4addr_ntoa(&gnetif.ip_addr));
printf("Subnet mask: %s\n", ip4addr_ntoa(&gnetif.netmask));
printf("Default gateway: %s\n", ip4addr_ntoa(&gnetif.gw));
HAL_Delay(1000);
}
/* USER CODE END 3 */
}
查看效果:
使用電腦ping上面的ip:
十迅细、工程代碼
鏈接:https://pan.baidu.com/s/1ds3cqlt1JpjeaSF5-Tpurg?pwd=e4gv 提取碼:e4gv
十一、相關API說明
11.1 MX_LWIP_Init
初始化LwIP的內(nèi)存管理和各個協(xié)議層淘邻。
按順序執(zhí)行了:
- 網(wǎng)絡接口的添加
netif_add()
- 初始化底層
ethernetif_init()
然后LwIP就可以用了茵典。
收包用的是調(diào)用 low_level_input
把數(shù)據(jù)包接回來,給 netif->input
處理宾舅。
發(fā)包則是由 netif->output
交由 etharp_output
制作數(shù)據(jù)包统阿,調(diào)用 low_level_output
發(fā)出去。
void MX_LWIP_Init(void)
{
/* IP addresses initialization */
IP_ADDRESS[0] = 192;
IP_ADDRESS[1] = 168;
IP_ADDRESS[2] = 11;
IP_ADDRESS[3] = 196;
NETMASK_ADDRESS[0] = 255;
NETMASK_ADDRESS[1] = 255;
NETMASK_ADDRESS[2] = 255;
NETMASK_ADDRESS[3] = 0;
GATEWAY_ADDRESS[0] = 192;
GATEWAY_ADDRESS[1] = 168;
GATEWAY_ADDRESS[2] = 10;
GATEWAY_ADDRESS[3] = 1;
/* USER CODE BEGIN IP_ADDRESSES */
/* USER CODE END IP_ADDRESSES */
/* Initilialize the LwIP stack without RTOS */
lwip_init();
/* IP addresses initialization without DHCP (IPv4) */
IP4_ADDR(&ipaddr, IP_ADDRESS[0], IP_ADDRESS[1], IP_ADDRESS[2], IP_ADDRESS[3]);
IP4_ADDR(&netmask, NETMASK_ADDRESS[0], NETMASK_ADDRESS[1] , NETMASK_ADDRESS[2], NETMASK_ADDRESS[3]);
IP4_ADDR(&gw, GATEWAY_ADDRESS[0], GATEWAY_ADDRESS[1], GATEWAY_ADDRESS[2], GATEWAY_ADDRESS[3]);
/* add the network interface (IPv4/IPv6) without RTOS */
// 如果有多個接口則需多次調(diào)用
// 需要提供一個init函數(shù)指針,這個指針指向我們自己的硬件接口初始化函數(shù)膘侮,一般來說就是ethernetif.c中的ethernetif_init()
netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input);
/* Registers the default network interface */
// 將網(wǎng)絡接口設置為默認的網(wǎng)絡接口
netif_set_default(&gnetif);
// 查看是否有鏈接
if (netif_is_link_up(&gnetif))
{
/* When the netif is fully configured this function must be called */
// 使能網(wǎng)絡接口
netif_set_up(&gnetif);
}
else
{
/* When the netif link is down this function must be called */
// 關閉網(wǎng)絡接口
netif_set_down(&gnetif);
}
/* Set the link callback function, this function is called on change of link status*/
netif_set_link_callback(&gnetif, ethernetif_update_config);
/* Create the Ethernet link handler thread */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to netif_add().
*
* @param netif the lwip network interface structure for this ethernetif
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init(struct netif *netif)
{
LWIP_ASSERT("netif != NULL", (netif != NULL));
#if LWIP_NETIF_HOSTNAME
/* Initialize interface hostname */
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
// 初始化name字段
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
#if LWIP_IPV4
#if LWIP_ARP || LWIP_ETHERNET
#if LWIP_ARP
netif->output = etharp_output;
#else
/* The user should write its own code in low_level_output_arp_off function */
netif->output = low_level_output_arp_off;
#endif /* LWIP_ARP */
#endif /* LWIP_ARP || LWIP_ETHERNET */
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = low_level_output;
/* initialize the hardware */
low_level_init(netif);
return ERR_OK;
}
11.2 MX_LWIP_Process
不斷地接收來自接口的信息愉耙,并檢查是否延時
/**
* ----------------------------------------------------------------------
* Function given to help user to continue LwIP Initialization
* Up to user to complete or change this function ...
* Up to user to call this function in main.c in while (1) of main(void)
*-----------------------------------------------------------------------
* Read a received packet from the Ethernet buffers
* Send it to the lwIP stack for handling
* Handle timeouts if LWIP_TIMERS is set and without RTOS
* Handle the llink status if LWIP_NETIF_LINK_CALLBACK is set and without RTOS
*/
void MX_LWIP_Process(void)
{
/* USER CODE BEGIN 4_1 */
/* USER CODE END 4_1 */
ethernetif_input(&gnetif);
/* USER CODE BEGIN 4_2 */
/* USER CODE END 4_2 */
/* Handle timeouts */
sys_check_timeouts();
/* USER CODE BEGIN 4_3 */
/* USER CODE END 4_3 */
}
十二、注意事項
用戶代碼要加在 USER CODE BEGIN N
和 USER CODE END N
之間结澄,否則下次使用 STM32CubeMX 重新生成代碼后,會被刪除岸夯。
? 由 Leung 寫于 2022 年 8 月 25 日
? 參考:從零開始Cubemx配置STM32搭載freeRTOS以及l(fā)wip實現(xiàn)tcp網(wǎng)絡通信(二)
STM32cubeMX配置LWIP+FREERTOS
LwIP的配置