基于Ubuntu20.04.6LTS,QEMU8.0.0,FreeRTOS 202212.01。
由于本教程不是后补上的,因此可能存在有些库或者文件安装的遗漏。
如果有与教程不一致的地方,看提示,要啥装啥。
1、QEMU8.0.0安装
必需安装:
sudo apt-get install git libglib2.0-dev libfdt-dev libpixman-1-dev zlib1g-dev ninja-build
其他推荐安装的,我也装了:
sudo apt-get install git-email \
libaio-dev libbluetooth-dev libcapstone-dev libbrlapi-dev libbz2-dev \
libcap-ng-dev libcurl4-gnutls-dev libgtk-3-dev \
libibverbs-dev libjpeg8-dev libncurses5-dev libnuma-dev \
librbd-dev librdmacm-dev \
libsasl2-dev libsdl2-dev libseccomp-dev libsnappy-dev libssh-dev \
libvde-dev libvdeplug-dev libvte-2.91-dev libxen-dev liblzo2-dev \
valgrind xfslibs-dev \
libnfs-dev libiscsi-dev
下载QEMU8.0.0源码(Github: GitHub - qemu/qemu: Official QEMU mirror. Please see https://www.qemu.org/contribute/ for how to submit changes to QEMU. Pull Requests are ignored. Please only use release tarballs from the QEMU website.):
git clone git://git.qemu-project.org/qemu.git
也可以通过https://download.qemu.org/qemu-8.0.0.tar.xz下载(我是基于这个版本的)。
在解压后的QEMU路径下开始编译:
# 基于~/work/qemu-8.0.0,这是我存放代码的路径
mkdir build
cd build
../configure
make
编译后生成的产物在build路径下,我们后续在不同平台上用到不同的命令。
在qemu-8.0.0/build/qemu-bundle/usr/local/bin下,我们可以看到很多软链接指向这些命令。
将当前路径加入到系统环境变量PATH中,还可以做一个软链接指向该目录,再将该目录加入到环境变量中。
创建指向该目录的软链接:
mkdir -p ~/bin/qemu
ln -sf -t ~/bin/qemu/ ~/work/qemu-8.0.0/build/qemu-bundle/usr/local/bin/
在~/.bashrc中加入:
export HOMEBIN="${HOME}/bin"
# 这里面的arm-gnu-toolchain-12.2后面会用到,现在先加上吧
export PATH="${HOMEBIN}:${HOMEBIN}/qemu/bin:${HOMEBIN}/arm-gnu-toolchain-12.2/bin:${PATH}"
查看环境变量添加结果:
source ~/.bashrc
which qemu-system-mips
# 返回/home/hihan/bin/qemu/bin/qemu-system-mips
2、FreeRTOS源码
直接整最新的源码,基于GitHub - FreeRTOS/FreeRTOS: 'Classic' FreeRTOS distribution. Started as Git clone of FreeRTOS SourceForge SVN repo. Submodules the kernel.,GitHub - FreeRTOS/FreeRTOS-Kernel: FreeRTOS kernel files only, submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos.。
首先,我们下载FreeRTOS的源码:
mkdir -p ~/work/code/FreeRTOS
cd ~/work/code/FreeRTOS
git clone git@github.com:FreeRTOS/FreeRTOS.git
下载FreeRTOS Kernel源码,这个放在哪呢?看下面,后面会讲为什么要下载在这里。
cd ~/work/code/FreeRTOS/FreeRTOS/Source
git clone git@github.com:FreeRTOS/FreeRTOS-Kernel.git
注意,由于git clone下载后,会自带一层目录FreeRTOS-Kernel,需要将下载的内容挪出来到Source目录下。或者每个Demo下改Makefile:
KERNEL_DIR = $(FREERTOS_ROOT)/Source
==>
KERNEL_DIR = $(FREERTOS_ROOT)/Source/FreeRTOS-Kernel
3、Demo演示
首先是FreeRTOS首页链接:FreeRTOS - Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions。
然后就是Demo的指引:FreeRTOS on QEMU mps2-an385 Model - FreeRTOS。
使用 ARM-none-eabi-gcc (GNU GCC) 编译器生成项目的 makefile 和 构建相同 makefile 的 Eclipse 项目 均位于 FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc 目录中。
构建与执行(得先确保安装Arm GNU Toolchain Downloads – Arm Developer,解压后的路径加到系统环境变量PATH中)
cd ~/work/code/FreeRTOS/FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC/build/gcc
make
如果你一开始没有将FreeRTOS Kernel下载到~/work/code/FreeRTOS/FreeRTOS/Source,编译就会报错,看Makefile就知道了。
# The directory that contains the /source and /demo sub directories.
FREERTOS_ROOT = ./../../../../
#
# Kernel build.
#
KERNEL_DIR = $(FREERTOS_ROOT)/Source
KERNEL_PORT_DIR += $(KERNEL_DIR)/portable/GCC/ARM_CM3
INCLUDE_DIRS += -I$(KERNEL_DIR)/include \
-I$(KERNEL_PORT_DIR)
VPATH += $(KERNEL_DIR) $(KERNEL_PORT_DIR) $(KERNEL_DIR)/portable/MemMang
SOURCE_FILES += $(KERNEL_DIR)/tasks.c
SOURCE_FILES += $(KERNEL_DIR)/list.c
SOURCE_FILES += $(KERNEL_DIR)/queue.c
SOURCE_FILES += $(KERNEL_DIR)/timers.c
SOURCE_FILES += $(KERNEL_DIR)/event_groups.c
SOURCE_FILES += $(KERNEL_DIR)/stream_buffer.c
SOURCE_FILES += $(KERNEL_DIR)/portable/MemMang/heap_4.c
SOURCE_FILES += $(KERNEL_DIR)/portable/GCC/ARM_CM3/port.c
我们在output目录下新增一个runQemu.sh脚本,
CUR_PATH="$(dirname $(readlink -f "$0"))"
qemu-system-arm \
-machine mps2-an385 \
-cpu cortex-m3 \
-kernel "${CUR_PATH}"/RTOSDemo.out \
-monitor none \
-nographic
-serial stdio \
-s \
-S
加执行权限后运行,终端打印信息如下:
4、在VisualStudio Code中Debug
为什么VS Code来调试呢?因为我刚好在此Demo的根目录下看到了.vscode目录。为了方便看代码,我将Source目录和此Demo加到一个工作区中。
有个Readme.md,如下所示。
# Running with VSCode Launch Configurations
## Prerequisites
* Install [C/C++ extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) in VSCode.
* Install [arm-none-eabi-gcc](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads).
* Install GNU make utility.
* Ensure the required binaries are in PATH with ```arm-none-eabi-gcc --version```, ```arm-none-eabi-gdb --version```, and ```make --version```.
## Building and Running
1. Open VSCode to the folder ```FreeRTOS/Demo/CORTEX_MPS2_QEMU_IAR_GCC```.
2. Open ```.vscode/launch.json```, and ensure the ```miDebuggerPath``` variable is set to the path where arm-none-eabi-gdb is on your machine.
3. Open ```main.c```, and set ```mainCREATE_SIMPLE_BLINKY_DEMO_ONLY``` to ```1``` to generate just the [simply blinky demo](https://www.freertos.org/a00102.html#simple_blinky_demo).
4. On the VSCode left side panel, select the “Run and Debug” button. Then select “Launch QEMU RTOSDemo” from the dropdown on the top right and press the play button. This will build, run, and attach a debugger to the demo program.
根据提示,主要是几个:
(1)前提条件安装好、配置好。
(2)miDebuggerPath需要根据本地配置调整下,终端命令行输入which arm-none-eabi-gdb,得到的结果给到miDebuggerPath。
"miDebuggerPath": "/home/hihan/bin/arm-gnu-toolchain-12.2/bin/arm-none-eabi-gdb",
(3)其他的配置,Demo中已经配好,不需要修改。
下面两种启动调试的方式都可以。
看效果,首先我没有加任何断点,会默认停在main()函数的入口处,这是因为qemu-system-arm启动时,加入了-S参数,再点击继续按钮就能跑起来了。这篇博客不讲为啥这边是入口,后续会讲解。
再看整个过程中终端的输出。
5、 qemu-system-arm命令参数的简单介绍
qemu-system-arm是qemu编译后生成的基于arm平台的程序,--help可以查看所带参数的含义。基于本篇博客运行的命令,我们看一些常用参数。
qemu-system-arm \
-machine mps2-an385 \
-cpu cortex-m3 \
-kernel "${CUR_PATH}"/RTOSDemo.out \
-monitor none \
-nographic
-serial stdio \
-s \
-S
-machine: selects emulated machine ('-machine help' for list)
==> mps2-an385 ARM MPS2 with AN385 FPGA image for Cortex-M3
-cpu: select CPU ('-cpu help' for list)
-kernel bzImage : use 'bzImage' as kernel image
-monitor dev redirect the monitor to char device 'dev'-nographic disable graphical output and redirect serial I/Os to console
-serial dev redirect the serial port to char device 'dev'
-s shorthand for -gdb tcp::1234
-S freeze CPU at startup (use 'c' to start execution)