在移植库的时候,出现了这样的报错,Library reports error: __use_no_semihosting was requested, but _ttywrch was referenced原子哥指点后,然后查找问题,牵扯了到了题目的问题。理解这段代码,需要解决以下三个问题。一、什么是半主机模式和重定向。二、为什么要避免半主机模式以及如何避免。三、为什么代码要这样写。(暂时没有找到原因)半主机模式:用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如 printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕和键盘。我的理解就是:例如通过printf这样的函数,在ARM中运行该函数后,可通过仿真器(例如JTAG)在PC上打印出来。和ITM机制差不多,我也是通过ITM机制才理解的半主机模式是个什么鬼。ITM机制是一种调试机制,是新一代调试方式,在这之前,有一种比较出名的调试方式,称为半主机(semihosting)方式。据说两种机制是差不多的。如下图所示:通过该模式可以在PC上查看打印内容。以下是我自己的一点理解,望指正。我认为重定向和半主机模式是完全的两个概念。重定向是改变printf这样的函数输出方向,例如该函数原来是打印到屏幕上的,通过重定向,将该函数输出到串口中,这样就可以通过该函数直接打印串口了,重定向方便了用户,但是也相应出现了问题,容易与半主机模式发生冲突,因此需要关闭半主机模式。在重定向后,又不禁用半主机模式,通常会导致程序卡在某处,出不来。论坛吧友是这样解释的(我是比较认同的,暂时没有更好的解释了):这个是因为原子程序为了实现ARM能调用输出函数,把fputc重新定向到ARM的串口了(在标准C库里,printf 和scanf是被默认定向到显示器的),禁止使用半主机模式,就是在link的时候不调用标准C库的函数,但是可能由于在自己的子C文件中用到了某个函数,由于自己没有重定义,它就会去标准库里调用,这样就造成了矛盾,一边禁止使用半主机模式,一遍去C库里调用函数。所以会报错,这是我自己的理解,可能局部有说的不合适的地方,但是大概原理就是这个样子的。在单片机开发中,当然是不需要重定向和半主机模式的,这种重定向和半主机模式只试用与调试阶段,所以我认为一般开发是用不到的(或许我水平太浅)。当需要重定向函数时,需要做的就是避免半主机模式,需要用到以下代码:[mw_shl_code=applescript,true]#pragma import(__use_no_semihosting) 必须声明的
{
int handle;
};
FILE __stdout;
void _sys_exit(int x) 避免半主机模式
{
x = x;
}
有时候还需要添加这样一行代码:
_ttywrch(int ch)
{
ch = ch;
}
int fputc(int ch, FILE *f) 重定向函数
{
while((USART1->ISR&0X40)==0);
USART1->TDR=(u8)ch;
return ch;
}
[/mw_shl_code]以上是避免半主机模式的代码,为何这样写,暂时网上还没有一个确切的说法,只有说明怎样避免和为什么要避免半主机模式。以上是我参考网上的回答后理解,望指正。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>