今天继续总结LWIP的移植过程。
参考代码
LWIP源码包
在官网下载的源码包:lwip-2.1.3.zip
还有移植软件包:contrib-2.1.0.zip
GD32固件库
GD32F4xx_Firmware_Library_V3.1.0.7z
重点关注TELNET例程:
GD32F4xx_Firmware_Library_V3.1.0.7z\GD32F4xx_Firmware_Library_V3.1.0\Examples\ENET\Telnet
移植过程
拷贝代码
1,拷贝lwip的src目录;
lwip-2.1.3.zip\lwip-2.1.3\src
2,拷贝GD的ENET例程下的arch和Basic目录;
GD32F4xx_Firmware_Library_V3.1.0\Examples\ENET\Telnet\lwip-2.1.2\port\GD32F4xx\arch
GD32F4xx_Firmware_Library_V3.1.0\Examples\ENET\Telnet\lwip-2.1.2\port\GD32F4xx\Basic
3,拷贝GD的ENET例程中src目录下的netconf.c, netconf.h, lwipopts.h
4,拷贝应用层程序:tcp_echo
contrib-2.1.0\apps\tcpecho_raw下面的tcpecho_raw.c和tcpecho.h文件:
也可以参考ST的tcp_echoserver:
STSW_STM32070_V1.1.1.zip\STM32F4x7_ETH_LwIP_V1.1.1\Project\Standalone\tcp_echo_server\src\tcp_echoserver.c
或者:
STM32Cube\Repository\STM32Cube_FW_F4_V1.27.0\Projects\STM32469I_EVAL\Applications\LwIP\LwIP_TCP_Echo_Server\Src\tcp_echoserver.c
改写代码
新建一个任务,代替main函数。
原始main函数:
int main(void)
{
/* setup ethernet system(GPIOs, clocks, MAC, DMA, systick) */
enet_system_setup();
/* initilaize the LwIP stack */
lwip_stack_init();
while(1) {
/* check if any packet received */
if(enet_rxframe_size_get()) {
/* process received ethernet packet */
lwip_pkt_handle();
}
/* handle periodic timers for LwIP */
lwip_periodic_handle(g_localtime);
}
}
新建一个模块,代替gd32f4xx_enet_eval.c文件。里面的主要内容是:
/*!
\brief setup ethernet system(GPIOs, clocks, MAC, DMA, systick)
\param[in] none
\param[out] none
\retval none
*/
void enet_system_setup(void)
{
uint32_t ahb_frequency = 0;
#ifdef USE_ENET_INTERRUPT
nvic_configuration();
#endif /* USE_ENET_INTERRUPT */
/* configure the GPIO ports for ethernet pins */
enet_gpio_config();
/* configure the ethernet MAC/DMA */
enet_mac_dma_config();
if(0 == enet_init_status) {
while(1) {
}
}
#ifdef USE_ENET_INTERRUPT
enet_interrupt_enable(ENET_DMA_INT_NIE);
enet_interrupt_enable(ENET_DMA_INT_RIE);
#endif /* USE_ENET_INTERRUPT */
#ifdef SELECT_DESCRIPTORS_ENHANCED_MODE
enet_desc_select_enhanced_mode();
#endif /* SELECT_DESCRIPTORS_ENHANCED_MODE */
/* configure systick clock source as HCLK */
systick_clksource_set(SYSTICK_CLKSOURCE_HCLK);
/* an interrupt every 10ms */
ahb_frequency = rcu_clock_freq_get(CK_AHB);
SysTick_Config(ahb_frequency / 100);
}
/*!
\brief configures the ethernet interface
\param[in] none
\param[out] none
\retval none
*/
static void enet_mac_dma_config(void)
{
ErrStatus reval_state = ERROR;
/* enable ethernet clock */
rcu_periph_clock_enable(RCU_ENET);
rcu_periph_clock_enable(RCU_ENETTX);
rcu_periph_clock_enable(RCU_ENETRX);
/* reset ethernet on AHB bus */
enet_deinit();
reval_state = enet_software_reset();
if(ERROR == reval_state) {
while(1) {}
}
/* configure the parameters which are