完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
简单地说:想在mdk中用printf,同时重定义fputc函数和避免使用半主机模式,
标准库函数的默认输出是显示器,要实现在串口设备或LCD输出,必须重定义库函数的与输出设备相关的函数. 例如:printf输出到串口,需要将fputc里面的输出接口调用(主机),方法如下: #ifdef __GNUC__ /* With GCC/RAISONANCE, small printf (option LD Linker) ->Libraries->Small printf 设置为 'Yes') 调用 __io_putchar() */ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /* __GNUC__ */ PUTCHAR_PROTOTYPE { /* 将你的 fputc 实现放在这里 */ /* 例如写一个字符到 USART */ USART_SendData(USART1, (uint8_t) ch); /* 循环直到传输结束 */ 而 (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); 返回 ch; } 因printf()之类的函数,使用了半主机模式。使用标准库会导致程序无法运行,以下是解决方法: 方法1.使用微库,因为使用微库的话,不会使用半主机模式。 方法2.仍可使用标准库,在主程序添加如下代码: #pragma import(__use_no_semihosting) _sys_exit(int x) { x = x; } struct __FILE { int 句柄; /* 无论你在这里需要什么。如果您使用的唯一文件是 */ /* 使用 printf() 进行调试的标准输出,则不需要文件处理 */ /*。*/ }; /* FILE 在 stdio.h 中是 typedef' d。*/ FILE __stdout; 如果使用的是MDK,请在工程属性的“Target“-》”Code Generation“中勾选”Use MicroLIB;今天参考论坛,微库可以很好的解决这个问题。 2.另一种方法:(其实是大同小异) 需要添加以下代码 (论坛里应该有完整介绍这个帖子的,但是我没搜到,可能是沉了。) #pragma import(__use_no_semihosting) /***** ****************************************************** ************************ *标准库需要的支持函数 ******************** ****************************************************** ********/ struct __FILE { int 句柄; /* 无论你在这里需要什么。如果您使用的唯一文件是 */ /* 使用 printf() 进行调试的标准输出,则不需要文件处理 */ /*。*/ }; /* FILE 在 stdio.h 中是 typedef' d。*/ 文件 __stdout; /// ///定义_sys_exit()定义使用半主机模式 //// /// /// _sys_exit(int x) { x = x; } int fputc(int ch, FILE *f) { //USART_SendData(USART1, (u8) ch); USART1->DR = (u8) 通道; /* 循环直到传输结束 */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } return ch; } semihosting 的作用,介绍如下 Semihosting 是ARM 目标将输入/输出请求 从应用程序代码传送到运行调试器的主机的一种机制 。这种机制可能是 例如,用于允许 C 库中的函数(如 printf() 和 scanf())使用主机的屏幕和键盘,而不是在目标系统上使用屏幕和键盘。 这很有用,因为开发硬件通常不具备 最终系统的所有输入和 输出设施。半主机允许主机提供这些功能。 半主机由一组定义的软件中断 (SWI) 操作实现。 应用程序调用适当的 SWI,然后调试代理处理 SWI 异常。调试代理提供与主机所需的通信。 在许多情况下,半主机 SWI 将由库函数中的代码调用。应用程序还可以直接调用半主机 SWI。有关在 ARM C 库中支持半主机的更多信息,请参阅 ADS 编译器和库指南中的 C 库描述。 按我的理解,这个模式是分解的,通过仿真器,使用主机的输入输出转换转换自己的,想要自己的目标没有输出口也能把printf传到电脑上。由于这个模式改变了printf()等的实现方式,输入输出输出驱动的外设了,所以只重定义fputc不起作用。 用代码关闭此模式后,需要同时更新一下__stdout和__stdin的定义,所以有后面的语句。 以上仅为个人理解,如有错误请指正。 另外,勾选microlib中之后,也许编译的时候就不把开启半主机的文件包进去了,所以没事。 ç库函数重定向: 。用户能定义自己的ç语言库函数,连接器在连接时自动使用这些新的功能函数这个过程叫做重定向C语言库,如下图所示。 举例,用户有一个I/O设备(如UART)。本来库函数fputc()是把字符输出到调试器控制窗口中去的,但把输出设备改成UART端口,这样你,所有基于fputc()函数的printf()系列函数输出都被成功到UART端口上去了。 下面是实现fputc()生成的一个例子: externvoidsendchar(char*ch); intfputc(intch,FILE*f) {/*egwriteacharactertoanUART*/ chartempch=ch; 发送字符(&tempch); 返回; } 这个例子简单地将输入字符重新定向到另一个函数sendchar(),sendchar()假定是个另外定义的串口输出函数。在这里,fputc()函数就似乎目标硬件和标准Ç库函数之间的一个抽象层。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 22:15 , Processed in 0.990681 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号