您的位置 首页 ADAS

怎样处理STM32(MDK)中不能运用printf()函数的问题

简单地说:想在mdk中用printf,需要同时重定义fputc函数和避免使用semihosting(半主机模式),标准库函数的默认输出设备是显示器,要实现…

简略地说:想在mdk 顶用printf,需求一起重界说fputc函数和防止运用semihosting(半主机形式),
规范库函数的默许输出设备是显示器,要完成在串口或LCD输出,有必要重界说规范库函数里调用的与输出设备相关的函数.
例如:printf输出到串口,需求将fputc里边的输出指向串口(重定向),办法如下:
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to Yes) calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART1, (uint8_t) ch);
/* Loop until the end of transmission */
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
return ch;
}
因printf()之类的函数,运用了半主机形式。运用规范库会导致程序无法运转,以下是处理办法:
办法1.运用微库,因为运用微库的话,不会运用半主机形式.
办法2.依然运用规范库,在主程序增加下面代码:
#pragma import(__use_no_semihosting)
_sys_exit(int x)
{
x = x;
}
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
假如运用的是MDK,请在工程特点的“Target“-》”Code Generation“中勾选”Use MicroLIB;今日参阅了一下论坛,运用微库能够很好的处理这个问题。
2.另一种办法:(其实迥然不同)
需求增加以下代码
(论坛里应该有完好介绍这个的帖子,可是我没搜到,或许是沉了。)
#pragma import(__use_no_semihosting)
/******************************************************************************
*规范库需求的支撑函数
******************************************************************************/
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;

///

/// 界说_sys_exit()以防止运用半主机形式
///

/// ///
_sys_exit(int x)
{
x = x;
}

int fputc(int ch, FILE *f)
{
//USART_SendData(USART1, (u8) ch);
USART1->DR = (u8) ch;

/* Loop until the end of transmission */
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
{
}

return ch;
}
semihosting的效果,介绍如下
Semihosting is a mechanism for ARM targets to communicate input/output requests
from application code to a host computer running a debugger. This mechanism could be
used, for example, to allow functions in the C library, such as printf() and scanf(), to use the screen and keyboard of the host rather than having a screen and keyboard on the target system.
This is useful because development hardware often does not have all the input and
output facilities of the final system. Semihosting allows the host computer to provide these facilities.
Semihosting is implemented by a set of defined software interrupt (SWI) operations.
The application invokes the appropriate SWI and the debug agent then handles the SWI
exception. The debug agent provides the required communication with the host.
In many cases, the semihosting SWI will be invoked by code within library functions. The application can also invoke the semihosting SWI directly. Refer to the C library descriptions in the ADS Compilers and Libraries Guide for more information on support for semihosting in the ARM C library.
按我的了解,这个形式是用来调试的,经过仿真器,运用主机的输入输出替代单片机自己的,也就是说即使单片机没有输出口也能printf到电脑上。反过来,因为这个形式更改了printf()等的完成方法,输入输出就不走单片机的外设了,所以只重界说fputc不起效果。

用代码封闭此形式后,需求一起更新一下__stdout 和__stdin 的界说,所以有后边的句子。

以上仅为个人了解,如有过错请纠正。

别的,勾选microlib之后,或许编译的时分就不把敞开semihosting的文件包进去了,所以没事。

C库函数重定向:
用户能界说自己的C言语库函数,衔接器在衔接时主动运用这些新的功用函数。这个进程叫做重定向C言语库函数,如下图所示。
举例来说,用户有一个I/O设备(如UART)。原本库函数fputc()是把字符输出到调试器操控窗口中去的,但用户把输出设备改成了UART端口,这样一来,一切根据fputc()函数的printf()系列函数输出都被重定向到UART端口上去了。
下面是完成fputc()重定向的一个比如:
externvoidsendchar(char*ch);
intfputc(intch,FILE*f)
{/*e.g.writeacharactertoanUART*/
chartempch=ch;
sendchar(&tempch);
returnch;

这个比如简略地将输入字符从头定向到另一个函数sendchar(),sendchar()假定是个别的界说的串口输出函数。在这里,fputc()就好像方针硬件和规范C库函数之间的一个笼统层。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/adas/266958.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部