在MDK开发环境中,
MicroLib是缺省c库的备选库,它可装入少量内存中,与嵌入式应用程序配合使用,且这些应用程序不在操作系统中运行。
MicroLib进行了高度优化以使代码变得很小,功能比缺省c库少,不具备某些ISO c特性,部分库函数的运行速度也比较慢,如内存拷贝函数memcpy()。
MicroLib与缺省c库之间的主要差异在网上有许多文章都有写到,这里摘抄记录:
MicroLib提供了一个有限的stdio子系统,它仅支持未缓冲的stdin、stdout和stderr,那么也就是说勾选了Use MicroLib选项后,在代码工程中就可以使用printf()函数咯?
然而事实并非如此,这样直接使用printf()函数,其打印的字符串最终不知道打印到何处。
我们要做的是将调试信息打印到USART1中,所以需要对printf()函数所依赖的打印输出函数fputc()重定向(MicroLib中的printf()函数打印操作依赖fputc())。
在MicroLib的stdio.h中,fputc()函数的原型为:
int fputc(int ch, FILE* stream)
此函数原本是将字符ch打印到文件指针stream所指向的文件流去的,现在我们不需要打印到文件流,而是打印到串口1。基于前面的代码:
#include
int fputc(int ch, FILE* stream)
{
//USART_SendData(USART1, (unsigned char) ch);
//while (!(USART1->SR & USART_FLAG_TXE));
USART_SendChar(USART1, (uint8_t)ch);
return ch;
}
注意,需要包含头文件stdio.h,否则FILE类型未定义。勾选了Use MicroLib选项,重定向fputc()函数后,我们就可以在工程代码中使用printf()函数了:
int main(void)
{
USART_Configuration();
//USART_SendString(USART1, "HelloWorld\n");
//USART_SendChar(USART1, 'h');
printf("\r\nstm32f103rct6\r\n");
printf("\r\nCortex-M3\r\n");
while (1);
return 0;
}
printf()函数的使用方法跟之前一样,运行结果:
半主机模式是ARM的一种机制,实现将来ARM应用程序代码的输入/输出请求传送至运行着调试器的主机。
例如设置使用半主机模式下的ARM应用程序,可以使用printf()和scanf()来使用主机的显示器和键盘,而不需要在ARM系统上搭配显示器和键盘。
半主机通过一组定义好的软件指令(如SVC)来实现的,这些指令在程序控制下产生异常,ARM应用程序调用半主机对应的异常处理函数,然后调试代理处理该异常。
一般的ARM应用程序中并不需要半主机操作,在这里为确保ARM应用程序中没有链接MicroLib的半主机相关函数,我们要取消ARM的半主机工作模式。
在工程中加上如下代码:
//取消ARM的半主机工作模式
#pragma import(__use_no_semihosting)
struct __FILE {
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f){
while((USART1->SR&0X40)==0);
USART1->DR = (u8) ch;
return ch;
}
这样操作后,在不使用MicroLib的前提下,仍能使用printf()函数将调试信息打印到USART1上了。
原文链接:https://blog.csdn.net/qq_29344757/article/details/75363639
由于微信公众号近期改变了推送规则,如果您想经常看到我们的文章,可以在每次阅读后,在页面下方点一个「赞」或「在看」,这样每次推送的文章才会第一时间出现在您的订阅列表里。
免责声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。
往期推荐:
C语言、嵌入式中几个非常实用的宏技巧
分享一个自用的、极简的log模块!
分享一个很酷的IDE!软工必备
C语言、嵌入式位操作精华技巧大汇总
嵌入式大杂烩周记 | 第 1 期
Hello系列 | cmake简明基础知识
干货 | 项目乏力?nanopb助你一臂之力
在公众号聊天界面回复1024,可获取嵌入式资源;回复 m ,可查看文章汇总。
点击阅读原文,查看更多分享。