Unit testing 在执行裸机程序后,如何在没有用户干预的情况下干净地退出QEMU?
我正在为ARM系统组装一个交叉编译单元测试平台,并在主机上使用Unit testing 在执行裸机程序后,如何在没有用户干预的情况下干净地退出QEMU?,unit-testing,arm,qemu,bare-metal,Unit Testing,Arm,Qemu,Bare Metal,我正在为ARM系统组装一个交叉编译单元测试平台,并在主机上使用qemu系统ARM运行测试。具体来说,我使用qemu模拟Stellaris LM3S6965评估板,因为它包含一个Cortex M3处理器,就像我的目标环境一样。qemu中的二进制运行是使用用于ARM的GNU工具构建的 没有涉及操作系统。测试套件作为裸机应用程序运行,qemu处于-nographic模式。工具链和试验台本身工作正常。测试成功地运行到完成,并在qemu内产生测试结果 问题在于将qemu封装到一个自动构建工具中(在本例中为
qemu系统ARM
运行测试。具体来说,我使用qemu模拟Stellaris LM3S6965评估板,因为它包含一个Cortex M3处理器,就像我的目标环境一样。qemu中的二进制运行是使用用于ARM的GNU工具构建的
没有涉及操作系统。测试套件作为裸机应用程序运行,qemu处于-nographic
模式。工具链和试验台本身工作正常。测试成功地运行到完成,并在qemu内产生测试结果
问题在于将qemu封装到一个自动构建工具中(在本例中为Rake)。除了键盘命令之外,我还没有找到一种好方法,可以在测试套件运行并输出结果后使qemu退出。这会导致生成环境挂起/依赖于用户干预
我到处寻找,没有找到关于如何在程序终止后完成简单退出的好消息来源。我确实发现了一些建议,建议使用-no reboot
选项运行qemu,然后从模拟器中运行的程序触发系统重置。我试过这个。它起作用了…有点。在执行main()
之后,我将适当的值写入模拟处理器的重置向量,这确实会触发重置。运行测试套件后,qemu报告捕获到系统重置。但是,它将此报告为硬件错误,转储寄存器内容,然后退出(下面的错误消息)。虽然这确实可以在测试套件运行后完成退出,但由于qemu退出时出现错误,因此会中断自动构建脚本
qemu: hardware error: System reset
我希望避免将键盘命令插入构建以模拟用户干预。我还希望避免依赖qemu以错误状态退出
看来我已经接近一个干净的出口了,但还不太清楚。搜索qemu错误消息(如上)除了相关的bug报告外,没有生成任何相关文档
在我丢失的裸机程序中返回
main()
后,是否有机制导致qemu退出?此-无重新启动+系统重置策略是否有效?如果是这样,还需要什么才能让qemu干净地退出?通常,您需要在硬件上执行任何可能导致系统关闭(断电)的操作;QEMU将使其成为“退出QEMU”。不幸的是,并不是我们模拟的所有硬件都实现了断电机制(有时它没有连接到QEMU模型中,尽管这通常是一个很容易修复的错误)。对我来说,最干净的选择是获取接近我们已经使用的QEMU的稳定版本的源代码。以下是Qemu源代码的1.1.2版
我在armv7m\u nvic.c
中修改了Cortex M3+Stellaris LM3S6965评估板重置向量处理的仿真。我将调用hw\u error()
替换为调用qemu\u system\u reset\u request()
。此内部系统调用将重置虚拟机,但也会响应-no reboot
命令行选项以实现完全关闭,如我在原始问题中所述
这些在抓取后对我有用。我遇到了几个构建错误,但web搜索很快解决了每个问题。我建议对ARM处理器使用Angel界面。这对调试非常有帮助。你可以在网上读到一些关于它的东西。特别是查看操作angel\u SWIreason\u ReportException(0x18)和参数ADP\u Stopped\u ApplicationExit,QEMU将理解您的应用程序已结束
不要忘记使用-semihosting参数运行QEMU,如下所示:
qemu-system-arm -nographic -semihosting -kernel your_binary
下面是告诉QEMU停止的代码(您必须使用一些汇编程序):
您也可以在我使用它的地方查看我的项目。aarch64半托管退出
给出了A32,这里是A64:
.global main
main:
/* 0x20026 == ADP_Stopped_ApplicationExit */
mov x1, #0x26
movk x1, #2, lsl #16
str x1, [sp,#0]
/* Exit status code. Host QEMU process exits with that status. */
mov x0, #0
str x0, [sp,#8]
/* x1 contains the address of parameter block.
* Any memory address could be used. */
mov x1, sp
/* SYS_EXIT */
mov w0, #0x18
/* Do the semihosting call on A64. */
hlt 0xf000
以下是GitHub上的一个示例:
文档已移至:当前的ARMv7M qEmu(基于TI Stellaris LM3S6965微控制器)支持从AICRCR寄存器复位()。
写入该寄存器的SYSRESETREQ
位将向外部系统发出请求复位的信号
写入AICRCR
需要将0x5FA
写入VECTKEY
字段,否则处理器将忽略写入操作
该行使ARMv7M qEmu复位
SCB->AIRCR = (0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;
SCB->airr=(0x5FA下面,它使用不同的组件工作,我使用的是zephyr:
及
据我所知,仿真Stellaris LM3S6965 eval board/Cortex处理器没有软件控制的断电选项(典型的嵌入式系统)。唯一接近的是睡眠和低功耗模式。鉴于此,我是被迫在脚本控制下注入键盘命令,还是生活在qemu错误状态/寄存器转储出口中?是否有一种通用方法以某种方式触发qemu系统arm中的断电?以下是aarch64版本:
SCB->AIRCR = (0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;
static inline void _exit_qemu() {
register u32_t r0 __asm__("r0");
r0 = 0x18;
register u32_t r1 __asm__("r1");
r1 = 0x20026;
__asm__ volatile("bkpt #0xAB");
}
qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -vga none -net none -pidfile qemu.pid -serial mon:stdio -semihosting -kernel build/zephyr/zephyr.elf