ARM 之十九 详解 Semihosting、SWO 以及在 MDK-ARM、IAR、Eclipse、SEGGER-ES 的使用

news2024/11/24 6:27:19

  在嵌入式系统开发中,我们通常会将标准输入输出作为一个控制台功能添加到我的嵌入式应用程序中。这样我就有了一个命令行接口,可以检查和修改目标系统。在 ARM 架构中,Semihosting 和 SWO 是经常会遇到的两个概念,在调试输出方面也是用的非常多的,今天就来学习一下!

Semihosting

  Semihosting 是嵌入式芯片中提供一种机制,它使在嵌入式芯片上运行的固件代码可以使用主机计算机的 I/O(与主机计算机的 I/O 进行通信)。在此技术之下,目标芯片上固件程序中的 printf 就可以直接输出到 PC 显示器,目标芯片上固件程序中的 scanf 就可以直接接收从 PC 键盘上的输入。

工作原理

  Semihosting 的基本实现方法是通过在固件代码的某个点使用某种类型的断点指令或者模式切换(legacy ARM 或 Cortex A/R 的 supervisor 模式)来停止目标程序的运行然后与调试器进行通信来实现的。
在这里插入图片描述

  1. 目标 CPU 通过进入断点指令或其他某些操作来停止程序执行并将目标 CPU 控制在调试仿真器(例如 J-Link)或调试器(例如 GDB、集成在 IDE 中的调试器)的控制之下。

    通常由编译器对应的 C 库中相关函数实现,发送 Semihosting 请求

  2. 调试仿真器或调试器读取一个或多个寄存器以确定主机代表目标执行的操作类型,然后执行操作,然后重新启动目标芯片上的程序运行。

    调试仿真器或调试器需要实现对各种 Semihosting 请求的响应

  需要注意的是,Semihosting 仅在调试状态下才可以正常使用,如果是发布程序,则通常需要显示将 Semihosting 禁用,否则,可能会由于无法正确处理 Semihosting 的请求进而导致程序运行异常!

历史

  术语 Semihosting 最初是由 ARM 在 1990 年代初期提出的,该技术实现部分功能由主机(运行调试工具的 PC)执行,部分由目标芯片(开发板)执行。最初的设计目的是在根本没有真正基于外设的 I/O 的目标环境中提供 I/O。

  Semihosting 这种技术并不是什么新鲜事物,它已经在嵌入式系统中使用了几十年。开发工具领域的大多数公司都开发了自己的 Semihosting,基本上都遵循停止目标处理器的相同想法(通常是让它运行到一个断点)。然而,各家的实现没有互操作性,因为没有标准,直到 ARM 为其处理器定义了相关标准,并采用了 Semihosting 这个术语。

ARM 规范

  Semihosting 是通过一组定义的软件指令来实现的,这些指令会从程序控制中产生异常。使用 A64、 A32 和 T32 指令集的 A 和 R profiles 以及使用 T32 指令集的 M profiles 均支持 Semihosting 技术。Semihosting 操作是使用 Trap Instructions 来发送请求,Semihosting 的 Trap Instructions 和编码表如下所示:
在这里插入图片描述
  Semihosting 的实现必须支持 ARM 架构中该指令的所有版本。对于使用 A32 和 T32 指令集的 A 系列以及 R 系列而言,可以使用 SVC 指令和 HLT 指令。尽管 HLT 指令在 ARMv8 中被定义,但是在 ARMv7 以及更早的版本中也可以使用,当然,这可能需要 Semihosting agent 把它当作 UNDEF 异常来处理。

  • 在 AArch32 架构下,应用程序通过使用 SVC(SWI)指令并携带一个特定的 SVC number,来触发一个异常,从而实现一个 Semihosting 请求。

    • 在 ARMv7 中(如 ARM7、 ARM9、 ARM11),优先使用 SVC 指令,早期称为 SWI。
    • 在 ARMv6-M 或者 ARMv7-M,比如 Cortex-M1 或 Cortex-M3 ,则使用 BKPT 指令来产生 semihosting 请求。
  • 在 AArch64 架构下,应用程序使用 HLT 指令,并携带一个常数 0xF000 来创建一个 Semihosting 请求,但是它不会产生异常。

最新版 ARM 的 Semihosting 标准下载 Semihosting for AArch32 and AArch64.pdf

  ARM 鼓励在目标芯片测程序中实现 A32 和 T32 指令集 中的 HLT 指令作为 Semihosting 的可配置选项。ARM 强烈反对目标芯片测程序中混合使用 HLT 和 SVC 机制。

  各种 Semihosting 操作的参数或者返回值的传递由特定的寄存器来实现,一些 Semihosting 操作在 32 位和 64 位版本之间还有其他不同之处。如下所示:
在这里插入图片描述

  • OPERATION NUMBER REGISTER:包含要执行的 Semihosting 操作的数目

    W0 寄存器仅使用低 32 位

  • PARAMETER REGISTER:包含 Semihosting 操作使用的参数。对于大多数操作,PARAMETER REGISTER 必须包含一个指向保存参数的数据块的指针。在某些情况下,直接在 PARAMETER REGISTER 中传递单个参数,或者根本不传递任何参数。

  • RETURN REGISTER:结果以显式返回值或指向数据块的指针的形式在 RETURN REGISTER 中返回。某些操作也通过 PARAMETER REGISTER 返回信息

  现在,Semihosting 操作码的定义如下:0x00-0x31 由 ARM 使用;0x32-0xFF 由 ARM 保留给未来扩展;0x100-0x1FF 可用用户自定义;0x200-0xFFFFFFFF 未定义,当前未使用。当前 ARM 定义的操作码如下所示:
在这里插入图片描述

旧规范中的操作码 0x17(angel_SWIreason_EnterSVC)和 0x19(angelSWI_Reason_SyncCacheRange)现在被保留

使用

  大多数情况下,Semihosting 请求是由 C 库函数中的代码调用的,同时各大 IDE 都对 Semihosting 提供了支持(响应 Semihosting 请求),我们只需要在 IDE 中启用即可。当然我们自己的应用程序也可以直接调用/实现 Semihosting 操作(ARM 建议自己实现时自定义所有操作码,不要标准 + 自定义混用)。

IAR(EWARM)

  IAR 的编译器使用的 C 库官方称为 DLIB,DLIB 运行时库被设计成通过一小组简单的功能来执行所有的 I/O 操作,这些功能被称为 DLIB 低级 I/O 接口。在默认情况下,很多 DLIB 低级 I/O 接口是没有被实现的,而标准输入输出则默认被实现为 Semihosting 模式。
在这里插入图片描述
  IAR(EWARM)的调试器(官方名称为 C-SPY)支持由 C-SPY 模拟 I/O。这样当 DLIB 库中的相应函数发出 Semihosting 请求时,C-SPY 就会读取到相关信息,进而传递到 C-SPY 模拟 I/O,而 C-SPY 模拟 I/O 实际就是和 Terminal I/O 这个界面交互的,这也就实现了和用户进行交互。
在这里插入图片描述
  要启用 C-SPY 模拟 I/O,只需要打开 Project ➔ Options ➔ General Options ➔ Library Configuration 页面,然后在 Library low-level interface implementation 中选择 Semihosted 或 IAR breakpoint 即可,然后就可以在 IAR 的 Terminal I/O 中进行输出输出了。

MDK-ARM

  MDK-ARM 不支持 Semihosting,我们只能自己进行重定义来实现调试跟踪输出。但是,ARM 编译器的 C 标准库(StandardLIB)则默认是支持 Semihosting(其中的标准输入输出默认就实现为 Semihosting 模式)。

ARM 编译器的 MicroLIB 本身不支持 Semihosting,如果使用 MicroLIB ,只能选择自己重定向 I/O

  我这里先使用 MDK-ARM 编译出可执行程序(.axf),然后使用 SEGGER 的 Ozone 进行调试来进行简单验证(如下配置中选择 User input via terminal window,不过貌似 Ozone 的处理有些问题,输入一次就会一直有效):
在这里插入图片描述

Eclipse 系

  Eclipse 系大都使用的是 GCC 作为编译工具链,而调试则使用的是 GDB,而对应的 C 标准库则由 GCC 的供应商决定。但是,大多数情况下,目标芯片裸机编程就是使用 Newlib 这个 C 库,目标芯片 Linux 系统编程则使用 glibc 这个 C 库。

  我使用编译工具链是 Arm GNU Toolchain(arm-none-eabi-gcc) 的 11.3.1 版本,Arm GNU Toolchain 使用的 C 库就是 Newlib。根据官方文档,如果需要支持 Semihosting 则必须添加 --specs=rdimon.specs 这个链接器选项;如果不需要 Semihosting 或者需要自己进行重定向,则必须使用 --specs=nosys.specs 这个链接器选项。

  1. 添加 --specs=rdimon.specs 这个链接器选项。Eclipse 的 UI 配置界面并没有这个选项,只能自己添加
    在这里插入图片描述
    实际上,该操作会链接 libc.a(Newlib 主库) 和 librdimon.a(libgloss 库的一部分) 中相应的实现
  2. 在自己的代码中显示启用 Semihosting 处理函数 initialise_monitor_handles,否则将收到 WARNING: Semihosting command SYS_FLEN failed. Handle is 0. 这个错误提示!
    在这里插入图片描述
  3. 调试配置中开启 Semihosting 支持。我这里使用的是 J-Link,其他调试仿真器的设置类似。
    在这里插入图片描述
  4. 启动调试,就可以在 Console 界面中接收或者输入数据了。注意需要切换合适的 Console 通道!
    在这里插入图片描述

SEGGER Embedded Studio

  SEGGER 定义了一套自己的名为 SEGGER Semihosting 的 Semihosting 标准,并与 ARM 定义的旧标准兼容,相关源码可以从官网下载。SEGGER Embedded Studio 调试器完全支持 SEGGER Semihosting 标准,而且其 C 标准库(官方名为 emRun)中默认情况下就启用了 Semihosting 支持。
在这里插入图片描述
  SEGGER Embedded Studio 的 Semihosting 实现还包括主机格式化输出功能。对于目标芯片上的格式化的输出,比如通过 printf () ,目标芯片上的程序不必在 RAM 中构造格式化的字符串。相反,格式字符串通过 Semihosting 传递给 Embedded Studio,Embedded Studio 解析它并从目标中读取参数,从而节省了目标芯片资源。

  1. https://wiki.segger.com/SEGGER_Semihosting
  2. https://wiki.segger.com/Semihosting

SWO

  SWO(Serial Wire Output)是 ARM 制定的 Serial Wire Debug(SWD)的一个扩展,但是并不是所有支持 SWD 的 ARM 核心都支持 SWO。而 SWD 又是 ARM 公司 Cortex-M CoreSight 组件的一部分。CoreSight 是 ARM 设计的用于芯片内部的调试及跟踪的组件。
在这里插入图片描述

  • Arm Debug Interface(ADI):定义了嵌入式 SoC 中调试组件的接口。
  • Serial Wire Debug (SWD):SWD(Serial Wire Debug)是由 ARM 公司设计的用于编程和调试 Cortex 系列微控制器的协议。SWD 协议定义了 2 个引脚,在体系结构方面支持星型拓扑。
  • ARM 处理器实时跟踪宏单元(ETM,PTM,STM)体系结构
  • High Speed Serial Trace Port (HSSTP) 体系结构将串行传输端口(STP)定义为替代现有的并行数据输出端口。它适合于在芯片外传输高带宽数据,例如来自 CoreSight 解决方案的数据。
  • 调试访问端口(Debug Access Port,DAP):这是 ARM Debug Interface version 5.1(ADIv5.1)的一个实现,该版本包含在单个配置中提供的许多组件。所有提供的组件都适用于 Debug Ports (DP) 的各种体系结构组件,这些组件用于从外部调试器和 Access Ports (AP)访问 DAP,以访问片上系统资源。

  Arm Cortex-M 的 DWT 和 ITM 核心外围设备生成的数据包可以在发生可配置的事件集时通过 SWO 输出。通过 SWO 传输的 DWT/ITM 数据包的组合称为串行有线查看器(Serial Wire Viewer,SWV)。SWV 的一个常见用例是 printf 样式的日志输出,以至于 SWV 或多或少就是这个意思。
在这里插入图片描述
  SWO 支持两种有线协议,异步 UART 和曼彻斯特编码,尽管在实践中几乎只使用 UART。(SWO 也可以作为独立的 CoreSight 组件使用,但这种情况相对较少)

参考

  1. https://blog.csdn.net/luolaihua2018/article/details/127344891
  2. https://interrupt.memfault.com/blog/arm-semihosting
  3. https://wiki.segger.com/Semihosting
  4. https://mklimenko.github.io/english/2018/11/02/disable-semihosting/
  5. https://docs.parasoft.com/display/CPPDESKE1033/Runtime+Testing+with+Keil+MDK-ARM+Support
  6. https://www.keil.com/pack/doc/compiler/RetargetIO/html/_retarget__overview.html
  7. https://mcuoneclipse.com/2014/09/11/semihosting-with-gnu-arm-embedded-launchpad-and-gnu-arm-eclipse-debug-plugins/
  8. https://www.cnblogs.com/foxclever/p/7787083.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2212594.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python+appium+雷电模拟器安卓自动化及踩坑

一、环境安装 环境:window11 1.1 安装Android SDK AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 这里面任选一个就可以,最终下载完主要要安装操作安卓的工具adb,安装这个步骤的前提是要…

MarsCode--字符串有多少种可能性【简单】

问题描述 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数&#x…

[翻译]MOSIP Blue Book

目录 Preface(前言) Executive summary(执行摘要) 1 Introduction(介绍/序言) 1.1 Principles on Identification(识别原则) 1.2 Need for a Foundational ID(需要基…

【Java进阶】Java进阶-手撕java agent

文章目录 Java Agent一、定义与工作原理二、主要特点三、应用场景四、使用注意事项 Java Agent相关接口1. Instrumentation接口2. ClassFileTransformer接口3. 其他相关类和接口 手写一个Java Agent1. 编写Java Agent代码2. 编写MANIFEST.MF文件3. 编译代码并打包成JAR文件4. 运…

JavaWeb——Maven(2/8):概述-介绍安装(步骤、具体操作、测试)

目录 介绍 安装 步驟 具体操作 测试 主要讲解两个方面:Maven的介绍以及Maven的安装。 先来介绍一下没问当中的一些概念和模型。 介绍 Apache Maven是一个项目管理和构建工具,它基于项目对象模型(POM:project object model…

Java | Leetcode Java题解之第477题汉明距离总和

题目&#xff1a; 题解&#xff1a; class Solution {public int totalHammingDistance(int[] nums) {int ans 0, n nums.length;for (int i 0; i < 30; i) {int c 0;for (int val : nums) {c (val >> i) & 1;}ans c * (n - c);}return ans;} }

基于Flink+Hologres搭建实时数仓

Apache Paimon是一种流批统一的数据湖存储格式&#xff0c;结合Flink及Spark构建流批处理的实时湖仓一体架构。Paimon创新地将湖格式与LSM技术结合起来&#xff0c;给数据湖带来了实时流更新以及完整的流处理能力。借助实时计算Flink版与Apache Paimon&#xff0c;可以快速地在…

多人播客的生成#使用OpenAI Swarm框架

使用Swarm来写多智能体的代码&#xff0c;非常简洁高效。 什么是Swarm&#xff1f; Swarm是由OpenAI开发的一个实验性多代理系统框架&#xff0c;旨在探索多代理系统的高效接口。该框架注重轻量级、可控性高且易于测试&#xff0c;主要用于展示代理之间的交接与例行操作模式。S…

多智能体协同太复杂?OpenAI Swarm让问题迎刃而解

OpenAI Solutions团队最新推出的实验性框架Swarm正在为AI领域带来新的可能性。这个专为构建、编排和部署多智能体系统而生的轻量级工具集&#xff0c;正在改变我们处理复杂任务的方式。 Swarm框架的核心理念是让多个AI代理&#xff08;Agent&#xff09;协同工作&#xff0c;每…

基于SSM+Vue+MySQL的少儿编程网上报名系统

系统展示 用户前台界面 管理员后台界面 系统背景 在当下&#xff0c;随着国家对教育的重视以及教育部门对教育改革的不断推进&#xff0c;少儿编程教育逐渐成为了一个热门领域。传统的少儿编程报名方式往往依赖于线下填写纸质表格或电话报名&#xff0c;这种方式不仅效率低下&a…

群晖使用frpc连接qbittorrent时会出现Unauthorized

跨域问题&#xff1a; 如果你是通过不同的网络或子网访问 qBittorrent Web UI&#xff0c;可能会引发跨域问题。尝试在 qBittorrent.conf 中添加以下设置&#xff0c;允许跨域访问&#xff1a; find / -name qBittorrent.conf WebUI\HostHeaderValidationfalse 成功

【机器人数值优化】数值优化基础(一)从理论到实战全方位指南 | 解锁机器人技术的核心技能

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

一文简述工程项目管理中的最常见概念

蓝燕云https://www.lanyancloud.com/致力于为工程行业中各类企业和组织提供专业、简单、可靠的工程项目管理系统&#xff0c;专注于提升企业对于项目管理中成本、进度、质量、安全、资料等全场景管理能力。 01 怎么理解工程项目管理&#xff1f; 建设工程项目管理指的是专业…

神经网络模型的“扩散与进化”思想启迪

在上一篇笔记「上交大全华班复现o1旅程式学习下的深思考」中&#xff0c;其中对于上交大提出的旅程学习即system2慢思考认知范式下对于“多步骤的隐式到显式空间状态映射下的细粒度联合概率分布建模”的描述隐喻为“社会心理学或社会经济学两种不同的长程动态系统慢演化现象”。…

Java之lambda

目录 lambda 引入 语法 函数式接口 lambda表达式的使用 语法精简&#xff1a; 代码示例&#xff1a; 变量捕获 局部变量捕获 成员变量捕获 lambda在集合中的使用 lambda的优缺点 lambda 引入 Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表…

设计模式-原型模式(克隆、Clone、Prototype)

原型模式&#xff08;克隆、Clone、Prototype&#xff09;是一种创建型设计模式&#xff0c; 使你能够复制已有对象&#xff0c; 而又无需使代码依赖它们所属的类。 问题 譬如美国研制了一种特效药&#xff0c;而且还在专利保护器内&#xff0c;而印度制药公司看中了&#xff0…

常见开源组件的详解

文章目录 RPCRPC架构和工作流程为什么有了HTTP还要用RPC底层协议数据格式连接管理错误处理 使用场景常见的RPC框架 Web应用框架主要功能常见的Web应用框架Spring Boot (Java)Django (Python)Express.js (Node.js) Redis主要特点应用场景缓存问题Redis集群架构主从复制Redis Clu…

【算法】笨小猴

[NOIP2008]笨小猴_牛客题霸_牛客网 【描述】 eg1中&#xff0c;输入“error” “e”出现了1次&#xff0c;“r”出现了3次&#xff0c;“o”出现了1次 最大是3&#xff0c;最小是1&#xff0c;3-12&#xff0c;2是质数&#xff0c;所以输出“Lucky word”和这个单词 eg2中&…

【Oracle数据库进阶】003.SQL基础查询_增、删、改数据

课 程 推 荐我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448;入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448;虚 拟 环 境 搭 建 &#xff1a;&#x1…

【基于ARM深入分析C程序】1--ARM架构与汇编、分析C语句`a++`的执行过程

【基于ARM深入分析C程序】1–ARM架构与汇编、分析C语句a的执行过程 文章目录 【基于ARM深入分析C程序】1--ARM架构与汇编、分析C语句a的执行过程一、3个操作指令二、CPU是怎么知道执行这三条操作指令的&#xff1f;2.1 CPU的架构 2.2 寄存器 本文作为学习笔记&#xff0c;围绕的…