最近由于项目需要,要在APM32F107的MCU上使用网络的功能,而且计划在项目中使用RT-Thread系统。然后在RT-Thread源码仓库发现,极海的bsp包已经有了APM32F107开发板的bsp了,而且已经适配了网络功能。本文就分享一下,自己基于极海的APM32F107时,在RT-Thread系统上使用LwIP网络组件的过程。 1. 获取RT-Thread源码RT-Thread 源码可以到其 github 仓库下载。仓库地址是: https://github.com/RT-Thread/rt-thread 我们直接打开网页,然后点击下载 ZIP 源码压缩包。 或者使用git bash工具,克隆整个仓库。 在 github 上下载非常慢,而且有时还打不开网页。所以,也可以到国内的 gitee 网站下载RT-Thread的源码,链接如下: https://gitee.com/rtthread/rt-thread 不过 gitee 上的代码更新可能会慢于 github 上的代码,但基本上足够我们使用了。 2. 使能以太网外设和LwIP网络组件下载完源码之后,我们到源码根目录的bsp目录,然后找到apm32目录下的,关于apm32f107的bsp,如下图: 进入该目录,然后在该目录下打开ENV工具(ENV工具的使用和介绍可参考RT-Thread官方文档介绍:https://www.rt-thread.org/document/site/#/development-tools/env/env),输入menuconfig命令: 然后找到Hardware Drivers Config选项,进去把以太网外设打开: 使能了以太网外设之后,就会默认打开了RT-Thread组件的网络接口设备以及LwIP网络协议栈了,我们还需要自己配置一下LwIP有关的选项。比如是否使用DHCP动态分配IP地址,还是使用静态IP,比如裁剪下LwIP内存池的大小,使得占用内存减少。如下: 因为我身边没有路由器进行动态分配IP,所以这里我配置成静态IP。另外,还裁剪了LwIP对RAM的使用。 配置完成之后,保存退出。 然后在ENV工具中输入命令:scons --target=mdk5 -s 生成 mdk5 工程。 3. 以太网板级驱动的移植适配上面生成的MDK5工程,如果使用人家制作这个bsp的硬件板卡的话,代码是直接可以编译下载就能使用了的。 但是,每个人手上的硬件板卡,使用的物理层芯片不一样,硬件连接方式也可能不一样,所以需要做一点简单的配置工作。 3.1 确认phy复位引脚和MCU的连接我项目的硬件板卡,所使用的phy是很常见的LAN8720芯片,其中phy的复位引脚是没有和MCU的GPIO相连的,而是直接连接到了MCU上电的复位引脚上。所以不用修改该引脚的代码,phy引脚的复位函数直接写为空函数即可。 但是,有些硬件板卡,可能会把该引脚和MCU的GPIO连接,使用软件进行复位,我们需要根据自己的原理图确认phy的复位引脚连接到了哪个引脚。 然后,再编写该复位函数了。其实就是把该引脚先拉低,然后延时一下再拉高即可。相关代码如下: 3.2 phy与MCU连接方式和引脚初始化对于我自己的项目,phy和MCU的连接关系如下。其中因为LAN8720只要RMII连接模式,所以与MCU的连接就是RMII模式的,然后GPIO引脚的连接也如下: 根据这些引脚的连接关系,我们在board.c中编写关于MCU连接模式已经GPIO引脚初始化的代码,官方的bsp源码已经提供的一个初始化的参考代码了,但是那个函数只是适用于apm32自身的硬件,但也很有参考作用,我们就根据那个函数修改一下适应自己的硬件即可。具体代码如下: /*
* GPIO Configuration for ETH
*/
void ETH_GPIO_Configuration(void)
{
#ifdef BSP_USING_ETH
GPIO_Config_T GPIO_ConfigStruct;
/* Enable SYSCFG clock */
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_AFIO);
/* Enable GPIOs clocks */
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOB
| RCM_APB2_PERIPH_GPIOC | RCM_APB2_PERIPH_GPIOD);
/* ETHERNET pins remapp: RX_DV and RxD[3:0] */
GPIO_ConfigPinRemap(GPIO_REMAP_ETH_MAC);
/* MII/RMII Media interface selection */
GPIO_ConfigPinRemap(GPIO_REMAP_MACEISEL_RMII);
/*********************** 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 ----> PD8
ETH_MII_RXD0/ETH_RMII_RXD0 -------> PD9
ETH_MII_RXD1/ETH_RMII_RXD1 -------> PD10
ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PB11
ETH_MII_TXD0/ETH_RMII_TXD0 -------> PB12
ETH_MII_TXD1/ETH_RMII_TXD1 -------> PB13
*/
GPIO_ConfigStruct.pin = GPIO_PIN_1;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
/* Configure PD8, PD9, PD10 as input mode */
GPIO_ConfigStruct.pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
GPIO_Config(GPIOD, &GPIO_ConfigStruct);
/* Configure PA2, PC1 */
GPIO_ConfigStruct.pin = GPIO_PIN_2;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_1;
GPIO_Config(GPIOC, &GPIO_ConfigStruct);
/* Configure PB11, PB12, PB13 as alternate function push-pull */
GPIO_ConfigStruct.pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
GPIO_Config(GPIOB, &GPIO_ConfigStruct);
#endif
}
3.3 更改phy型号的宏定义在apm32官方提供的网络驱动代码中,已经支持了 LAN8720、DP83848、DM9161这几款常见的phy了,如果我们的硬件正好是使用这几款phy芯片,那么只需要在 rt-config.h 文件中定义对应phy型号的宏定义即可。 当然如果我们使用的phy芯片不是上面那几种,我们自己适配改动也不大,只要对着对应的phy芯片手册,定义相关的寄存器即可,相关宏定义代码可查看 drv_eth.h 文件,部分代码截图如下: 官方的bsp支持的芯片是DP83848,而我项目的硬件phy使用的是LAN8720芯片,所以需要在 rt-config.h 文件中定义 PHY_USING_LAN8720A 这个宏,如下图: 4. 移植测试经过上一步的移植适配自己的硬件板卡之后,就可以编译下载到自己的板子验证是否OK了。代码默认是使用USART1作为打印调试接口的,编译下载程序后,启动如下: 说明,代码已经正常运行了的。 我们输入 ifconfig 命令,查看网口启动情况以及IP地址,如下图: 可以看到,状态是LINK_UP,说明已经正常启动起来了,而且DHCP是失能的,使用的是静态IP地址。 硬件板卡的IP地址是 192.168.1.30 ,我们打开电脑cmd,然后去ping板子的IP(注意要保证自己电脑IP和板子的IP在同一网段),如下图: 可以看到板子是有正常回复的,说明网络功能已经在APM32F107上正常运行起来了。 5. RT-Thread以太网应用示例RT-Thread的源码里面,其实有很多关于网络的基础应用例程了,我们可以根据这些例程修改为符合自己项目的需要。下面展示一下tcpserver和udpclient基本的应用例程。 1、首先,我们需要使能自己需要的网络应用例程,我这里使能 tcp server 和 udp client 。 2、保存退出之后,需要把示例程序下载到本地,输入 pkgs --update 命令即可拉取代码: 然后,我们再输入命令:scons --target=mdk5 -s 更新一下MDK工程即可。 我们打开MDK工程,可以看到我们添加的两个应用例程,如下图: 3、编译下载,进行测试。 这两个应用例程,其实都是再shell中,以命令的形式运行的,我们在shell输入对应的命令,就可以运行对应的例程了。我们可以在shell按tab键,可以看到下面两条关于这两个示例的命令: 4、tcpserver应用示例测试 再命令行下面运行tcpserv命令,这是板子会作为服务端,一直等待客户端的连接。 我们在电脑上打开网络调试工具,去连接板子,如下: 连接成功后,shell终端就可以接收电脑发送过来的数据了,如下图: 5、udpclient应用示例测试 首先我们在电脑上开启一个udp服务器,设置如下图: 然后,我再shell上面输入udp的命令:udpclient 192.168.1.50 5000 。 其中 192.168.1.50 就是udp服务端的IP,5000就是我们刚刚设置得端口号,如下: 运行该命令之后,udp服务端会收到10条数据,如下图: 以上就是我使用APM32F107,在RT-Thread系统上应用网络功能的过程分享了,希望对大家有所帮助。 由于论坛上传文件大小的限制,完整的工程源码上传不了,这里就不上传工程源码了,整个过程其实也很详细了,而且官方的bsp也做好了大部分工作,跟着上面的步骤来基本没太大问题的。
|