背景
虽然qemu
的仿真功能很强大,但是原始的 qemu 并没有仿真板子的功能。而为了仿真裸板,可以使用它的分支 GNU MCU Eclipse QEMU (包含了这个工具qemu-system-gnuarmeclipse
)来做这个事情。
CubeMX 可以生成 Makefile 项目,我们可以基于这样的结果来进行QMEU仿真。我们以 STM32F429I-DISC1 为例,刚好在 2边的工具都有这个板子的型号。
STM32 Cube :v5.6
MCU : STM32F429I-DISC1
LIB : stm32cube_fw_f4_v1250
QEMU: qemu-system-gnuarmeclipse_v2.8.0 win_x64版本工具下载 、linux_x64版本工具下载
Ubuntu:gcc : arm-none-eabi-gcc_v4.9.3 20150529
Windows:
MDK : Keil 5
准备
下面以 Ubuntu 为例。
工具的下载以及配置
下载工具:下载地址
wget https://github.com/xpack-dev-tools/qemu-arm-xpack/releases/download/v2.8.0-8/xpack-qemu-arm-2.8.0-8-linux-x64.tgz
配置工具到$PATH
中:export PATH=$PATH:实际路径
测试:qemu-system-gnuarmeclipse --version
安装工具链
这一步不是必须的,如果机器中有 arm-none-gcc 可以跳过此步骤。
sudo apt-get install gcc-arm-none-eabi -y
准备工程
1)STM32 CubeMX 选择 以 F429-DISC1 作为项目模板。
2)在"Project Manager"中,"Project" - "Toolchain/IDE" 选择 Makefile。
3)根据自己的需求改改其他的东西(建议禁用FreeRTOS),"GENERATE CODE"。
编译项目
由于是CubeMx生成的,一般除了gcc如果不是arm-node-eabi-gcc之外,不需要其他的改动了。
进入项目以后,直接输入:
make
arm-none-eabi-gcc -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -DUSE_HAL_DRIVER -DSTM32F429xx -IInc -IDrivers/STM32F4xx_HAL_Driver/Inc -IDrivers/STM32F4xx_HAL_Driver/Inc/Legacy -IMiddlewares/Third_Party/FreeRTOS/Source/include -IMiddlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS -IMiddlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F -IMiddlewares/ST/STM32_USB_Host_Library/Core/Inc -IMiddlewares/ST/STM32_USB_Host_Library/Class/CDC/Inc -IDrivers/CMSIS/Device/ST/STM32F4xx/Include -IDrivers/CMSIS/Include -IDrivers/CMSIS/Include -Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 -MMD -MP -MF"build/main.d" -Wa,-a,-ad,-alms=build/main.lst Src/main.c -o build/main.o
...
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld: warning: /usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7e-m/fpu/libc_nano.a(lib_a-reent.o) uses 2-byte wchar_t yet the output is to use 4-byte wchar_t; use of wchar_t values across objects may fail
arm-none-eabi-size build/for_stm32f429.elf
text data bss dec hex filename
30548 156 37660 68364 10b0c build/for_stm32f429.elf
arm-none-eabi-objcopy -O ihex build/for_stm32f429.elf build/for_stm32f429.hex
arm-none-eabi-objcopy -O binary -S build/for_stm32f429.elf build/for_stm32f429.bin
仿真
使用以下命令进行仿真:
注意,仿真需要 elf 文件( 由 arm-none-eabi-gcc 编译出来的) 或者 axf 文件( 由 keil 编译出来的 )
qemu-system-gnuarmeclipse --board STM32F429I-Discovery -d unimp,guest_errors --image build/for_stm32f429.elf
可以看到 界面出现了开发板的样子。但由于 QEMU 不支持硬浮点,导致打印以下的报告:
$ qemu-system-gnuarmeclipse --board STM32F429I-Discovery -d unimp,guest_errors --image build/for_stm32f429.elf
NVIC: Bad read offset 0xd88
qemu-system-gnuarmeclipse: Attempt to set CP10/11 in SCB->CPACR, but FP is not supported yet.
[2] 4796 killed qemu-system-gnuarmeclipse --board STM32F429I-Discovery -d unimp,guest_errors
修改
由于仿真不顺利,我们需要进行修改。
修改Makefile,将 FLOAT-ABI = -mfloat-abi=hard
改为 FLOAT-ABI = -mfloat-abi=soft
sed -r -i "/FLOAT-ABI = -mfloat-abi=hard/ s/.*/FLOAT-ABI = -mfloat-abi=soft/" Makefile
之后,重新make
。如果没有在CubeMX中选择FreeRTOS,那么重新仿真是可以通过的。
qemu-system-gnuarmeclipse --board STM32F429I-Discovery -d unimp,guest_errors --image build/*.elf
修改 FreeRtos port.c 使其支持 仿真(如果已经配置)
如果CubeMX中选择了FreeRTos,但由于 FreeRTos中的底层不支持软浮点(具体是在文件Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
中),所以出现下面的问题:
make
...
/tmp/cc5R608O.s: Assembler messages:
/tmp/cc5R608O.s:426: Error: selected processor does not support 'vstmdbeq r0!,{s16-s31}' in Thumb mode
/tmp/cc5R608O.s:428: Error: instruction not allowed in IT block -- 'stmdb r0!,{r4-r11,r14}'
/tmp/cc5R608O.s:448: Error: selected processor does not support 'vldmiaeq r0!,{s16-s31}' in Thumb mode
/tmp/cc5R608O.s:450: Error: instruction not allowed in IT block -- 'msr psp, r0'
Makefile:201: recipe for target 'build/port.o' failed
make: *** [build/port.o] Error 1
打开Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F/port.c
文件,
- xPortStartScheduler 函数中 注释掉 以下2行代码:
373 // vPortEnableVFP();
1
2 /* Lazy save always. */
3 // *( portFPCCR ) |= portASPEN_AND_LSPEN_BITS;
- xPortPendSVHandler 函数 中 注释掉 以下2处地方的3行:
443 // " tst r14, #0x10
" /* Is the task using the FPU context? If so, push high vfp registers. */
1 // " it eq
"
2 // " vstmdbeq r0!, {s16-s31}
"
...
465 // " tst r14, #0x10
" /* Is the task using the FPU context? If so, pop the high vfp registers too. */
1 // " it eq
"
2 // " vldmiaeq r0!, {s16-s31}
"
再次仿真,顺利通过。
GDB调试
添加使用--gdb tcp::1234 -S
参数 来进行仿真,例如
qemu-system-gnuarmeclipse --board STM32F429I-Discovery -d unimp,guest_errors --mcu STM32F429ZI --gdb tcp::1234 -S -d --image build/*.elf
qemu启动后等待来自gdb的调试指令,打开另外一个终端窗口,运行
arm-none-eabi-gdb
# 在gdb界面内运行:
(gdb)target remote localhost:1234
(gdb)continue
可以看到qemu开始执行程序,GUI界面上可以看到程序执行效果。
附录:xPack QEMU Arm 所支持的芯片以及开发板
已经支持的板子:
- Maple – LeafLab Arduino-style STM32 microcontroller board
- NUCLEO-F103RB – ST Nucleo Development Board for STM32 F1 series
- NetduinoGo – Netduino GoBus Development Board with STM32F4
- NetduinoPlus2 – Netduino Development Board with STM32F4
- STM32-E407 – Olimex Development Board for STM32F407ZGT6
- STM32-H103 – Olimex Header Board for STM32F103RBT6
- STM32-P103 – Olimex Prototype Board for STM32F103RBT6
- STM32-P107 – Olimex Prototype Board for STM32F107VCT6
- STM32F4-Discovery – ST Discovery kit for STM32F407/417 lines
- STM32F429I-Discovery – ST Discovery kit for STM32F429/439 lines
已经支持的芯片:
- STM32F103RB、STM32F107VC
- STM32F405RG、STM32F407VG、STM32F407ZG
- STM32F429ZI
- STM32L152RE
计划支持但还没支持的开发板:
- EK-TM4C123GXL – TI Tiva C Series TM4C123GXL LaunchPad Evaluation Kit
- FRDM-K20D50M – Freescale Freedom Development Platform for Kinetis K20 USB MCUs
- FRDM-K22F – Freescale Freedom Development Platform for Kinetis K22 MCUs
- FRDM-K64F – Freescale Freedom Development Platform for Kinetis K6[34] and K24 MCUs
- FRDM-KL25Z – Freescale Freedom Development Platform for Kinetis KL[12][45] MCUs
- FRDM-KL26Z – Freescale Freedom Development Platform for Kinetis KL[12]6 MCUs
- FRDM-KL43Z – Freescale Freedom Development Platform for Kinetis KL[34]3, KL[12]7 MCUs
- FRDM-KL46Z – Freescale Freedom Development Platform for Kinetis KL[34]x MCUs
- LPCXpresso-LPC1769 – Embedded Artists LPCXpresso LPC1769 Development Board
- NUCLEO-F334R8 – ST Nucleo Development Board for STM32 F3 series
- NUCLEO-F411RE – ST Nucleo Development Board for STM32 F4 series
- NUCLEO-L152RE – ST Nucleo Development Board with STM32L152RET6
- Netduino2 – Netduino Development Board with STM32F2
- OLIMEXINO-STM32 – Olimex Maple (Arduino-like) Development Board
- SAM3-H256 – Olimex Header Board for ATSAM3S4BA
- STM32F0-Discovery – ST Discovery kit for STM32F051 line
- STM32F3-Discovery – ST Discovery kit for STM32F303 line
- STM32VL-Discovery – ST Discovery kit for STM32F100 Value Line
- TWR-K60F120M – Freescale Kinetis K60 120 MHz Tower System Module
- XMC 2Go – Infineon XMC 2Go Kit with XMC1100
- XMC1100 Boot Kit – Infineon CPU Card XMC1100 Boot Kit Entry Series
- XMC1200 Boot Kit – Infineon CPU Card XMC1200 Boot Kit Feature Series
- XMC1300 Boot Kit – Infineon CPU Card XMC1300 Boot Kit Control Series
- XMC4200 Enterprise Kit – Infineon CPU Board XMC4200 Actuator
- XMC4400 Enterprise Kit – Infineon CPU Board XMC4400 General Purpose
- XMC4500 Enterprise Kit – Infineon CPU Board XMC4500 General Purpose
- XMC4500 Relax Kit – Infineon CPU Board XMC4500 Relax Kit
- XMC4500 Relax Lite Kit – Infineon CPU Board XMC4500 Relax Lite Kit
附录:安装 GNU MCU Eclipse QEMU 完整 IDE(可选项)
qemu-system-gnuarmeclipse
已经足够我们的使用,但如果需要图形界面式的开发,请参考以下的文档。
参考文档:How to download the GNU MCU Eclipse QEMU?
安装 Node.js 与 npm
安装 xmp
npm install --global xpm@latest
安装 QEMU-arm
xpm install --global @xpack-dev-tools/qemu-arm@latest
安装 OPENOCD(Open On-Chip Debugger)
xpm install --global @xpack-dev-tools/openocd@latest