嵌入式系统重定向printf的三种方法

您所在的位置:网站首页 两种重定向 嵌入式系统重定向printf的三种方法

嵌入式系统重定向printf的三种方法

#嵌入式系统重定向printf的三种方法| 来源: 网络整理| 查看: 265

对printf()进行重定向的三种方法 方法1: 使用MircoLib并重定义fputc方法2: 停用半主机模式,在MDK中使用标准库重定向printf()方法3: 在Gcc中使用标准库重定向printf 1. MDK使用MircoLib并重定义fputc

printf()函数实际上是调用了fputc()根据 format 字符串给出的格式打印输出到 stdout(标准输出)中。这两个函数都定义在中:

int printf(const char *format, ...); ... int fputc(int ch, FILE *stream);

fputc() 函数写入字符 ch 到给定输出流 stream,printf()函数在调用fputc() 时,会向stream参数传入stdout从而打印数据到标准输出。 KEIL-MDK中有一个Use MicroLIB选项,MicroLib是缺省c库的备选库,它可装入少量内存中,与嵌入式应用程序配合使用,且这些应用程序不在操作系统中运行。MicroLib提供了一个有限的stdio子系统,它仅支持未缓冲的stdin、stdout和stderr。 所以我们只需要勾选Use MicroLIB选项,并重写fputc() 函数就可以将printf()从串口输出了。 在这里插入图片描述

int fputc(int ch, FILE* f) { USART_SendData(USART1, (unsigned char) ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } return ch; } 2. 在MDK中使用标准库重定向printf()

如果不想使用MicroLib,也可以使用标准库,但是需要停用半主机模式。下面我们提供另外一种重定义fputc()的写法。

STM32或者其他类似的ARM芯片(比如航顺HK32系列)的USART串口外设有一个 ISR 寄存器,全名 Interrupt and status register, 用来指示当前串口的状态,可以通过判断该位来判断串口当前是否处于发送状态,代码如下:

while((USART1->ISR & 0X40) == 0);

为了提高发送效率,直接使用寄存器来操作串口发送字符ch:

USART1->TDR = (uint8_t) ch; #include /* 告知连接器不从C库链接使用半主机的函数 */ #pragma import(__use_no_semihosting) /* 定义 _sys_exit() 以避免使用半主机模式 */ void _sys_exit(int x) { x = x; } /* 标准库需要的支持类型 */ struct __FILE { int handle; }; FILE __stdout; /*重定义fputc的另外一种方式*/ int fputc(int ch, FILE *stream) { /* 堵塞判断串口是否发送完成 */ while((USART1->ISR & 0X40) == 0); /* 串口发送完成,将该字符发送 */ USART1->TDR = (uint8_t) ch; return ch; } 3. 在Gcc中使用标准库重定向printf()

如果你不使用MDK而是Gcc来编译项目,那么上述两种方法不可行。 那么需要怎么做呢:

在使用Gcc编译器的时候,需要重新定义_write函数而不是fputs()函数。只能使用标准库,因为Gcc中没有MicroLib。 代码如下: #include int _write(int fd, char *ptr, int len) { HAL_UART_Transmit(&huart1, (uint8_t*)ptr, len, 0xFFFF); return len; }


【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3