学习笔记-Semihosting

Semihosting是一种在目标板上运行程序时,利用主机设备进行调试的方法,尤其适用于没有Angel支持的裸板调试。通过设置断点在SWI向量,Multi-ICE或类似的debug agent可以模拟Semihosting SWI,提供打印字符、接收输入等服务。在C/C++代码中,当包含汇编代码时,需要使用Semihosting。通过调整内部变量如$semihosting_enabled和$semihosting_vector,可以启用、禁用或自定义Semihosting行为。
AI助手已提取文章相关产品:

如何理解Semihosting?(老帖重发,写得比较久了)

  Semihosting,顾名思义,就是"半主控",意思就是说,运行在target board上的程序利用主机上的facilities的一种程序调试方式,主要是debug目标板时,利用主机的输入输出设备,例如在AxD的console上打印相应的调试信息或者用主机的键盘输入相应字符作为target上的程序的输入。
  C/C++ code默认是可以使用console的,例如,如果只包含C/C++的程序采用ARMulater模拟,就可以直接使用console作为程序的输出设备;如果程序包含有汇编代码,要使用主机设备的话,必须采用semihosting SWI方式。Semihosing SWI(以下简称SHS),必须有相应的debug agent的支持,才能截获SHS,并向software debugger(AxD)请求相应的服务,如打印字符或者接受字符输入,这样的agents包括:
 1)ARMulater
 2)debug monitor(Angel)
 3)MultiICE
  由于调试裸板或者没有Angel可以供目标板使用的时候,主要还是要借助仿真器进行调试,所以第三种方式最为常用,下面主要就这种方式进行介绍。当然,UART也是一种最常用的调试接口,但是,使用Semihosting,可以独立地调试各个硬件模块的逻辑功能,确保各段代码正确后再进行集成,相应地省去了每次都要配置UART和另开一个hyperterminal观察调试信息。所以,我在开发的时候倾向于使用semihosting来调试相关的代码,这些代码使用C或者C++编写,也就是说和硬件配置关系不大。

=================================Below from ADS help===============================
Multi-ICE
When using Multi-ICE in default configuration, semihosting is implemented as follows:
1. On ARM7 processors:
 a) A breakpoint is set on the SWI vector.
 b) When this breakpoint is hit, Multi-ICE examines the SWI number.
 c) If the SWI is recognized as a semihosting SWI, Multi-ICE emulates it and transparently restarts execution of the application.
 If the SWI is not recognized as a semihosting SWI, Multi-ICE halts the processor and reports an error.
2. On other processors:
 a) Vector-catch logic traps SWIs.
 b) If the SWI is recognized as a semihosting SWI, Multi-ICE emulates it and transparently restarts execution of the application.
 If the SWI is not recognized as a semihosting SWI, Multi-ICE halts the processor and reports an error.
 This semihosting mechanism can be disabled or changed by the following debugger internal variables:
  $semihosting_enabled
 Set this variable to 0 to disable semihosting. If you are debugging an application running from ROM, this allows you to use an  additional watchpoint unit.
 Set this variable to 1 to enable semihosting. This is the default.
 Set this variable to 2 to enable Debug Communications Channel semihosting.
 The S bit in $vector_catch has no effect unless semihosting is disabled.
 $semihosting_vector
This variable controls the location of the breakpoint set by Multi-ICE to detect a semihosted SWI. It is set to the SWI entry in the exception vector table (0x8) by default.
If your application requires semihosting as well as having its own SWI handler, set $semihosting_vector to an address in your SWI handler. This address must point to an instruction that is only executed if your SWI handler has identified a call to a semihosting SWI. All registers must already have been restored to whatever values they had on entry to your SWI handler.
Multi-ICE handles the semihosted SWI and then examines the contents of lr and returns to the instruction following the SWI instruction in your code.
Regardless of the value of $vector_catch, all exceptions and interrupts are trapped and reported as an error condition.
For details of how to modify debugger internal variables, see the appropriate debugger documentation.

 

最后一次修改2006.3.14

您可能感兴趣的与本文相关内容

<think>嗯,用户遇到了“文件':semihosting - features'无法打开”的问题,这看起来是个嵌入式开发中的路径处理错误。用户引用了三段资料,但核心应该是semihosting机制相关的文件访问异常。 从用户提供的引用内容看,第三个引用提到QEMU构建时的GIT子模块缺失错误,这暗示用户可能在搭建类似OP-TEE的嵌入式环境。而“:semihosting - features”这个文件名格式很特殊,冒号开头像虚拟文件系统路径,常见于ARM semihosting机制中通过调试器暴露的宿主文件。 用户真正的痛点可能是:在交叉调试环境下,宿主机文件无法被目标设备访问。需要分三层排查: 1. 路径格式是否正确——semihosting要求宿主路径必须是绝对路径,Windows需注意盘符大小写 2. 调试器配置是否启用semihosting——比如OpenOCD需要显式开启`arm semihosting enable` 3. 文件权限问题——特别是Linux/macOS宿主机的SELinux或访问控制列表限制 突然想到更隐蔽的可能性:如果用户在用QEMU,其semihosting默认只读,写操作需要额外参数。另外引用[2]提到的堆分配失败也值得关注,因为semihosting依赖动态内存,如果用户的裸机程序堆初始化失败会导致文件操作崩溃。 解决方案应该优先验证最基本场景:让用户尝试用绝对路径打开宿主机的文本文件。如果失败再检查调试器日志,通常会输出semihosting调用错误码。ARM文档定义了详细的semihosting错误代码表,比如0x200001代表文件不存在。 </think>文件`:semihosting - features`无法打开的问题通常与嵌入式开发中的**Semihosting机制**相关,以下是常见原因及解决方案: --- ### **问题根源分析** 1. **路径格式错误** - Semihosting要求宿主机文件的路径必须是**绝对路径**(如 `C:\file.txt` 或 `/home/user/file.txt`) - 错误示例:`:semihosting - features`(缺少绝对路径前缀) - ✅ 正确格式:`:/path/to/semihosting-features`(Unix/Linux)或 `:C:\\path\\to\\semihosting-features`(Windows) 2. **调试器未启用Semihosting** - 需在调试器(如 OpenOCD、J-Link)中**显式启用** Semihosting功能 - 例如 OpenOCD 需添加命令:`arm semihosting enable` 3. **文件权限/位置问题** - 宿主机文件可能不存在、路径错误或被锁定 - 检查文件是否位于调试器工作目录(如 QEMU/QEMU_V8 的构建目录) 4. **目标设备堆内存不足** - Semihosting依赖动态内存分配,需确保目标设备有足够堆空间(参考引用[2]的堆分配问题) --- ### **解决方案** #### 1. 修正文件路径格式 ```c // 错误调用 fopen(":semihosting - features", "r"); // 正确调用(Linux示例) fopen(":/home/user/semihosting-features", "r"); // Windows示例 fopen(":C:\\data\\semihosting-features", "r"); ``` #### 2. 启用调试器的Semihosting - **OpenOCD** 配置中添加: ```tcl arm semihosting enable ``` - **J-Link** 使用参数: ``` -enable semihosting ``` - **QEMU** 启动时添加: ``` qemu-system-arm ... -semihosting ``` #### 3. 检查文件系统权限 - 确认宿主文件存在且路径正确 - 关闭可能占用文件的进程(如 IDE) - Linux/macOS 使用 `chmod a+r` 开放读取权限 #### 4. 增加目标设备堆内存 - 修改链接脚本(.ld文件),扩大堆空间: ```ld _heap_size = 0x2000; /* 原值加倍 */ ``` #### 5. 验证Semihosting基础功能 测试最小示例(需在调试环境运行): ```c #include <stdio.h> int main() { FILE *f = fopen(":/test.txt", "w"); // 写测试 if(f) { fprintf(f, "Semihosting test"); fclose(f); return 0; } return 1; // 失败 } ``` --- ### **调试建议** 1. 查看调试器日志(如 OpenOCD 输出 `semihosting` 相关错误码) 2. ARM Semihosting 标准错误码: - `0x200001`:文件不存在 - `0x200002`:访问拒绝 3. 使用 **SEGGER SystemView**(引用[1])分析实时系统行为 > 若问题仍存,请提供: > - 调试器类型及版本 > - 完整的错误日志 > - 目标设备型号(如 Cortex-M3/M4) > 这将有助于进一步诊断硬件兼容性或工具链配置问题[^1][^2][^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值