RL_TCPNET是ARM的RL库中的网络协议栈,之前只在工程中见过,没有实际研究过。刚好需要在STM32F2上开发网络接口,对比了几个常用的嵌入式网络栈,发现比较常用的就LwIP,刚开始也是想用LwIP,但怕调试时间来不及,且初试了一下,感觉内容比较多,暂时放弃。后决定参考之前的工程,使用RL_TCPNET。
主要参考了野火和硬汉的嵌入式开发版配套资料,大概熟悉了关于MAC、PHY、RMII/SMI等基础概念,然后根据MDK的文档开始网络开发。
首先,使用的STM32F207芯片自带MAC控制器,需要外部通过RMII/SMI接口连接一个PHY芯片。这里直接使用ARM的CMSIS-Driver中的Ethernet_MAC和Ethernet_PHY进行开发。
PHY根据实际情况选择相似的,由于之前项目有PHY驱动文件,所以没有后面勾选KSZ8081RNA,而使用的之前的PHY_general驱动文件(文件内容没有太多差异)。
选择Ethernet_MAC后,Project的CMSIS-Driver下会多出两个文件,“EMAC_STM32F2xx.c”和“EMAC_STM32F2xx.h”,其中C文件中主要定义了一个MAC对象的操作集。
/* MAC Driver Control Block */
ARM_DRIVER_ETH_MAC Driver_ETH_MAC0 = {
GetVersion,
GetCapabilities,
Initialize,
Uninitialize,
PowerControl,
GetMacAddress,
SetMacAddress,
SetAddressFilter,
SendFrame,
ReadFrame,
GetRxFrameSize,
GetRxFrameTime,
GetTxFrameTime,
ControlTimer,
Control,
PHY_Read,
PHY_Write
};
其中,ARM_DRIVER_ETH_MAC的定义在“Driver_ETH_MAC.h”中,该文件中有很多函数的声明,类似“ARM_ETH_MAC_XXX( )”,由于RT_TCPNET不开源,具体操作不清楚,只能根据函数名意会。
选择Ethernet_PHY后,Project的CMSIS-Driver下会多出两个文件,“KSZ8081RNA.c”和“KSZ8081RNA.h”,其中C文件中主要定义了一个PHY对象的操作集(实际是"PHY_general.c"和"PHY_general.h")。
/* PHY Driver Control Block */
ARM_DRIVER_ETH_PHY ARM_Driver_ETH_PHY_(ETH_PHY_NUM) = {
GetVersion,
Initialize,
Uninitialize,
PowerControl,
SetInterface,
SetMode,
GetLinkState,
GetLinkInfo
};
其中,ARM_DRIVER_ETH_PHY的定义在“Driver_ETH_PHY.h”中,该文件中有很多函数的声明,类似“ARM_ETH_PHY_XXX( )”,由于RT-TCPNET不开源,具体操作不清楚,只能根据函数名意会。
MAC和PHY对象操作集最终会被RL-TCPNET调用,这两个对象操作集会被“net_config.h”文件中的“net_eth0_config”结构体引用。
/* ETH0 device configuration */
NET_ETH_CFG net_eth0_config = {
&ARM_Driver_ETH_MAC_(ETH0_DRIVER),
&ARM_Driver_ETH_PHY_(ETH0_DRIVER),
osThread(netETH_Thread),
osSemaphore(eth0_lock),
eth0_mac_addr,
ETH0_MAC_ADDR,
#if (ETH0_IP4_ENABLE)
ð0_ip4_config,
#else
NULL,
#endif
#if (ETH0_IP6_ENABLE)
ð0_ip6_config
#else
NULL
#endif
};
然后按照MDK的网络组件文档,回到KEIL的RTE,配置Network,使用一个以太网口,“ETH”数量1个。
通过netInitialize( )函数进行初始化,但后来编译通过却发现程序会在这个函数卡死,无法完成初始化。后来仔细看了文档,原来是要多开两个用户线程。
所以需要到RTX_Conf_CM.c中进行额外配置。
之后netInitialize( )成功执行,网络其他配置也正常,设置了固定IP、网关、掩码和MAC,可以正常ping通。后以为网络开发差不多了,但有发现一个问题,刚开始确实可以ping通,但过一会儿就不行了,后来测试了多次,大概就是启动后一分钟,就再也ping不通了,程序也没死,其他线程正常运行。百思不得其解,偶然在网上搜到一个关于打印机一分钟后ping不通的提问,才发现原来是开了DHCP,一分钟后自动重配IP地址,所以取消DHCP之后,网络正常了。
记录一波,因为RL-TCPNET不开源,有些东西理解的不深,后期有机会再用LwIP试试,毕竟都是主流嵌入式网络协议栈。