1. 创建APM32F4的工程项目
1、首先点击新建RT-Thread项目
2. 编译下载生成的基本工程项目
点击完成之后,就可以在左边的资源管理器看到生成的项目文件了。生成项目文件之后,我们可以直接点击编译(就是那个锤子的图标),刚刚生成的工程项目文件,我们现在直接编译,一般是不会有任何警告和错误的。然后,编译完成之后,我们可以把程序下载到我们的板子上运行的。下载程序后,打开串口终端软件,可以看到RT-Thread打印的信息,如下:
3. 解决shell不能输入字符bug
这时,我们在串口终端发现,shell不能接收字符输入。这是一个bug,原因就是串口的GPIO配置有问题,我们把下面文件函数修改一下即可:

4. 使能网络接口设备和LwIP
双击打开配置文件 RT-Thread Settings , 然后找到组件这里,使能网络接口设备和LwIP堆栈。


5. 添加RTT的网络驱动文件(重点)
这个驱动文件如果bsp包里面有的话,应该是可以配置加入 RTT Studio 里面的吧,但是APM32并没有这个文件的支持,所以只能我们自己编写这个网络驱动文件了,可以参考下面RTT官方文档的介绍,看看需要我们提供什么样的接口函数。https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/application-note/components/network/an0010-lwip-driver-porting这里,我已经提前写好了这个文件,分别是 drv_eth.c 和 drv_eth.h 。我们把这两个文件复制到工程目录的drivers目录下。

6. 然后打开 BSP_USING_ETH 宏定义
我们在 board.h 文件中,打开 BSP_USING_ETH 这个宏定义,以及定义 phy 物理芯片的型号(根据自己板子的芯片类型选择),如下:

7. 添加缺少的文件到工程目录中
我们打开右边的文件资源管理器,找到libraries目录,查看芯片的标准外设驱动库,可以看到并没有 apm32f4xx_eth.c 文件,这应该是 RTT Studio 没有合并进去吧。这个需要我们去geehy的官网下载f4的SDK包,然后把网口外设的标准驱动文件复制到这个目录下(包括头文件)即可。然后再在drv_common.h文件中,添加下面两句语句(主要就是包含这两个两个所用到的头文件):
8. 添加 phy_reset 和 ETH_GPIO_Configuration 函数
上面全部重新编译,然后就只有3个报错了,如下:
/* * 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); }
/* MII/RMII Media interface selection */ //#define MII_MODE #define RMII_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 */ #if defined(MII_MODE) /* Mode MII. */ SYSCFG_ConfigMediaInterface(SYSCFG_INTERFACE_MII); #elif defined(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); #ifdef MII_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 }

9. 验证网络功能是否正常
下载程序后运行,然后再串口终端输入 ifconfig 命令,可以看到网卡已经正常工作了,而且使用的是静态IP。

10. 使用RTT的tcp client和server例程
RTT还有各种软件包,其中tcp client和server例程就属于软件包的一部分,我们可以使能这两个例程,这样就可以在shell命令行下面运行tcp客户端或者服务器例程了。1、先使能这两个软件包


11. 总结
以上就是APM32F4系列,在RT-Thread系统上应用LwIP网络功能的详细过程。其实其他APM32带有以太网控制器的MCU,在RT-Thread使用LwIP网络功能也是大同小异的,按照这个过程基本都可以把网络功能应用起来。