[APM32F1] RT-Thread系统的LwIP网络组件在APM32F107使用过程分享

[复制链接]
2944|15
 楼主| luobeihai 发表于 2023-2-9 21:28 | 显示全部楼层 |阅读模式
最近由于项目需要,要在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 源码压缩包。
image-20230207232819511.png
或者使用git bash工具,克隆整个仓库。
image-20230207233316492.png
在 github 上下载非常慢,而且有时还打不开网页。所以,也可以到国内的 gitee 网站下载RT-Thread的源码,链接如下:
https://gitee.com/rtthread/rt-thread
不过 gitee 上的代码更新可能会慢于 github 上的代码,但基本上足够我们使用了。
2. 使能以太网外设和LwIP网络组件
下载完源码之后,我们到源码根目录的bsp目录,然后找到apm32目录下的,关于apm32f107的bsp,如下图:
image-20230208212428753.png
进入该目录,然后在该目录下打开ENV工具(ENV工具的使用和介绍可参考RT-Thread官方文档介绍:https://www.rt-thread.org/document/site/#/development-tools/env/env),输入menuconfig命令:
image-20230208214449671.png
然后找到Hardware Drivers Config选项,进去把以太网外设打开:
image-20230208214731900.png
使能了以太网外设之后,就会默认打开了RT-Thread组件的网络接口设备以及LwIP网络协议栈了,我们还需要自己配置一下LwIP有关的选项。比如是否使用DHCP动态分配IP地址,还是使用静态IP,比如裁剪下LwIP内存池的大小,使得占用内存减少。如下:
image-20230208215601036.png
因为我身边没有路由器进行动态分配IP,所以这里我配置成静态IP。另外,还裁剪了LwIP对RAM的使用。
配置完成之后,保存退出。
然后在ENV工具中输入命令:scons --target=mdk5 -s   生成 mdk5 工程。
3. 以太网板级驱动的移植适配
上面生成的MDK5工程,如果使用人家制作这个bsp的硬件板卡的话,代码是直接可以编译下载就能使用了的。
但是,每个人手上的硬件板卡,使用的物理层芯片不一样,硬件连接方式也可能不一样,所以需要做一点简单的配置工作。
3.1 确认phy复位引脚和MCU的连接
我项目的硬件板卡,所使用的phy是很常见的LAN8720芯片,其中phy的复位引脚是没有和MCU的GPIO相连的,而是直接连接到了MCU上电的复位引脚上。所以不用修改该引脚的代码,phy引脚的复位函数直接写为空函数即可。
image-20230208222118529.png
但是,有些硬件板卡,可能会把该引脚和MCU的GPIO连接,使用软件进行复位,我们需要根据自己的原理图确认phy的复位引脚连接到了哪个引脚。
然后,再编写该复位函数了。其实就是把该引脚先拉低,然后延时一下再拉高即可。相关代码如下:
image-20230208222323075.png
3.2 phy与MCU连接方式和引脚初始化
对于我自己的项目,phy和MCU的连接关系如下。其中因为LAN8720只要RMII连接模式,所以与MCU的连接就是RMII模式的,然后GPIO引脚的连接也如下:
image-20230208224337057.png
根据这些引脚的连接关系,我们在board.c中编写关于MCU连接模式已经GPIO引脚初始化的代码,官方的bsp源码已经提供的一个初始化的参考代码了,但是那个函数只是适用于apm32自身的硬件,但也很有参考作用,我们就根据那个函数修改一下适应自己的硬件即可。具体代码如下:
  1. /*
  2. * GPIO Configuration for ETH
  3. */
  4. void ETH_GPIO_Configuration(void)
  5. {
  6. #ifdef BSP_USING_ETH
  7.     GPIO_Config_T GPIO_ConfigStruct;

  8.     /* Enable SYSCFG clock */
  9.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_AFIO);

  10.     /* Enable GPIOs clocks */
  11.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOB
  12.         | RCM_APB2_PERIPH_GPIOC | RCM_APB2_PERIPH_GPIOD);

  13.     /* ETHERNET pins remapp: RX_DV and RxD[3:0] */
  14.     GPIO_ConfigPinRemap(GPIO_REMAP_ETH_MAC);

  15.     /* MII/RMII Media interface selection */
  16.     GPIO_ConfigPinRemap(GPIO_REMAP_MACEISEL_RMII);

  17.     /*********************** Ethernet pins configuration ***************************/
  18.     /*
  19.         ETH_MDIO -------------------------> PA2
  20.         ETH_MDC --------------------------> PC1
  21.         ETH_MII_RX_CLK/ETH_RMII_REF_CLK---> PA1
  22.         ETH_MII_RX_DV/ETH_RMII_CRS_DV ----> PD8
  23.         ETH_MII_RXD0/ETH_RMII_RXD0 -------> PD9
  24.         ETH_MII_RXD1/ETH_RMII_RXD1 -------> PD10
  25.         ETH_MII_TX_EN/ETH_RMII_TX_EN -----> PB11
  26.         ETH_MII_TXD0/ETH_RMII_TXD0 -------> PB12
  27.         ETH_MII_TXD1/ETH_RMII_TXD1 -------> PB13
  28.     */
  29.     GPIO_ConfigStruct.pin = GPIO_PIN_1;
  30.     GPIO_ConfigStruct.mode  = GPIO_MODE_IN_FLOATING;
  31.     GPIO_Config(GPIOA, &GPIO_ConfigStruct);
  32.        
  33.     /* Configure PD8, PD9, PD10 as input mode */
  34.     GPIO_ConfigStruct.pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
  35.     GPIO_ConfigStruct.mode = GPIO_MODE_IN_FLOATING;
  36.     GPIO_Config(GPIOD, &GPIO_ConfigStruct);
  37.        
  38.     /* Configure PA2, PC1 */
  39.     GPIO_ConfigStruct.pin = GPIO_PIN_2;
  40.     GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
  41.     GPIO_ConfigStruct.mode  = GPIO_MODE_AF_PP;
  42.     GPIO_Config(GPIOA, &GPIO_ConfigStruct);

  43.     GPIO_ConfigStruct.pin = GPIO_PIN_1;
  44.     GPIO_Config(GPIOC, &GPIO_ConfigStruct);

  45.     /* Configure PB11, PB12, PB13 as alternate function push-pull */
  46.     GPIO_ConfigStruct.pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
  47.     GPIO_Config(GPIOB, &GPIO_ConfigStruct);
  48. #endif
  49. }

3.3 更改phy型号的宏定义
在apm32官方提供的网络驱动代码中,已经支持了 LAN8720、DP83848、DM9161这几款常见的phy了,如果我们的硬件正好是使用这几款phy芯片,那么只需要在 rt-config.h 文件中定义对应phy型号的宏定义即可。
当然如果我们使用的phy芯片不是上面那几种,我们自己适配改动也不大,只要对着对应的phy芯片手册,定义相关的寄存器即可,相关宏定义代码可查看 drv_eth.h 文件,部分代码截图如下:
image-20230208233733569.png
官方的bsp支持的芯片是DP83848,而我项目的硬件phy使用的是LAN8720芯片,所以需要在 rt-config.h 文件中定义 PHY_USING_LAN8720A 这个宏,如下图:
image-20230208234133226.png
4. 移植测试
经过上一步的移植适配自己的硬件板卡之后,就可以编译下载到自己的板子验证是否OK了。代码默认是使用USART1作为打印调试接口的,编译下载程序后,启动如下:
image-20230208235237437.png
说明,代码已经正常运行了的。
我们输入 ifconfig 命令,查看网口启动情况以及IP地址,如下图:
image-20230208235615323.png
可以看到,状态是LINK_UP,说明已经正常启动起来了,而且DHCP是失能的,使用的是静态IP地址。
硬件板卡的IP地址是 192.168.1.30 ,我们打开电脑cmd,然后去ping板子的IP(注意要保证自己电脑IP和板子的IP在同一网段),如下图:
image-20230209000037295.png
可以看到板子是有正常回复的,说明网络功能已经在APM32F107上正常运行起来了。
5. RT-Thread以太网应用示例
RT-Thread的源码里面,其实有很多关于网络的基础应用例程了,我们可以根据这些例程修改为符合自己项目的需要。下面展示一下tcpserver和udpclient基本的应用例程。
1、首先,我们需要使能自己需要的网络应用例程,我这里使能 tcp server 和 udp client 。
image-20230209001531902.png
2、保存退出之后,需要把示例程序下载到本地,输入 pkgs --update 命令即可拉取代码:
image-20230209001309181.png
然后,我们再输入命令:scons --target=mdk5 -s   更新一下MDK工程即可。
我们打开MDK工程,可以看到我们添加的两个应用例程,如下图:
image-20230209001942070.png
3、编译下载,进行测试。
这两个应用例程,其实都是再shell中,以命令的形式运行的,我们在shell输入对应的命令,就可以运行对应的例程了。我们可以在shell按tab键,可以看到下面两条关于这两个示例的命令:
image-20230209002136277.png
4、tcpserver应用示例测试
再命令行下面运行tcpserv命令,这是板子会作为服务端,一直等待客户端的连接。
我们在电脑上打开网络调试工具,去连接板子,如下:
image-20230209002807103.png
连接成功后,shell终端就可以接收电脑发送过来的数据了,如下图:
image-20230209002856130.png
5、udpclient应用示例测试
首先我们在电脑上开启一个udp服务器,设置如下图:
image-20230209003920572.png
然后,我再shell上面输入udp的命令:udpclient 192.168.1.50 5000  。
其中 192.168.1.50 就是udp服务端的IP,5000就是我们刚刚设置得端口号,如下:
image-20230209003634125.png
运行该命令之后,udp服务端会收到10条数据,如下图:
image-20230209004112956.png
以上就是我使用APM32F107,在RT-Thread系统上应用网络功能的过程分享了,希望对大家有所帮助。
由于论坛上传文件大小的限制,完整的工程源码上传不了,这里就不上传工程源码了,整个过程其实也很详细了,而且官方的bsp也做好了大部分工作,跟着上面的步骤来基本没太大问题的。

weifeng90 发表于 2023-2-10 08:45 来自手机 | 显示全部楼层
RT-Thread系统现在的第三方功能库也做的比较完善了。

评论

RT-Thread确实有很多拿来就能用的组件了,使用起来很方便。但是我个人感觉,如果项目中使用到了RT-Thread没有的组件,需要自己去添加这部分功能时,还是有难度的。当然可能是我对RT-Thread的驱动框架还不是很熟悉吧  发表于 2023-2-10 09:15
kai迪皮 发表于 2023-2-13 15:13 | 显示全部楼层
好文,点赞o( ̄▽ ̄)d
linfelix 发表于 2023-3-4 20:15 | 显示全部楼层
LWIP协议怎么提高UDP速度
janewood 发表于 2023-3-4 21:09 | 显示全部楼层
如何在APM32F107上使用LwIP访问网页
maqianqu 发表于 2023-3-4 21:55 | 显示全部楼层
lwip, udp协议如何进行流量控制
elsaflower 发表于 2023-3-5 10:12 | 显示全部楼层
LWIP协议怎么提高UDP速度
louliana 发表于 2023-3-7 21:13 | 显示全部楼层
如何在APM32F107上使用LwIP访问网页
xiaoyaodz 发表于 2023-3-9 12:49 | 显示全部楼层
运行lwip库需要占用多少ram
bartonalfred 发表于 2023-3-10 10:32 | 显示全部楼层
lwip, udp协议如何进行流量控制
pl202 发表于 2023-3-10 13:01 | 显示全部楼层
可以用单片机实现一个HTTP服务器吗?
jonas222 发表于 2023-3-10 13:14 | 显示全部楼层
uip lwip 哪个好?              
abotomson 发表于 2023-3-10 16:11 | 显示全部楼层
LWIP协议怎么提高UDP速度
chenci2013 发表于 2023-3-10 17:24 | 显示全部楼层
lwip只能在RT-Thread平台下用吗

评论

不是啊,lwip可以裸机使用,也可以在其他RTOS使用  发表于 2023-3-11 11:49
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

101

帖子

4

粉丝
快速回复 在线客服 返回列表 返回顶部