历史上的今天

今天是:2024年10月30日(星期三)

正在发生

2020年10月30日 | STM32(MDK)中不能使用printf()函数的问题

发布者:独享留白1028 来源: eefocus关键字:STM32  MDK  printf()函数 手机看文章 扫描二维码
随时随地手机看文章

简单地说:想在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 */

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“-》”Co de 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()以避免使用半主机模式  

///

  

/// name="x">  

/// 

  

_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 co de 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 co de 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);

    return ch;


这个例子简单地将输入字符重新定向到另一个函数sendchar(),sendchar()假定是个另外定义的串口输出函数。在这里,fputc()就似乎目标硬件和标准C库函数之间的一个抽象层。


关键字:STM32  MDK  printf()函数 引用地址:STM32(MDK)中不能使用printf()函数的问题

上一篇:STM32 USB 大容量存储器Mass Storage工程的讲解
下一篇:STM32 USB数据接收与数据发送程序流程分析

推荐阅读

集微网消息 5G带来的不仅仅是带宽更大、延时更小的技术和机遇,还将为整个信息产业带来巨大的变革。5G为显示带来哪些变革?从黑白到彩色,从标清到高清,短短十几年,我们见证了显示技术的飞速发展。而今,在5G即将到来的关键节点,新一轮技术革命将彻底改变我们习以为常的生活习惯。当然,这一过程并非一蹴而就,需要产业链的相互配合,这其中自然包括显...
个人总结,如有错误,欢迎纠正,谢谢!!!MOV指令可以完成从另一个寄存器,被移位的寄存器或将一个立即数加载到目的寄存器。例如:MOV R1, R0MOV R1, R0, LSL #3MOV R1 , #3但把立即数赋给一个寄存器,对立即数的范围有要求。只能是由8bit连续有效位通过偶数次移位能得到的数。如果立即数超出这个范围,就没办法用一条MOV指令...
10月30日,苹果突然宣布将暂时关闭法国20家门店中的17家,以响应法国政府针对新冠肺炎疫情的新一轮全国性封锁政策。因该国正进入新的疫情封锁期,为期一个月。同时,苹果网站显示,该公司在德国的15家门店将保持开放。苹果公司周四盘后公布了其2020财年第四财季财报,数据略高于华尔街的普遍预期,但iPhone销售收入出现大幅下降,且未为投资者提供下一财季...
随着蜂窝移动技术进入5G时代,移动带宽不断增加,更多的频段被开发使用,这些带宽中的每一个频段都需要滤波器来将其信号与其他频段分开。对于使用频分双工(FDD)的信道,有两个相邻的链路——一个用于发送,一个用于接收。两者之间存在一个保护频段。这些频段或每一个子频段中都需要一个带通滤波器。随着频段数量的激增,所需的滤波器数量也呈爆炸式增长。...

史海拾趣

问答坊 | AI 解惑

高压双向触发器件SIDAC的特点及其应用

摘要:介绍一种新型的高压双向触发器件SIDAC的工作原理、性能特点及典型应用。在电子镇流器中广泛采用的双向触发器件是DB3,其触发开通电压在30V左右,触发电流较小(mA级),导通后的残余电压在20V左右,这些特点决定了只能用于小电流的触发电路中 ...…

查看全部问答∨

电子工程师必备基础知识

运算放大器通过简单的外围元件,在模拟电路和数字电路中得到非常广泛的应用。运算放大器有好些个型号,在详细的性能参数上有几个差别,但原理和应用办法一样。   运算放大器通常有两个输入端,即正向输入端和反向输入端,有且只有一个输出端。部 ...…

查看全部问答∨

逆变资料

本帖最后由 paulhyde 于 2014-9-15 09:23 编辑 自己用的,可能对大家有用  …

查看全部问答∨

程序返回值问题,欢迎大虾米来指导

最近我常用的一个函数出了点异样,大虾米现身了!!!HOHO 函数如下: unsigned int SysTim; unsigned int PreTim1; unsigned int PreTim2; unsigned int LenTim(unsigned int preTim, unsigned int sysTim) { if (preTim > sysTim) { return (0 ...…

查看全部问答∨

帮我看下,左边是信号源,右边是AD

来自EEWORLD合作群:arm linux fpga 嵌入0(49900581)群主:wangkj…

查看全部问答∨

s3c2410 jtag 下载不进去程序

ads1.2 显示下载进去程序了,但是查看内存发现,没有下进去,都为0xff。 …

查看全部问答∨

紧急!!!!!!!!!!

有谁了解深圳"研祥智能科技"公司吗?那边的待遇怎么样,我是08年的应届毕业生,我很想知道,本科生在那边的待遇和发展怎么样呢? 望各位知情的大虾帮帮忙啊 ~谢过~…

查看全部问答∨

fatal error C1083: Cannot open include file: 'zlib.h': No such file or directory

fatal error C1083: Cannot open include file: \'zlib.h\': No such file or directory 为什么会出这种错误,…

查看全部问答∨

射频电路板设计技巧

射频电路板设计技巧…

查看全部问答∨

【讨论】用单片机开发产品的几点体会

以下见解纯属一家之言,本来是写给自己的,但是看到本 BBS 中不少兄弟热心助人,受到感染,故将其贴出。希望能起到抛砖引玉的作用。 谬误及其它不妥之处,还望兄弟们提出指正。 用单片机开发产品的几点体会 1、用户需求 必须明确认识到作产品开 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved