Printf重定向以及半主机模式

本文介绍了半主机模式在ARM嵌入式开发中的作用,如何通过仿真器实现输入输出调试,以及禁用半主机模式的方法。同时讨论了MicroLib库的特点和在使用printf重定向时的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

半主机模式:

半主机是用于ARM目标的一种机制;可将来自STM32单片机应用程序的输入输出请求传送至运行仿真器的PC主机。使用此机制可以启用C库中的函数,如printf()和scanf(),来使用PC主机的屏幕和键盘。

这样就可以看到单片机的输入输出,方便进行调试。但是这种机制的运行需要仿真器,否则无法运行。

半主机模式就是通过仿真器实现开发板在电脑上的 输入 和 输出 。在嵌入式的编程中避免不了使用printf、fopen、fclose等函数的但是因为嵌入式的程序中并没有对这些函数的底层实现,使得设备运行时会进入软件中断BAEB处,这时就需要__use_no_semihosting_swi这个声明,使程序遇到这些文件操作函数时不停在此中断处。
所以,我们需要禁止半主机模式。当目标板脱离仿真器(jlink/ulink)单独运行时,不能使用半主机模式。否则进入软件中断BAEB处,无法再执行下去。

半主机是通过一组定义好的软件指令(如 SVC)来实现的,这些指令通过程序控制生成异常。 应用程序调用相应的半主机调用,然后调试代理处理该异常。 调试代理提供与主机之间的必需通信。

半主机接口对 ARM 公司提供的所有调试代理都是通用的。 在无需移植的情况下使用 RealView ARMulator® ISS、指令集系统模型 (ISSM)、实时系统模型 (RTSM)、RealView ICE 或 RealMonitor 时,会执行半主机操作。

标准库使用半主机模式,半主机是通过一组定义好的软件指令 (如 SVC)SVC 指令 (以前称为 SWI 指令)来实现的,这些指令通过程序控制生成异常。 应用程序调用相应的半主机调用,然后调试代理处理该异常。调试代理(这里的调试代理是仿真器)提供与主机之间的必需通信。也就是说使用半主机模式必须使用仿真器调试。

ARMv7 之前的 ARM 处理器使用 SVC 指令 (以前称为 SWI 指令)进行半主机调用。 但是,如果要为 ARMv6-M 或 ARMv7-M (如 Cortex™-M1 或 Cortex-M3 处理器)进行编译,需要使用 BKPT 指令来实现半主机。

禁用半主机:
#pragma import(__use_no_semihosting)     //关闭半主机模式,只需要在任意一个C文件中加入即可

重定向Printf:

 要使用Printf通常有两种方法:

1.使用ARM标准库,在任意一个.c文件中添加如下代码
xx.c
struct __FILE 
{ 
    int handle; 
}; 
 
// 定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
    x = x; 
} 
 
FILE __stdout;

// 重定义fputc函数 
int fputc(int ch, FILE *f)
{  
    while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;     		
    return ch;
}
2.使用微库 

/*使用microLib的方法*/
int fputc(int ch, FILE *f)
{
    USART_SendData(USART1, (uint8_t) ch);
 
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {}	
 
    return ch;
}
int GetKey (void)  { 
 
    while (!(USART1->SR & USART_FLAG_RXNE));
 
    return ((int)(USART1->DR & 0x1FF));
}

关于MicroLIB微库:

  1. 什么是MicroLIB
    来自ARM-MDK官方的解释:MicroLib 是一个高度优化的库,适用于用 C 编写的基于 ARM 的嵌入式应用程序。与 ARM 编译器工具链中包含的标准 C 库相比,MicroLib 提供了许多嵌入式系统所需的显着代码大小优势。

  2. MicroLib 和标准 C 库之间的主要区别是:

  • MicroLib 专为深度嵌入式应用而设计。
  • MicroLib 经过优化,可以使用比使用 ARM 标准库更少的代码和数据存储器。
  • MicroLib 设计为无需操作系统即可工作,但这并不妨碍它与任何操作系统或 RTOS(例如 Keil RTX)一起使用。
  • MicroLib 不包含文件 I/O 或宽字符支持。
  • 由于 MicroLib 已经过优化以最小化代码大小,因此某些函数的执行速度将比 ARM 编译工具中可用的标准 C 库例程更慢。
  • MicroLib 和 ARM 标准库都包含在 Keil MDK-ARM 中
  1. 使用MicroLib的优缺点
  • 使用MicroLIB,简化嵌入式开发操作,例如你用printf()函数的时候,就会从串口1输出字符串,当然也可以重定义到其他串口;
  • 使用MicroLIB会优化代码空间,但会降低某些程序的执行效率(比如: memcpy()),效率换空间;
  • 由于MicroLIB不支持浮点运算,所以在有FPU单元的MCU上,使用MicroLIB并开启FPU会让程序死机或跑飞
  • Microlib不支持C++,在使用C++开发MCU时,首要条件是不能使用Microlib;

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值