Keil MDK环境下FreeModebus移植踩坑记录
文章目录
- Keil MDK环境下FreeModebus移植踩坑记录
- armcc (arm compiler v5)环境
- 实验一:
- 实验二:
- armclang (arm compiler v6)环境
- 实验一:
- 实验二:
- 实验三:
- 实验四
- 总结
armcc (arm compiler v5)环境
实验一:
不勾选使用微库,不实现printf重定向。
在程序未接收到数据时可以正常运行,一接收到下发的数据便会停止运行,卡在如下图所示的BKPT 0xAB
处
实验二:
不勾选使用微库,关闭半主机模式,添加如下重定向代码:
#include <stdio.h>
//#include <time.h>
//#include <rt_misc.h>
#include "usart.h"#if !defined(__MICROLIB)
#pragma import(__use_no_semihosting)
void _sys_exit(int x) //避免使用半主机模式
{x = x;
}
void _ttywrch(int ch) {//sendchar (ch);ch = ch;
}
struct __FILE
{int handle;
};
FILE __stdout;
#endif#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{/* 实现串口发送一个字节数据的函数 *///serial_write(&serial1, (uint8_t)ch); //发送一个自己的数据到串口huart1.Instance->DR = ch & 0xff;return ch;
}
程序可以正常运行。
armclang (arm compiler v6)环境
实验一:
和上面实验一完全一致。
实验二:
不勾选使用微库,关闭半主机模式
__asm (".global __use_no_semihosting\n\t");
void _sys_exit(int x) //避免使用半主机模式
{x = x;
}
void _ttywrch(int ch) {//sendchar (ch);ch = ch;
}
程序中添加上如上代码,程序会卡死在hardfault中断中,在串口接收中断中设置断点,发现是由assert()函数位置处跳进了hardfault中断中。
实验三:
勾选上使用微库,其它不动,编译会有如下报错:
上面的第一个报错和第三个报错可以通过https://blog.csdn.net/qq_62014938/article/details/125602277文章中介绍的办法解决掉,然后只剩如下一个错误:
对于__eabi_assert
未定义错误我们可以参考如下连接中的解释:ARMCLANG: L6218E: Undefined Symbol __aeabi_assert。文中说明了原因:我们勾选了使用微库,而微库不支持abort()
,exit()
,assert()
等函数。FreeModbus库中用到了assert函数,因而导致了该问题。文章中也给除了多种解决方法:
- 在RTE环境下添加STDERR组件
- 使用微库自己实现
__eabi_assert()
函数 - 关闭assert函数:在C/C++配置页中的全局宏定义位置添加
NDEBUG
的宏,这可以让assert()
函数无效 - 关闭使用微库
在测试方法1的时候程序总会卡死在retarget_io.c
文件中的abort()
函数位置处。如下所示:
方法2未测试。方法3可以有效解决该问题。
实验四
不使用微库,不配置RTE,只在C/C++配置处添加NDEBUG
宏,如下所示:
程序可以正常运行。
总结
出现上面问题的主要原因在于FreeModbus库中使用了assert函数导致的,这里比较好的办法还是通过添加NDEBUG
宏使assert()
函数失效。