《極海芯得》系列內(nèi)容為用戶使用極海系列產(chǎn)品的經(jīng)驗(yàn)總結(jié),均轉(zhuǎn)載自21ic論壇極海半導(dǎo)體專區(qū),全文未作任何修改,未經(jīng)原文作者授權(quán)禁止轉(zhuǎn)載。
下面是基于RT-Thread的ENV命令行開發(fā)環(huán)境,在APM32F427上使用LwIP網(wǎng)絡(luò)協(xié)議棧實(shí)現(xiàn)網(wǎng)絡(luò)通信功能的。
1. 工具和RT-Thread源碼的準(zhǔn)備
1.1 ENV工具的安裝和使用
這里只做基本的介紹,詳細(xì)的使用方法請(qǐng)點(diǎn)擊下面鏈接看RTT的官方文檔中心中對(duì)ENV工具的介紹。
https://www.rt-thread.org/document/site/#/development-tools/env/env
Env 是 RT-Thread 推出的開發(fā)輔助工具,針對(duì)基于 RT-Thread 操作系統(tǒng)的項(xiàng)目工程,提供編譯構(gòu)建環(huán)境、圖形化系統(tǒng)配置及軟件包管理功能。
其內(nèi)置的 menuconfig 提供了簡(jiǎn)單易用的配置剪裁工具,可對(duì)內(nèi)核、組件和軟件包進(jìn)行自由裁剪,使系統(tǒng)以搭積木的方式進(jìn)行構(gòu)建。
ENV工具可以從下面的RTT官方網(wǎng)站下載。
https://www.rt-thread.org/download.html#download-rt-thread-env-tool
1.2 下載RTT源碼
到下面官網(wǎng)下載:
https://www.rt-thread.org/download.html#download-rt-thread-source-code

然后點(diǎn)擊碼云下載。

點(diǎn)擊下載ZIP就行。
當(dāng)然,如果有g(shù)it bash的話,可以使用 git clone 命令進(jìn)行遠(yuǎn)程源碼拉取到本地電腦中。
注意:請(qǐng)下載最新版本的RTT源碼包,太老版本的話可能還沒有APM32的BSP包。
2. 進(jìn)入到APM32F407的bsp根目錄下編譯bsp
進(jìn)入apm32f4的bsp根目錄下:

然后右鍵在該目錄下打開ENV工具(如果沒有把ENV添加到右鍵菜單的話,自己看RTT文檔進(jìn)行操作,或者自行切換ENV路徑到該目錄下)。

打開ENV工具之后,在該目錄下輸入 scons 命令即可編譯該BSP。

最終編譯成功如下:

如果使用 mdk/iar 來(lái)進(jìn)行項(xiàng)目開發(fā),可以直接使用 BSP 中的工程文件或者使用以下命令中的其中一種,重新生成工程,再進(jìn)行編譯下載。
scons --target=iar
scons --target=mdk4
scons --target=mdk5
3. 復(fù)制APM32F407的BSP修改為APM32F427的BSP
由于官方可能還沒有添加APM32F427的BSP目錄,但是沒關(guān)系,由于APM32F407與APM32F427很像。我們基于APM32F407修改為F427即可。
主要就是修改407的時(shí)鐘配置函數(shù)。打開工程中的drv_clk.c文件,修改 clk_init 函數(shù)對(duì)于時(shí)鐘的初始化函數(shù)。
修改代碼如下:
void SystemInit(void)
{
/* FPU settings */
#if(__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); ?//!< set CP10 and CP11 Full Access
#endif
/* Reset the RCM clock configuration to the default reset state */
/* Set HSIEN bit */
RCM->CTRL_B.HSIEN = BIT_SET;
/* Reset CFG register */
RCM->CFG = 0x00000000;
/* Reset HSEEN, CSSEN and PLL1EN bits */
RCM->CTRL &= (uint32_t)0xFEF6FFFF;
/* Reset PLL1CFG register */
RCM->PLL1CFG = 0x24003010;
/* Reset HSEBCFG bit */
RCM->CTRL &= (uint32_t)0xFFFBFFFF;
/* Disable all interrupts */
RCM->INT = 0x00000000;
#ifdefined(DATA_IN_ExtSRAM)
SystemInit_ExtSRAM();
#endif/* DATA_IN_ExtSRAM */
SystemClockConfig();
/* Configure the Vector Table location add offset address */
#ifdefVECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}
4. 使能 LwIP 與 net dev
4.1 首先使能以太網(wǎng)板級(jí)外設(shè)驅(qū)動(dòng)
在ENV工具中輸入 menuconfig 命令:

本來(lái)在這個(gè)配置項(xiàng)下應(yīng)該有板級(jí)外設(shè)驅(qū)動(dòng)選項(xiàng)配置的,但是沒有看到,很明顯是該bsp包還沒支持這個(gè)功能。那么后面只能自己把以太網(wǎng)板級(jí)外設(shè)驅(qū)動(dòng)文件(drv_eth.c)添加到keil工程里面了。當(dāng)然,就算支持該功能,如果沒有drv_eth.c這個(gè)文件的支持那也沒用。
4.2 啟用 lwIP 與 net device

然后再使能LwIP網(wǎng)絡(luò)協(xié)議棧。其中,在該配置項(xiàng)下面我們把DHCP功能關(guān)閉了,使用靜態(tài)IP地址。然后我們?cè)偈鼓?netif loopback 功能,該功能就是可以自己ping通自己的。

配置完成后,我們保存退出。
最后輸入命令:scons --target=mdk5 把剛剛的配置同步到 MDK5 工程。
5. 編寫基于RTT的以太網(wǎng)板級(jí)驅(qū)動(dòng)drv_eth.c
當(dāng)我們添加了LwIP網(wǎng)絡(luò)協(xié)議棧之后,就可以編譯代碼后可以下載到開發(fā)板運(yùn)行。如下,我們下載代碼到開發(fā)板后,在串口終端運(yùn)行 ifconfig 命令查看網(wǎng)絡(luò)狀態(tài),可以看到有錯(cuò)誤:

這是因?yàn)橐蕴W(wǎng)的驅(qū)動(dòng)文件還沒添加進(jìn)去編譯的原因。
5.1 添加編寫好的drv_eth.c文件
因?yàn)閍pm32的BSP包里面并沒有RTT的以太網(wǎng)板級(jí)驅(qū)動(dòng)文件drv_eth.c,所以需要我們自己編寫這個(gè)文件。這個(gè)文件我已經(jīng)編寫好了,然后我們自己把這個(gè)文件復(fù)制到apm32的bsp包里面,而且手動(dòng)添加到MDK5的工程中即可:
? 
5.2 打開ETH板級(jí)外設(shè)驅(qū)動(dòng),和選擇PHY芯片型號(hào)
因?yàn)?drv_eth.c 文件使用了宏 BSP_USING_ETH 默認(rèn)關(guān)閉了這個(gè)外設(shè)驅(qū)動(dòng)的,需要定義這個(gè)宏才能打開這個(gè)外設(shè)驅(qū)動(dòng),另外開發(fā)板使用的PHY芯片的宏也需要定義,目前支持的芯片類型有,LAN8720、DP83848以及DM9161。
我們就在 drv_eth.c 文件(或者rtconfig.h文件也行)的最前面定義下面兩個(gè)宏:
#defineBSP_USING_ETH
#definePHY_USING_DP83848C // 根據(jù)自己使用的phy芯片型號(hào)定義
5.3 添加標(biāo)準(zhǔn)外設(shè)驅(qū)動(dòng)文件apm32f4xx_eth.c和apm32f4xx_eth.h
添加了上面那兩個(gè)宏之后,編譯一大堆報(bào)錯(cuò),這是因?yàn)镸DK還沒有添加eth的標(biāo)準(zhǔn)庫(kù)外設(shè)驅(qū)動(dòng)文件apm32f4xx_eth.c和apm32f4xx_eth.h。

我發(fā)現(xiàn)RTT的源碼里面,apm32的bsp包竟然沒有apm32f4xx_eth.c和apm32f4xx_eth.h這兩個(gè)文件,那沒辦法了,只好到apm32的官網(wǎng)下載f4的SDK包,然后再把這兩個(gè)文件復(fù)制到bsp包的庫(kù)目錄下面。然后再手動(dòng)添加到MDK工程里面。
5.4 添加包含apm32f4xx_eth.h頭文件代碼
添加了標(biāo)準(zhǔn)外設(shè)驅(qū)動(dòng)文件apm32f4xx_eth.c到MDK工程之后,這時(shí)編譯,還是報(bào)上面步驟一樣的錯(cuò)誤,這是因?yàn)闆]有包含 apm32f4xx_eth.h 頭文件,我們?cè)?board.h 文件中寫上包含該頭文件。另外,因?yàn)楹竺娴拇a有用到apm32f4xx_syscfg.h這個(gè)頭文件,所以這里一起寫上,如下圖:

5.5 添加 phy_reset 和 ETH_GPIO_Configuration 函數(shù)
繼續(xù)編譯,會(huì)發(fā)現(xiàn)還有兩個(gè)鏈接報(bào)錯(cuò),說(shuō)沒有定義 phy_reset 和 ETH_GPIO_Configuration 函數(shù),這兩個(gè)函數(shù)一個(gè)是phy芯片硬件復(fù)位引腳進(jìn)行復(fù)位的,另外一個(gè)函數(shù)是eth外設(shè)GPIO口的初始化。

這兩個(gè)函數(shù)是在 drv_eth.c 文件中要用到的,因?yàn)檫@兩個(gè)函數(shù)和板級(jí)硬件的關(guān)聯(lián)太大,并不能確定用戶使用的是什么GPIO口,所以獨(dú)立出來(lái)由用戶自己添加。
我目前使用的事RMII接口和PD11作為復(fù)位引腳,我們?cè)?board.c 文件中添加下面的代碼。
phy_reset 函數(shù):
/*
* phy reset
*/
void phy_reset(void)
{
/* PHY RESET PIN: PD11 */
GPIO_Config_T GPIO_ConfigStruct;
GPIO_ConfigStruct.mode = GPIO_MODE_OUT;
GPIO_ConfigStruct.speed = GPIO_SPEED_2MHz;
GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
GPIO_ConfigStruct.pupd = GPIO_PUPD_NOPULL;
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOD);
GPIO_ConfigStruct.pin = GPIO_PIN_11;
GPIO_Config(GPIOD, &GPIO_ConfigStruct);
GPIO_ResetBit(GPIOD, GPIO_PIN_11);
rt_thread_delay(2);
GPIO_SetBit(GPIOD, GPIO_PIN_11);
rt_thread_delay(2);
}
ETH_GPIO_Configuration 函數(shù):
/* MII/RMII Media interface selection */
//#defineMII_MODE
#defineRMII_MODE
/*
* GPIO Configuration for ETH
*/
void ETH_GPIO_Configuration(void)
{
GPIO_Config_T GPIO_ConfigStruct;
/* Enable SYSCFG clock */
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
/* Enable GPIOs clocks */
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOA | RCM_AHB1_PERIPH_GPIOC | RCM_AHB1_PERIPH_GPIOG);
/* MII/RMII Media interface selection */
#ifdefined(MII_MODE) /* Mode MII. */
SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_MII);
#elifdefined(RMII_MODE) /* Mode RMII. */
SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_RMII);
#endif
/*********************** Ethernet pins configuration ***************************/
/*
ETH_MDIO -------------------------> PA2
ETH_MDC --------------------------> PC1
ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PA7
ETH_MII_RXD0/ETH_RMII_RXD0 -------> PC4
ETH_MII_RXD1/ETH_RMII_RXD1 -------> PC5
ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PG11
ETH_MII_TXD0/ETH_RMII_TXD0 -------> PG13
ETH_MII_TXD1/ETH_RMII_TXD1 -------> PG14
**** Just for MII Mode ****
ETH_MII_CRS ----------------------> PA0
ETH_MII_COL ----------------------> PA3
ETH_MII_TX_CLK -------------------> PC3
ETH_MII_RX_ER --------------------> PB10
ETH_MII_RXD2 ---------------------> PB0
ETH_MII_RXD3 ---------------------> PB1
ETH_MII_TXD2 ---------------------> PC2
ETH_MII_TXD3 ---------------------> PB8
*/
/* Configure PC1, PC4 and PC5 */
GPIO_ConfigStruct.pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
GPIO_ConfigStruct.speed = GPIO_SPEED_100MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_AF;
GPIO_ConfigStruct.otype = GPIO_OTYPE_PP;
GPIO_ConfigStruct.pupd = GPIO_PUPD_NOPULL;
GPIO_Config(GPIOC, &GPIO_ConfigStruct);
GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_4, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_5, GPIO_AF_ETH);
/* Configure PG11, PG13 and PG14 */
GPIO_ConfigStruct.pin = GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14;
GPIO_Config(GPIOG, &GPIO_ConfigStruct);
GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_11, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_13, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOG, GPIO_PIN_SOURCE_14, GPIO_AF_ETH);
/* Configure PA1, PA2 and PA7 */
GPIO_ConfigStruct.pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_2, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_7, GPIO_AF_ETH);
#ifdefMII_MODE
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
/* Configure PC2, PC3 */
GPIO_ConfigStruct.pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_Config(GPIOC, &GPIO_ConfigStruct);
GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_2, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOC, GPIO_PIN_SOURCE_3, GPIO_AF_ETH);
/* Configure PB0, PB1, PB10 and PB8 */
GPIO_ConfigStruct.pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_10 | GPIO_PIN_8;
GPIO_Config(GPIOB, &GPIO_ConfigStruct);
GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_0, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_1, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_10, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_8, GPIO_AF_ETH);
/* Configure PA0, PA3 */
GPIO_ConfigStruct.pin = GPIO_PIN_0 | GPIO_PIN_3;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_0, GPIO_AF_ETH);
GPIO_ConfigPinAF(GPIOA, GPIO_PIN_SOURCE_3, GPIO_AF_ETH);
#endif
}
當(dāng)添加完上面的代碼之后,再次編譯就可以編譯通過(guò)了,沒有任何警告和錯(cuò)誤,如下:

到這里已經(jīng)完成了所有代碼的添加和移植了,LwIP網(wǎng)絡(luò)協(xié)議棧也可以正常運(yùn)行起來(lái)了。
6. 驗(yàn)證網(wǎng)絡(luò)功能是否正常
下載程序后運(yùn)行,然后再串口終端輸入 ifconfig 命令,可以看到網(wǎng)卡已經(jīng)正常工作了,而且使用的是靜態(tài)IP。

我們ping一下電腦主機(jī)IP(我的電腦主機(jī)IP是:1992.168.1.50),可以看到正常ping通,說(shuō)明網(wǎng)絡(luò)功能已經(jīng)正常了。

7. 使用RTT的tcp client和server例程
7.1 配置menuconfig
首先,需要在menuconfig開啟使用這兩個(gè)例程,配置如下:

7.2 更新軟件包
保存配置退出之后,我們要去下載在線軟件包,在ENV輸入 pkgs --update 命令即可,然后可以看到軟件包下載下來(lái)了。

最后,我們執(zhí)行命令,scons --target=mdk5 同步到 MDK5 工程里面。
注意:前面我們手動(dòng)添加了一些文件到 MDK 工程里面,如果我們這里執(zhí)行了 scons --target=mdk5 這個(gè)命令之后,其實(shí)會(huì)把我們之前添加的配置文件全部都移除掉的,這是使用 ENV 的一個(gè)不好的地方。
7.3 測(cè)試驗(yàn)證
然后,編譯下載程序到板子上運(yùn)行。
這兩個(gè)例程是以命令的形式放在串口終端下運(yùn)行的,我們?cè)诖诮K端下運(yùn)行 tcpserv 命令,使用開發(fā)板作為服務(wù)器,如下:

可以看到服務(wù)器端口端口是5000。
然后我們?cè)陔娔X端使用網(wǎng)絡(luò)調(diào)試工具作為客戶端,去連接開發(fā)板,如下:

以上,就是在ENV環(huán)境下,APM32F4在RT-Thread系統(tǒng)上使用LwIP網(wǎng)絡(luò)功能的詳細(xì)過(guò)程。
提示:關(guān)于文章的第五節(jié),其實(shí)已經(jīng)不需要我們自己添加APM32F427的drv_etc.c網(wǎng)絡(luò)驅(qū)動(dòng)文件了,因?yàn)楣俜揭呀?jīng)做好了。
注:文章作者在原帖中提供了詳細(xì)代碼,有需要請(qǐng)至原文21ic論壇
原文地址:https://bbs.21ic.com/icview-3501388-1-1.html?_dsign=c8a71825
-
網(wǎng)絡(luò)通信
+關(guān)注
關(guān)注
4文章
843瀏覽量
32629 -
開發(fā)環(huán)境
+關(guān)注
關(guān)注
1文章
274瀏覽量
17656 -
LwIP
+關(guān)注
關(guān)注
2文章
91瀏覽量
29684 -
RT-Thread
+關(guān)注
關(guān)注
32文章
1629瀏覽量
45070
原文標(biāo)題:極海芯得 EP.79 | APM32F427在RT-Thread系統(tǒng)上如何使用LwIP網(wǎng)絡(luò)功能實(shí)現(xiàn)網(wǎng)絡(luò)通信
文章出處:【微信號(hào):geehysemi,微信公眾號(hào):Geehy極海半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
RT-Thread最新推出Nano極簡(jiǎn)版
極海APM32F427如何實(shí)現(xiàn)自定義USB HID設(shè)備與PC進(jìn)行通信
SC0085 AT32在RT-Thread上運(yùn)行LwIP協(xié)議棧
在RT-Thread系統(tǒng)上移植eRPC并添加lwip的步驟
如何將RT-Thread系統(tǒng)移植到GD32F427上呢
【國(guó)產(chǎn)MCU系列】在 HK32F030 上移植 RT-Thread Nano
【國(guó)產(chǎn)MCU系列】在 HK32F030 上移植 RT-Thread Nano
RT-Thread全球技術(shù)大會(huì):在RT-Thread上編寫測(cè)試用例
RT-Thread已經(jīng)全面支持極海APM32F1系列MCU
APM32F030RCT6_軟件問題_RT-Thread在注冊(cè)設(shè)備時(shí),進(jìn)入硬件報(bào)錯(cuò)
機(jī)智云設(shè)備移植RT-Thread
RT-Thread移植使用webserver (lwip+httpd)
RT-Thread在Lan8720a和 lwip基礎(chǔ)上移植ntp流程
極海APM32F427系列MCU榮獲IEC 60730/60335功能安全認(rèn)證
極海APM32F427 MCU在RT-Thread系統(tǒng)上使用LwIP網(wǎng)絡(luò)功能
評(píng)論