ARM的Semihosting技术(转)
Semihosting技术将应用程序中的IO请求通过一定的通道传送到主机(host),由主机上的资源响应应用程序的IO请求, 而不是像在主机上执行本地应用程序一样,由应用程序所在的计算机响应应用程序IO请求, 也就是将目标板的输入/输出请求从应用程序代码传递到远程运行调试器的主机的一种机制。 简单来说,目标开发板上通常不会有输入/输出这些外设,开发板运行的代码想要将结果打印出来, 或者获得用户的输入,可以通过请求远程主机IO设备来实现,如:显示器,键盘等。 目标开发板执行代码中加入对输入/输出设备进行访问函数,如:printf,scanf等, 这些函数并不是目标开发板的库函数,而是远程主机交叉编译器中带有的库函数,这些库函数被编译时,编译成一条软件中断指令。 当目标开发板上电运行之后,执行到请求访问输入/输出设备指令时,产生特定中断号的软件中断SWI, 与开发板相连的调试器会先截获目标板SWI请求,由于开发板程序中也可能存在用户自定义软件中断, 为了区分二者,调试器会根据SWI的软中断号来判断是不是semihosting模式IO请求, 如果是,则取出R0寄存器里代表的具体请求号,然后使用远程主机来响应目标板具体IO请求, 而不是开发板本身去处理setmihosting请求。 semihosting仅仅是一种调试手段,它的工作原理就是利用调试器捕捉目标环境运行过程中产生SWI中断, 然后向远程主机调试环境发送对应的调试信息。 也就是说目标开发板通过特定的软件中断指令,借用了远程主机的输入输出设备实现IO请求的访问。
Semihosting半主机调试模式,只能使用在开发板和调试主机通过仿真器连接的情况下, 也就是说脱离了主机调试环境上述代码不能正常运行。 目标开发板上执行的IO实际上是交给了远程主机来处理实现,正是因为如此,这种方式只适合在调试模式下, 真正的嵌入式系统不可能依赖于主机实现IO处理的,嵌入式系统要想独立出来实现IO请求的处理, 这就需要将输入输出库函数的底层相关硬件实现重定向。
使用ITM机制实现调试,实现printf与scanf, ITM是ARM在推出semihosting之后推出的新一代调试机制。
ITM机制要求使用SWD方式接口,并需要连接SWO线。
半主机是用于 ARM 目标的一种机制,可将来自应用程序代码的输入/输出请求传送至运行调试器的主机。 例如,使用此机制可以启用 C 库中的函数,如 printf() 和 scanf(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕和键盘。
MDK中通常使用以下两种方法:
#pragma import(__use_no_semihosting) //不使用半主机模式
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
_sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}

大部分资料都是禁用了半主机模式,没有使用过半主机模式借助主机的键盘输入参数,看了很多资料,都是讲半主机的,但讲的内容太浅显,
在keil5中,不管是否使用Semihosting,使用printf,scanf,fopen,fread等都需要自己填充底层函数,以printf为例,需要补充定义fputc(Keil是否不支持Host-semi机制,即不支持直接在IDE打印字符串?)
特别注意:在keil中串口打印窗口和逻辑分析窗口仅在软件仿真的时候可用,而MDK5对STM32F4的软件仿真,基本上不支持(故本教程直接没有对软件仿真进行介绍了),所以,基本上这两个窗口用不着。但是对STM32F1的软件仿真,MDK5是支持的,在F1开发的时候,可以用到。所以基于STM32F4的软件仿真在keil5中很少用到。
在IAR中,选择Semihosting后,不用自己实现填充printf,scanf,fopen,fread等底层函数,就可以在terminal I/O界面实现prrint,scanf等的测试,可以在工程目录下实现文件操作。
疑问研究后的结论:
使用keil在半主机模式下,若是使用printf、 fopen等库函数库函数调用,会进入半主机模式,发生软件异常,若此时有半主机调试环境的支持(RealView ISS、ISSM、RealView ICE 和 RealMonitor)进而通过调试器与主机进行交互,则可以进入半主机模式。但是本人使用的是JLINK V9调试器,此调试器应该是不支持半主机的调试。所以程序会进入一个错误的BKPT 0xAB状态。得出结论:并不是keil5完全不支持半主机调试,是需要完全具备半主机调试的所有软硬件平台条件后才可以用半主机来调试代码。所以,大多数情况下,需要使用相关宏(#pragma import(__use_no_semihosting))和重定义底层IO函数的方法来避免使用半主机。
参考链接:
http://www.eeworld.com.cn/mcu/article_2016122632650.html
以及keil5的官方帮助文档。
另外:IAR、KEIL都可以使用ITM跟踪调试功能,可参考下面链接
https://www.jianshu.com/p/0255097f594e
。
posted on 2019-06-20 13:50 lh03061238 阅读(4623) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)