Win10 64位 + VS Code,ssh 远程连接 ubuntu
VMware Workstation Pro 16 + Ubuntu 20.04
FreeRTOSv202212.01
(备注:可以在 github 获取最新版本)
qemu qemu-system-arm
mps2-an385
开发板,qemu 版本 QEMU emulator version 4.2.1 或更高
arm gcc 交叉编译工具链:当前使用 gcc 编译环境, gcc-arm-11.2-2022.02-x86_64-arm-none-eabi
, gcc version 11.2.1 20220111
FreeRTOS 当前支持 qemu mps2-an385
,可以参考 FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_M3_MPS2_QEMU_GCC
,所以整个移植难度降低很多,不过为了全面的掌握 FreeRTOS 上 board 的移植方法,所以采用全新移植的方式。
为何使用 qemu而不使用实际的开发板进行 FreeRTOS 的学习研究?其实就是为了方便、高效,当然全面掌握RTOS 技术开发是离不开实际硬件的。
使用 qemu,可以用于评估验证一些软件功能,开发一些组件、框架,这些软件功能,由于不依赖具体的平台,所以使用 qemu 来开发会大大的提高效率
软件是调试出来的,一些功能的验证、运行结果的比对,需要大量的调试,使用 Qemu,无疑降低了调试环境的搭建,所以Qemu 用于开发学习 FreeRTOS,是很有用的一件事情。
开发环境暂时为 :Linux 环境, ubuntu 20.04,后面尝试适配到 Windows 上,工程编译采用 gcc 交叉编译,Makefile 构建
ubuntu 20.04 需要安装 qemu,qemu-system-arm
,默认版本即可支持 Qemu 开发板:mps2-an385
可以在 Linux shell 下 输入命令查看 qemu 支持的开发板:
$ qemu-system-arm --version
QEMU emulator version 4.2.1 (Debian 1:4.2-3ubuntu6.27)
Copyright (c) 2003-2019 Fabrice Bellard and the QEMU Project developers
qemu-system-arm -M help
查看当前 qemu qemu-system-arm
支持的 ARM 开发板mps2-an385 ARM MPS2 with AN385 FPGA image for Cortex-M3
,类似于 STM32F103 系列,是 ARM Cortex-M3 系列的。mps2-an385
相关资料mps2-an385
的资料非常少,我当前获取到的就是一个 SDK,还是从 ARM 官方搜索半天找到的。不过这个 mps2-an385
类似于 STM32,systick、pendSV 等跟 STM32 基本一致,所以基本不需要改动就可以运行。V2M-MPS2_CMx_BSP
,下载地址为: https://keilpack.azureedge.net/pack/Keil.V2M-MPS2_CMx_BSP.1.8.0.packKeil.V2M-MPS2_CMx_BSP.1.8.0.pack
后, 在 V2M-MPS2_CMx_BSP\1.8.0\Device\CMSDK_CM3\Source\GCC
路径下,有 mps2-an385 的启动文件与连接脚本把整个 V2M-MPS2_CMx_BSP\1.8.0\Device\CMSDK_CM3
目录复制到工程 qemu-mps2-arm
目录下
mps2-an385
的 启动文件与连接脚本,与 STM32F103 系列的很像,基本不需要修改就可以使用
编译报 system_CMSDK_CM3.c:35:4: error: #error device not specified!
,可以在 qemu-mps2-arm/CMSDK_CM3/Source/system_CMSDK_CM3.c
文件上面定义 MCU 的型号 #define CMSDK_CM3
编译还缺少 CMSIS 相关的头文件,如 core_cm3.h
文件: 这部分可以复制 Keil MDK5 pack 路径下的 \ARM\CMSIS\5.8.0\CMSIS\Core\Include\core_cm3.h
到 工程 cmsis\Core\Include
目录
工程创建 qemu-mps2-arm/cmsis/Core/Include
目录,把以下Keil MDK5 pack 路径下的相关 cmsis
头文件文件复制进来
\ARM\CMSIS\5.8.0\CMSIS\Core\Include\cmsis_compiler.h
\ARM\CMSIS\5.8.0\CMSIS\Core\Include\cmsis_gcc.h
\ARM\CMSIS\5.8.0\CMSIS\Core\Include\cmsis_version.h
\ARM\CMSIS\5.8.0\CMSIS\Core\Include\core_cm3.h
\ARM\CMSIS\5.8.0\CMSIS\Core\Include\mpu_armv7.h
下载 arm gcc 交叉编译工具链:ARM 官方提供 各个版本的下载地址
https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads
当前验证 较新的版本,如 gcc-arm-11.2-2022.02-x86_64-arm-none-eabi,可以正常编译并运行
可以在 gcc 交叉编译工具链下 bin
目录,运行 arm-none-eabi-gcc -v
,确认 交叉编译工具链可以工作
如果可以访问 github,建议从 github 上 使用 git 拉取最新的 FreeRTOS 版本,也可以下载 FreeRTOS 的 Release 版本,我当前使用 FreeRTOSv202212.01
下载地址:可以在 github 或者 FreeRTOS 官方网站上找到下载链接 https://github.com/FreeRTOS/FreeRTOS/releases/tag/202212.01
git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules
或者只 clone FreeRTOS 的 Kernel,不过最好全部 clone 下来,参考里面的例程
git clone https://github.com/FreeRTOS/FreeRTOS-Kernel.git
为了减少 工程的体积,只需要把需要的代码文件复制到工程即可
可以复制到工程后,手动移除不需要的目录与文件,也可以只复制需要的目录与文件到工程
当前的 qemu mps2-an385
属于 ARM Cortex-M3,Linux gcc 交叉编译环境,所以平台文件需要 FreeRTOSv202212.01\FreeRTOS\Source\portable\GCC\ARM_CM3
内存管理部分:FreeRTOSv202212.01\FreeRTOS\Source\portable\MemMang
需要
内核部分:主要是 FreeRTOSv202212.01\FreeRTOS\Source
下的 .c 文件
头文件 : 需要 FreeRTOSv202212.01\FreeRTOS\Source\include
FreeRTOS 的授权 License
可以复制到工程
工程的结构如下
zhangsz@zhangsz:~/rtos/freertos_arm_qemu$ tree
.
├── License
│ └── license.txt
├── qemu_arm_mps2
│ ├── application
│ │ ├── IntQueue.c
│ │ ├── IntQueue.h
│ │ ├── IntQueueTimer.c
│ │ ├── IntQueueTimer.h
│ │ ├── main_blinky.c
│ │ ├── main.c
│ │ └── printf-stdarg.c
│ ├── CMSDK_CM3
│ │ ├── Include
│ │ │ ├── CMSDK_CM3.h
│ │ │ └── system_CMSDK_CM3.h
│ │ └── Source
│ │ ├── ARM
│ │ │ ├── ac6_arm.sct
│ │ │ └── startup_CMSDK_CM3.S
│ │ ├── GCC
│ │ │ ├── gcc_arm.ld
│ │ │ └── startup_CMSDK_CM3.S
│ │ ├── startup_CMSDK_CM3.c
│ │ └── system_CMSDK_CM3.c
│ ├── cmsis
│ │ └── core
│ │ └── include
│ │ ├── cmsis_compiler.h
│ │ ├── cmsis_gcc.h
│ │ ├── cmsis_version.h
│ │ ├── core_cm3.h
│ │ └── mpu_armv7.h
│ ├── FreeRTOSConfig.h
│ ├── Makefile
│ ├── output
│ │ └── asm
│ ├── qemu-debug.sh
│ ├── qemu.sh
│ └── Readme.md
├── readme.md
└── Source
├── croutine.c
├── event_groups.c
├── include
│ ├── atomic.h
│ ├── CMakeLists.txt
│ ├── croutine.h
│ ├── deprecated_definitions.h
│ ├── event_groups.h
│ ├── FreeRTOS.h
│ ├── list.h
│ ├── message_buffer.h
│ ├── mpu_prototypes.h
│ ├── mpu_wrappers.h
│ ├── newlib-freertos.h
│ ├── picolibc-freertos.h
│ ├── portable.h
│ ├── projdefs.h
│ ├── queue.h
│ ├── semphr.h
│ ├── stack_macros.h
│ ├── StackMacros.h
│ ├── stdint.readme
│ ├── stream_buffer.h
│ ├── task.h
│ └── timers.h
├── LICENSE.md
├── list.c
├── portable
│ ├── GCC
│ │ └── ARM_CM3
│ │ ├── port.c
│ │ └── portmacro.h
│ └── MemMang
│ ├── heap_1.c
│ ├── heap_2.c
│ ├── heap_3.c
│ ├── heap_4.c
│ ├── heap_5.c
│ └── ReadMe.url
├── queue.c
├── README.md
├── stream_buffer.c
├── tasks.c
└── timers.c
备注: mps2-an385 的 bsp 相关文件,可以从 FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_M3_MPS2_QEMU_GCC
获取,当前连接脚本、启动文件,采用 V2M-MPS2_CMx_BSP
里面的
Makefile 构建文件
OUTPUT_DIR := ./output
IMAGE := mps2_demo.elf
KERNEL_ROOT = ./..
CROSS_COMPILE = /home/zhangsz/linux/tools/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/
CC = $(CROSS_COMPILE)/arm-none-eabi-gcc
LD = $(CROSS_COMPILE)/arm-none-eabi-gcc
SIZE = $(CROSS_COMPILE)/arm-none-eabi-size
MAKE = make
CFLAGS += $(INCLUDE_DIRS) -nostartfiles -ffreestanding -mthumb -mcpu=cortex-m3 \
-Wall -msoft-float -g -O0 -ffunction-sections -fdata-sections \
-std=gnu99 \
LDFLAGS=-mthumb \
-mcpu=cortex-m3 \
-mlittle-endian \
-ffreestanding \
-specs=nano.specs \
-specs=nosys.specs \
-specs=rdimon.specs \
-T$(LINK_SCRIPTS) \
-Wl,-Map=$(OUTPUT_DIR)/mps2_demo.map
#KERNEL_DIR = $(KERNEL_ROOT)/uC-OS2
KERNEL_DIR = $(KERNEL_ROOT)/Source
KERNEL_PORT_DIR += $(KERNEL_DIR)/portable/GCC/ARM_CM3
INCLUDE_DIRS += -I$(KERNEL_DIR)/include \
-I$(KERNEL_DIR)/portable/GCC/ARM_CM3 \
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
DEMO_ROOT = $(KERNEL_ROOT)
DEMO_PROJECT = $(DEMO_ROOT)/qemu_arm_mps2
INCLUDE_DIRS += -I$(DEMO_PROJECT) \
-I$(DEMO_PROJECT)/cmsis/core/include \
-I$(DEMO_PROJECT)/CMSDK_CM3/Include \
SOURCE_FILES += $(DEMO_PROJECT)/application/main.c
SOURCE_FILES += $(DEMO_PROJECT)/application/main_blinky.c
SOURCE_FILES += $(DEMO_PROJECT)/application/IntQueue.c
SOURCE_FILES += $(DEMO_PROJECT)/application/IntQueueTimer.c
SOURCE_FILES += $(DEMO_PROJECT)/application/printf-stdarg.c
SOURCE_FILES += $(DEMO_PROJECT)/CMSDK_CM3/Source/system_CMSDK_CM3.c
ASM_OBJS = $(DEMO_PROJECT)/CMSDK_CM3/Source/GCC/startup_CMSDK_CM3.o
APP_OBJS=$(patsubst %.c, %.o, $(SOURCE_FILES))
LINK_SCRIPTS = $(DEMO_PROJECT)/CMSDK_CM3/Source/GCC/gcc_arm.ld
all: app
@echo "---- build end ----"
.c.o:
$(CC) -c $^ -o $@ $(CFLAGS)
.S.o:
$(CC) -c $^ -o $@ $(CFLAGS)
app : $(APP_OBJS) $(ASM_OBJS)
$(CC) $^ -o $(IMAGE) $(LDFLAGS)
clean :
rm -f $(APP_OBJS)
rm -f $(ASM_OBJS)
rm -f $(IMAGE)
export CFLAGS CC
CROSS_COMPILE
交叉编译工具链的路径本篇注意介绍 FreeRTOS qemu mps2-an385 bsp 的制作,后面开始编译、调优与运行
qemu
调试环境可以加快 FreeRTOS 的学习与研究,在功能验证、软件组件框架开发中,会提高效率
掌握了 qemu 在 FreeRTOS 上的移植,相信移植到真实硬件上,也会提供较好的参考