四、移植过程

上面说到RT-THREAD修改了opener/port进行了系统适配,于是决定移植opener整套源码。

首先把必要原文件拷贝过去,头文件路径添加上,再对一遍有无遗漏,过程图如下:

点击编译会报很多错误,一部分是由于c语言版本不同导致,如keil默认不支持:

for(uint8_t i=0;i<10;i++)//报错
//--------------------------------
uint8_t i=0;
for(;i<10;i++)//不报错

应对措施,勾选c99模式就好

另外一部分报错__stdout被重复定义了。这是由于opener采用了<stdio.h>库,而这个库被wk_system.c做串口重定向时重复定义了。

于是注释掉wk_system.c内重定向代码,改用:

int fputc(int ch, FILE *f)
{
//  HAL_UART_Transmit(&husart_debug, (uint8_t *)&ch, 1, 0xffff);
        while(usart_flag_get(USART1, USART_TDBE_FLAG) == RESET){};
  usart_data_transmit(USART1, (uint16_t)ch);
  while(usart_flag_get(USART1, USART_TDC_FLAG) == RESET);
  return ch;
}

勾选微库:

由于勾选了微库,opener内使用的EXIT()和ASSART() time()均未定义,于是需要手动实现,添加如下代码:

void __aeabi_assert(const char *expr, const char *file, int line) {
    printf("ASSERT FAILED: %s, file %s, line %d\n", expr, file, line);

}
void exit(int status) {
    // 不做任何事,也不返回,因为裸机程序不需要真正退出
    while (1);  // 或者 return;
}


time_t time(time_t *t) {
    // 返回系统时间
                
    return timebase_ticks;
}

其他错误,如库内的枚举被重复定义:

../../middlewares/3rd_party/lwip/src/include/lwip/errno.h(59):
 warning:  #47-D: incompatible redefinition of macro "ENOMEM"  (declared at line 122 of "C:\Keil_v5\ARM\ARMCC\Bin\..\include\errno.h")   #define  ENOMEM          12  /* Out of memory */ 
C:\Keil_v5\ARM\ARMCC\include\errno.h(122) : #define ENOMEM  6

这是因为lwip定义了错误类型与库errno.h内冲突,修改采用标准库的.c为采用lwip的库就好。

其他的,如

#ifdef WIN32
#include <winsock2.h>
#elif defined STM32                 
#include "lwip/inet.h"
#else
#include <netinet/in.h>
#include <sys/socket.h>
#endif

手动定义下STM32,自动选择了lwip对应的库。

移植出现的大体问题列举完了,还有个别零星问题自行解决就好。

这里提醒下,移植及调试的过程中,有几个文件是要反复查看的,如:

opt.h//定义了lwip的系统功能开关及配置

lwipports.h//提供了lwip的快速配置选项

FreeRTOSConfig.h//定义了FreeRTOS的配置选项

opener_user_conf.h//定义了opener的配置选项

trace.,h//定义了opener的log开关等选项

未完待续。。。。

文内示例见咸鱼ID:tb764914262

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐