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(),来使用主机的屏幕和键盘,而不是在目标系统上配备屏幕和键盘。

这种机制很有用,因为开发时使用的硬件通常没有最终系统的所有输入和输出设备。 半主机可让主机来提供这些设备。

 

半主机是通过一组定义好的软件指令(如 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 指令来实现半主机。
 
简单的来说,半主机模式就是通过仿真器实现开发板在电脑上的输入和输出。和半主机模式功能相同的是ITM调试机制。 有关ITM调试机制可以参考这里http://www.douban.com/note/248637026/

      
 上面介绍的半主机和ITM功能相当,他们都是调试机制,开发板均借助仿真器与电脑连接,实现单片机利用主机的屏幕键盘的输入输出。
这两种机制的运行均需要仿真器,否则无法运行。
   
    开发式一般单片机需要独立运行,开发者应去掉仿真器,把printf函数通过单片机的外设来实现,例如通过开发板的串口,lcd或者sd卡。
 

 MDK中通常使用以下两种方法:

方法1.使用微库,因为使用微库的话,不会使用半主机模式.

int fputc(int ch, FILE *f)

{      
while((USART1->SR&0X40)==0);    
USART1->DR = (u8) ch;      
return ch;

}  
方法2.仍然使用标准库,在主程序添加下面代码:

#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;
}
关于 microlib
microlib 是缺省 C 库的备选库。 它用于必须在极少量内存环境下运行的深层嵌入式应用程序。 这些应用程序不在操作系统中运行。microlib 不会尝试成为符合标准的 ISO C 库。
microlib 进行了高度优化以使代码变得很小。 它的功能比缺省 C 库少,并且根本不具备某些 ISO C 特性。某些库函数的运行速度也比较慢,例如,memcpy()。上面给出了正确的方法,我在测试的过程中发现方法二中注释掉#pragma import(__use_no_semihosting) 程序依然运行正确,这个很让人费解,是否是keil本身就没有半主机模式???????以下是测试现象
1、假如程序中有printf等函数,如果使用微库或者禁用半主机,没有重定义fputc函数,程序可以运行,但不知道结果打印到主机的哪个地方去了。
2、假如程序中有printf等函数,既没有禁用半主机也没有重定义fputc函数,程序将一直停在中断处,如下图,结论:如果用了库函数而没有勾选微库,则不能够进行在线仿真。
 3、若程序中假如程序中有fopen、fread等函数,重定义fputc函数,既没有禁用半主机也没有重定义fopen、fread这些函数,编译会报错:
Error: L6200E: Symbol __stdout multiply defined (by stdio_streams.o and usart.o).为什么是重复定义,还未搞清楚。打开微库就不会报错,但是其实也是存在问题,这些函数也并未实现其功能。
 

大部分资料都是禁用了半主机模式,没有使用过半主机模式借助主机的键盘输入参数,看了很多资料,都是讲半主机的,但讲的内容太浅显,

我没有学会使用半主机,更多的是学会了禁用半主机模式,我们好像忽略了半主机模式的意义。另外,我们可以查到的大部分资料讲解的大同小异,它们更多的告诉我们正确的步骤,而不是让我们从源头了解一个问题,当然,大部分人看重的是实用,问题解决了,也就不再去思考背后的原理。最有效最直接最权威的资料是mdk官方给出的资料,但是资料内容太多,看起来太多,不易懂,大部分人没有看下去的欲望。我们应该让使用手册看起来更直观,更易懂,更方便查阅,更高效地查阅。

 

      在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

 

 

ARM的Semihosting技术(转)的更多相关文章

  1. ARM的Jazelle技术【转】

    转自:https://blog.csdn.net/ken_yjj/article/details/6797290 Come From: http://www.arm.com/zh/products/p ...

  2. ARM Cortex-M底层技术(2)—启动代码详解

    杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...

  3. ARM流水线关键技术分析与代码优化

    引 言    流水线技术通 过多个功能部件并行工作来缩短程序执行时间,提高处理器核的效率和吞吐率,从而成为微处理器设计中最为重要的技术之一.ARM7处理器核使用了典型三级流 水线的冯·诺伊曼结构,AR ...

  4. ARM Cortex-M底层技术(1)—程序在Flash和SRAM的空间分配

    1. keil编译介绍 当使用keil进行单片机的开发时,运行一段程序后,在output输出框会看到如下图的结果. 图1 keil 的output框 其中,Compiler编译器,使用的版本是 V5. ...

  5. ARM Cortex-M底层技术(3)—编译内核的原理及其应用

    概述: 当前开发中,我使用的Keil开发工具较多(keil526),故以keil为例进行介绍,其他开发环境大同小异. 1. 编译链接的定义 不管我们编写的代码有多么简单,都必须经过「编译 --> ...

  6. 【开学季】自学嵌入式开发|四核开发板|4412开发板|ARM+Android+linux技术

    淘宝店铺:迅为开发板http://arm-board.taobao.com 网站:http://www.topeetboard.com QQ咨询:2551456065 电话咨询:010-5895758 ...

  7. ARM的Trust Zone技术

    ARM的Trust_Zone技术是一个系统的Access Control的架构. 与AXI,AHB,APB其中的secure,supervisor信号相关联. 与ARM core的模式相关连,当ARM ...

  8. 痞子衡嵌入式:浅析IAR下调试信息输出机制之半主机(Semihosting)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是IAR下调试信息输出机制之半主机(Semihosting). 在嵌入式世界里,输出打印信息是一种非常常用的辅助调试手段,借助打印信息,我 ...

  9. 【转】arm 开发工具比较(ADS vs RealviewMDK vs RVDS)

      ADS REALVIEW MDK RVDS 公司 ARM Keil(后被ARM收购) ARM 版本 最新1.2 ,被RVDS取代 最新4.0 是否免费 破解情况 有 有 工程管理 CodeWarr ...

随机推荐

  1. Android dump命令查看某个apk是被谁安装的?

    adb shell dumpsys package packages > packageAll.txt     ORadb shell pm dump packages > package ...

  2. 同时购入两台同款thinkpad笔记本电脑,分别使用同一账户激活office失败--------------解决方法(账户下有多个Office激活信息,重装后提示“许可证不正确或者最大激活次数”)

    如题所述,该问题曾多次与京东商城售后,京东thinkpad品牌售后,thinkpad售后等进行沟通,最后通过微软的电话激活才成功,不过在之后发现了这么一个帖子,应该是官方给出的,应该合理,没有实际验证 ...

  3. js 经常用于条件判断 大于等于0 的正整数

    /^\d+(?=\.{,}\d+$|$)/.test() // true 转:https://www.jianshu.com/p/feef5e62dd67

  4. 【转】Fuel-Openstack的搭建(一)

    原文链接:https://blog.csdn.net/qq_35180983/article/details/82181496 2.1安装前的准备操作: 首先,我们需要准备以下操作: 2.1.1 下载 ...

  5. windows下大数据开发环境搭建(1)——Java环境搭建

    一.Java 8下载 https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 下载之后 ...

  6. linux中安装python3.7

    linux中安装python3.7 1. 安装依赖包 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite- ...

  7. Qt deletelater函数分析(2)

       夫唯不争,故天下莫能与之争  -- 老子 在C++中,delete 和 new 必须 配对使用,Qt作为C++的库,显然是不会违背C++原则.但是,qt有自己的内存管理,有时候虽然使用了new, ...

  8. Java 8 集合之流式(Streams)操作, Streams API 详解

    因为当时公司的业务需要对集合进行各种各样的业务逻辑操作,为了提高性能,就用到了这个东西,因为以往我们以前用集合都是需要去遍历(串行),所以效率和性能都不是特别的好,而Streams就可以使用并行的方式 ...

  9. 重回ubutntu12.04小记(装完ubuntu做的几件事)

    原来一直是在windows下用虚拟机跑redhat 和debian 做实验和一些工程,以前也装过ubuntu和windows双系统,但是换电脑后,就一直懒得捣鼓了. 现在,由于长期需要在linux上做 ...

  10. 01 Struts2框架学习(了解一下,已过时)

    1.框架介绍 所谓框架,就是把一些繁琐的重复性代码封装起来,使程序员在编码中把更多的精力放到业务需求的分析和理解上面. 特点:封装了很多细节,程序员在使用的时候会非常简单. 早前,有三大框架strut ...