Semihosting (半主机) 机制

Semihosting 具体来讲是指一种让代码在ARM 目标上运行,但使用运行了 ARM 调试器的主机上I/O 设备的方法;也就是让ARM 目标将输入/ 输出请求从应用程序代码传递到运行调试器的主机的一种机制。通常这些输入/输出设备包括键盘、屏幕和磁盘I/O。半主机由一组已定义的SWI 操作来实现。库函数调用相应的SWI(软件中断),然后调试代理程序处理SWI 异常,并提供所需的与主机之间的通讯。

大家经常遇到的bug:

http://www.icdev.com.cn/?action-spacelist-uid-5-type-blog-starttime-1210204800-endtime-1210291200.html

 

semihost 仅仅是一种调试手段,它的机理就是利用MULTI_IDE等工具捕捉目标环境运行过程中产生的值为0x123456的SWI中断,然后向上位机的ADS 软件发送对应的调试信息。对于我们最后的应用代码来说,都是nonsemihost类型的。如果我们在调试中使用semihost,那么只要在最后重定义 ADS中的一些使用到的库函数(比如fputc),代码就可以从semihost向nonsemihost的类型转变。

转]以太网驱动芯片终于调通了!

前些日子把ADS的C函数库调通了,可以使用丰富的库函数了。调试的关键如下:
__user_initial_stackheap()是C函数库初始化时必须调用的一个库函数,该函数的作用是设置堆指针和栈指针,而该该函数会涉及到swi。可在semihost中配置一个参数,当swi发生时semihost或将该参数传给target作为栈指针。如果要让代码脱离semihost,则必须处理该swi。不过__user_initial_stackheap()可以被重载,并且ADS在链接时会使用重载的该函数,而不管它自己提供的缺省实现。这样在重载了该函数后,C函数库的初始化顺利完成。娃哈哈~~

刚才又把以太网驱动芯片CS8900调通了,看到了芯片的ID--0x630e。昨天一整天调整2410与8900之间的读写时序,硬是出不来,还怀疑板子上的片子坏了。今天把8900的DataSheet和板子的原理图看了又看,终于搞清楚了它的访问逻辑。可是上板一试,数据还是出不来。后来又是调啊调啊,终于在动了唯一一个我弄不清楚的管脚的配置后,数据终于出来了。娃哈哈~娃哈哈~到此为止,东风已经完全具备。后面就是上uCos和TCP/IP协议栈了。娃哈哈~忍不住还要笑~~~



[转]今天纯翻译,浪费时间了。

半主机模式

这一章描述半主机模式机构。半主机模式提供的代码在运行ARM debugger时将主机电脑的部件灵活的应用到ARM

目标中(中国人不懂了吧,放心外国人也不会明白的)。例如工具包括:键盘输入,屏蔽输出和磁盘的输入输出这一章包括下列部分:
1 半主机
半主机是为了在运行调试时主机电脑与ARM输入输出通信的一个机构。这个机构可以这样使用,例如允许运行C语言库类似printf和scanf,用于屏蔽和主机键盘甚至有一个屏蔽和键盘在目标系统上。这个机构的好处在于硬件不用拥有全套的输入输出设备,这个机构允许主机电脑提供这些工具。
Semihosting 是通过设置软件中断来实现的。这个应用调用了适当的软件中断和易于操作的软件中断的向量。

这个代理调试提供了与主机必须的通信。在很多案例中,semihosting的软件中断被库函数代码调用。在应用中总是直接调用semihosting软件中断。涉及到编译器中的C语言库的描述和向导库有更多的信息提供对semihosting的支持。semihosting软件中断通常被ARM的代理调试所保护。semihosting可以运行在 ARMulator,

RealMonitor, Angel, or Multi-ICE 模式不需要任何设备。关于半主机在C语言库的进一步信息参看相关文档


1.1 软件中断接口
ARM和Thumb的软件中断指令包含了软件中断所要应用代码的编码信息。这个编码能够被系统中软件中断管理服务解码。关于软件中断管理服务更多的信息请看相关文档。半主机运行是被一个独立的软件中断号所请求的。

他区别于别的软件中断号是用来应用或者运行系统的。这个中断号是:
0x123456(ARM模式)
0xab(Thumb模式)
这个中断号表明这次软件中断是半主机的要求。为了区别于别的操作,这个运行通过R0。所有其它的参数通过R1。运行的结果返回到R0不管是一个直接的值还是一个指向数据块的指针,甚至没有返回结果,R0会被破坏。
可用的通过R0传递的半主机运行号如下:
0x00 to 0x31(ARM使用)
0x32 to 0xFF(保留为以后ARM使用)
0x100 to 0x1FF(保留为用户应用不会被ARM应用到)
如果你写自己的软件中断运行代码你要使用不同于半主机用的软件中断号它的典型值如下
0x200 to 0xFFFFFFFF(这些是未定义的)
这些不经常使用到,不推荐用户使用
在下列情况下运行号的值以运行名称的方式进入R0例如SYS_OPEN (0x01).
如果你调用软件中断使用汇编语言最好在运行名称,在semihost.h中声明你可以用EQU定义例如:
SYS_OPEN    EQU 0x01
SYS_CLOSE   EQU 0x02
改变半主机软件中断号:
如果不是必要建议不要改变如果一定要改变你需要:
改变你系统的所有代码包括库代码为新的中断号
重新装载你的调试来使用新的SWI号。
2 半主机执行
半主机的功能性与所有调试主机基本上是一样的。但是执行方式却是不同的。
2.1 ARMulator模式
当遇到半主机SWI,ARMulator立即响应SWI进入SWI指令的向量表但不执行。要让ARMulator支持需要改变

Default_Semihost in the default.ami file to No_Semihost.更多细节参看 Peripheral models
2.2 RealMonitor模式
RealMonitor执行一个SWI管理服务它让你的系统可以被半主机支持。当执行半双工SWI指令RealMonitorSWI管理服务完成与主机通信的请求。进一步的说明参看相关文档。
2.3 Angel模式
Angel模式在目标上电时装载了管理服务,给服务可以完成与主机的通信需求。
2.4 Multi—ICE模式
当使用Multi—ICE默认配置时半主机执行如下:
在ARM7处理器
a)在SWI向量处增加一个断点
b)当断点被触发Multi—ICE检查SWI号
c)如果SWI是半主机的Multi—ICE模仿重新启用应用。如果不是Multi—ICE就会停止处理器响应错误。
在其它处理器
a)捕捉SWI
b)如果SWI是半主机的Multi—ICE模仿重新启用应用。如果不是Multi—ICE就会停止处理器响应错误。
这个半主机机构可以被禁止或改变通过下列调试器的内部变量:
$semihosting_enabled
设置值为0是禁止半主机,如果你调试的应用在ROM,这个设置允许你应用一个额外的观察点
设置值为1允许半主机,这是默认的。
设置值为2可以确认半主机调试的信道。
除非半主机被禁止否则$vector_catch的S位不受影响。
$semihosting_vector
这个变量控制通过Multi-ICE 直接控制SWI设置的断点区域。他设置SWI默认异常向量表入口。
你应用半主机的请求就像自己的SWI服务一样设置$semihosting_vector给一个SWI服务的地址。如果你的SWI服务鉴定这是一个调用半主机的SWI则这个地址必须指向唯一的执行指令。无论进入你的SWI服务的值是多少所有的寄存器必须已经被恢复了。
Multi-ICE操作SWI和检查LR使软件中断返回你的代码。
无论$vector_catch的值如何,所有的异常和中断都会被捕获和响应就像一个错误条件一样。
更多的细节参看相关文档。
2.5 Multi-ICE DCC semihosting
Multi-ICE 能够用调试信道以至于内核在半主机占用时不会停止,可以设置$semihosting_enabled为2,更多细节参看用户手册。
3 添加一个SWI应用管理器
它对于半主机的SWI和你自己的专用SWI的实现都是有用处的。前提是你必须保证两个SWI机构能够正确地协同工作。这种方法依靠代理调试应用。
3.1 ARMulator模式
要让你自己的管理器与半主机的管理器协同工作,只需要简单的将你的SWI管理器放到SWI向量表中,没有其它的需求。
当一个适当的SWI在你的代码中ARMulator会分辨出它的指向进入响应的管理器。
3.2 RealMonitor模式
RealMonitorSWI服务器必须在你的应用中确认半主机被综合。(看相应文档)
3.3 Angel模式
应用SWI服务要添加:保存SWI向量、调整SWI向量使它指向SWI应用服务(更多细节看相应文档)
3.4 Multi—ICE模式

3.5 Multi-ICE DCC semihosting
当使用DDC半主机机构添加SWI应用服务必须向非DDC半主机模式一样正确
4 半主机SWIs (终于到有用的了)
SWIs在表5.1中列出执行半主机运行。这些运行被用来执行C函数库类似于printf()和scanf()他们被加工象调用ATPCS函数一样。R0作为返回值。表5.1如图所示:


4.1 SYS-OPEN(0X01)
打开主机系统一个文件。文件路径是被指定的无论与主机当前运行的相关联的目录还是完全目录,使用主机操作系统规定的路径。
ARM的目标中断有专门的路径名:tt意味着控制台的输入流(打开读)或者控制台的输出流(打开写)。打开这些流完成任务就像标准启动代码中涉及C语言stdio流。
入口
在入口处R1包含一个指向三个字的结构块
word1 这个指向一个文件包含串的终结或者设备名。
word2 这是一个整数详细说明了文件打开的模式表5.2提供了关于这个整数的值,它对应于ANSIC的fopen()模式。
word3 这是一个整数给出word1所指向串的长度。这个长度不包括结尾符号必须对准。


返回
返回R0:如果成功则返回一个非0的句柄,如果失败返回-1
4.2 SYS-CLOSE(0X02)
关闭主机系统的一个文件。句柄必须参考被SYS-OPEN打开的文件入口
R1包含一个指向一个配置块的指针
word1 一个指向打开文件的句柄
返回
返回R0:如果成功返回0,如果失败返回-1
4.3 SYS-WRITEC(0X03)
写入一个由R1指向的字符到调试通道。当在ARM调试下实现,这个字符会出现在与调试器相连接的显示设备上。
入口 R1包含的指针指向的字符
返回 没有返回值R0被破坏
4.4 SYS-WRITE0(0X04)
写一个带停止符的串到调试通道。当在ARM调试下实现,这个字符会出现在与调试器相连接的显示设备上。
入口 R1包含的指针指向的第一个字符
返回 没有返回值R0被破坏
4.5 SYS-WRITE(0X05)
写缓冲区的内容到一个指定的文件,指定这个文件可以是明确的(SYS-SEEK),也可以是隐含再上一级菜单的一个字节SYS-READ或者SYS-WRITE的请求。当文件打开时文件的地址在文件的开头,在文件关闭的时候释放。
只要可能完成文件的操作就像一个单独的动作一样。(意思是要全部的完成看作一个文件)例如不能分割一个16KB的文件为4个4KB块除非迫不得已。
入口 R1包含指向3个字的数据块
word1 它包含一个由SYS-OPEN打开的文件的句柄
word2 它指向要写入数据的内存
word3 它包含要从缓冲区写入数据的长度
返回 如果成功则返回0,如果失败则没有字节被写入。
4.6 SYS-READ(0X06)
读一个指定文件的内容到缓冲区,指定这个文件可以是明确的(SYS-SEEK),也可以是隐含再上一级菜单的一个字节SYS-READ或者SYS-WRITE的请求。当文件打开时文件的地址在文件的开头,在文件关闭的时候释放。
只要可能完成文件的操作就像一个单独的动作一样。(意思是要全部的完成看作一个文件)例如不能分割一个16KB的文件为4个4KB块除非迫不得已。
入口 R1包含指向3个字的数据块
word1 它包含一个由SYS-OPEN打开的文件的句柄
word2 它指向缓冲区
word3 它包含要读入缓冲区数据的长度
返回 如果成功则返回0,如果R0的值与word3一致则认为是失败了或者认为到了文件结束。如果R0比word3的值大则认为部份成功,假设没有错误但缓冲区没有被填充。
如果句柄是一个交互式的设备,一个非0的返回值表示读入的值没有填满缓冲区。
4.7 SYS-READC(0X07)
从控制台读取一个字节
入口 寄存器R1必须是0,没有其它参数会可能的值
返回 R0是从控制台读取的字节
4.8 SYS-ISERROR(0X08)
确定另一个半主机指令的返回值是否正确。这个调用检查调用块的参数。
入口 R1指向一个字的数据块
word1 核查必须的状态字
返回 如果没有错误则返回0,返回非0则代表状态字是错误的
4.9 SYS-ISTTY
检查一个文件是否连接一个交互设备
入口 R1指向一个一个字的配置块
word1 指向一个以前打开过的文件
返回 如果返回1则认为是一个交互设备,如果返回0则认为是一个纯文件,如果都不是则是由错误发生。
4.10 SYS-SEEK(0X0A)
利用一个指定的相对于文件头的偏移量寻找文件中指定的位置。文件假定一个字节阵列和一个字节的偏移
入口 R1指向一个两字的数据块
word1 一个指向可搜寻的文件对象的句柄
word2 搜寻过的一个字节的绝对地址
返回 如果需求成功则返回0,返负值则认为失败。SYS-ERRNO能被用来从主机读取一个值errno变量描述了错误
4.11 SYS-FLEN(0X0C)
返回一个指定文件的长度
入口 R1指向一个一个字的配置块
word1 一个指向以前打开过的可搜寻的文件的句柄
返回 如果成功则返回文件对象的长度,返回-1表示有错误发生。
4.12 SYS-TMPNAM(0X0D)
返回一个被系统文件识别系统临时识别用的文件名
入口 R1指向一个三字的配置块
word1 指向缓冲区的指针
word2 是一个识别这个文件名的目标识别器,值是一个0到255的整数
word3 包含了缓冲区的长度。这个长度最短是L_tmpnam在主机系统中的值
返回 成功则返回0,失败则返回-1
R1指向的缓冲区中文件名是一个与目录名相匹配的,如果你用了相同的识别器则返回的文件名是相同的
4.13 SYS-REMOVE(0X0E)
在主机归档系统中删除一个指定的文件
入口 R1指向一个二字的配置块
word1 指向一个要删除的带终止符文件的路径名
word2 是这个串的长度
返回 成功则返回0,否则返回非0
重命名一个指定文件
入口 R1指向一个四字的数据块
word1 指向旧的文件名
word2 旧文件名的长度
word3 指向新的文件名
word4 新文件名的长度
所有的串有终止符
返回 如果成功则返回0,否则返回非0
4.15 SYS-CLOCK(0X10)
返回厘秒 (略)
入口 R1为0
返回 如果成功则返回从任意指定开始点开始的时间,否则返回-1
4.16 SYS-TIME(0x11)
返回从1970年1月1日00:00开始到现在的时间,不管ARMulator任何配置
入口 没有参数
返回 秒数
4.17 SYS-SYSTEM(0X12)
建立一个主机命令行的解释程序,它允许你执行系统命令如dir,is或者pwd,访问主机的终端IO和不可见的目标。这个命令在主机上通过主机实际执行。确信任何命令不会有无意义结果。
入口 R1指向一个二字的配置块
work1 指向一个通过主机命令行的解释程序的串
work2 这个串的长度
返回 返回状态
4.18 SYS-ERRNO(0X13)
返回C库errno变量的值通过主机执行的半主机的SWIs,errno变量可以通过半主机的C库的数字设置包括SYS-REMOVE;SYS-OPEN;SYS-CLOSE;SYS-READ;SYS-WRITE;SYS-SEEK无论errno是否被设置或者被设置成什么数,他都是完全的主机细节除了在ANSIC标准中定义的行为
入口 R1必须为0
返回 errno变量的值
4.19 SYS-GET-CMDLINE(0X15)
返回调用执行的命令行
入口 R1指向一个二字的数据块
word1 指向缓冲区至少要有2字节的空余
word2 缓冲区字节的长度
返回 在R1中有二个字的数据块
word1 指向带有终止符的命令行
word2 串的长度
 在R0中成功则返回0;否则返回-1
4.20 SYS-HEAPINFO(0X16)

4.21 SYS-ELAPSED(0X30)

4.22 SYS-TICKFREQ(0X31)

5 调试用SWIs
在额外的半主机的C语言库中提供一些用于调试代理命令。在返回异常SWI,这个SWI通过半主机提供的代码应用就像一种调试异常的方式。进入管理SWI,SWI设置处理器到管理模式。启动原因SWI 这个SWI是陈旧的不再提供支持的。这些将在下面描述
5.1 angel-SWIreason-EnterSVC(0x17)
设置处理器进入管理模式,在新的CPSR中屏蔽中断。在RealMonitor, Angel, or Multi-ICE中用户堆栈指针复制到管理模式中的堆栈指设置当前CPSR终止普通和快速中断。
提示:如果在ARMulator中R0设置为0标志没有函数可以用则返回用户模式,用户模式中的堆栈指针不会复制到

管理模式的堆栈指针
入口 R1没有用,CPSR可以指定用户或管理模式
返回 R0包含返回用户模式被调用函数的地址,该函数用以下原型
void ReturnToUSR(void)

5.2 angel-SWIreason-ReportException(0x18)(这也就是常要遇到的东西,我这次寻找答案的原因)
这个SWI可以在应用中被调用用来立即响应调试的异常现象。最常用来表达执行完成(也就是我们经常看到的)
使用ADP_Stopped_ApplicationExit.
入口 R1是在5.3和5.4表中的值,这些值定义在adp.h
硬件异常发生在调试变量 $vector_catch变量设置成捕捉异常模式,代理调试有能力报告异常的类型Angel模式

在自己的向量中不能报告中断异常。5.3如图:

除非操作者在操作结束的时候能使用这些SWIs就像默认动作一样,来显示这些除非根本就没有句柄
5.4如图:


图片中有*的值在ARM调试中没有支持
返回 没有返回值
5.3 angel-SWIreason-LateStartup(0x20)
这个SWI被废止了。

 

 

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值