首页 > 其他分享 >FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇

时间:2023-10-15 13:05:35浏览次数:40  
标签:FreeRTOS CM3 bsp arm mps2 ARM qemu an385


开发环境

  • 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 开发板

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇_bsp

  • 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

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇_Source_02

  • 其实这是个 Keil MDK5 的 Pack 包,安装后,会有相应的头文件、简单的示例

提取启动文件与连接脚本

  • 安装 Keil.V2M-MPS2_CMx_BSP.1.8.0.pack 后, 在 V2M-MPS2_CMx_BSP\1.8.0\Device\CMSDK_CM3\Source\GCC 路径下,有 mps2-an385 的启动文件与连接脚本

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇_FreeRTOS_03

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇_qemu_04

  • 把整个 V2M-MPS2_CMx_BSP\1.8.0\Device\CMSDK_CM3 目录复制到工程 qemu-mps2-arm 目录下
  • mps2-an385 的 启动文件与连接脚本,与 STM32F103 系列的很像,基本不需要修改就可以使用

获取 CMSIS 相关头文件

  • 编译报 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 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,确认 交叉编译工具链可以工作

FreeRTOS qemu mps2-an385 bsp 移植制作 :环境搭建篇_qemu_05

获取 FreeRTOS

  • 如果可以访问 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 上的移植,相信移植到真实硬件上,也会提供较好的参考


标签:FreeRTOS,CM3,bsp,arm,mps2,ARM,qemu,an385
From: https://blog.51cto.com/zhangsz0516/7871359

相关文章

  • 《Mastering the FreeRTOS Real Time Kernel》读书笔记(4)软定时器
    5.软件定时器管理软件定时器由FreeRTOS内核实现,并受其控制。它们不需要硬件支持,也与硬件计时器或硬件计数器无关。软件定时器功能是可选的。包括软件定时器功能:1。作为项目的一部分,构建FreeRTOS源文件FreeRTOS/source/timers.c。2.在FreeRTOSConfig.h中将configUSE_TIMERS设置为......
  • 《Mastering the FreeRTOS Real Time Kernel》读书笔记(3)队列管理
    4.队列管理队列,在一些系统中被称为消息队列,可以理解为信息中转站。是任务和任务,任务和中断之间可以互相读和写的一个共享空间。4.2队列的特征存储数据队列本质上是一个先进先出的缓冲区(FIFO),所以可以存储一定容量的数据。有两种方式可以实现FIFO队列:1.将发送给队列的数据复......
  • 《Mastering the FreeRTOS Real Time Kernel》读书笔记(2)任务管理
    3.任务管理如何为每个任务分配处理时间,如何选择在任何给定时间执行何种任务,任务优先级,任务状态。3.2任务功能每个任务必须返回void,并接受一个void类型指针。这些任务一般会写成一个无限循环,由内核来调度,完成任务安排,创建和删除。3.3顶层任务状态由于一般单片机处理器为单核......
  • vue3+vite import 引入ThreeBSP库 报错
    我在网上查了一下先用npm下载了三方包npmithree-js-csg再使用constThreeBSP=require('three-js-csg')(THREE)的方法引入出现了这个报错查了是因为require是webpack里的vite不支持所以找不到然后我就尝试使用import的方法引入importThreeBSPfrom'three-js......
  • 《Mastering the FreeRTOS Real Time Kernel》读书笔记(1)堆内存管理
    这是161204的版本,不完全覆盖目前最新版本的内核。0.关于freeRTOS首先提出了了在小型嵌入式系统中为何需要多任务管理的问题,介绍了freeRTOS的用途。然后开始做广告,吹了一波freeRTOS的好处。其中要注意一些关键的名词:任务优先级分配、任务通知、队列、信号量、互斥锁、软定时器、......
  • FreeRTOS 和 RT-Thread 功能差别对比
    软件定时器FreeRTOS:定时器函数在task中被调用,居于任务调度的定时器RT-Thread:定时器函数既可以配置为在task中被调用,也可以配置为在tick中断中被调用 ......
  • FreeRTOS添加计时器
    最近需要将在Linux上的代码移植到FreeRTOS上,许多系统函数运行不了,其中就包括gettimeofday,以及使用定时器的不同。FreeRTOS的时间管理首先,FreeRTOS的系统时钟节拍可以在配置文件FreeRTOSConfig.h里面设置:#defineconfigTICK_RATE_HZ((TickType_t)1000)//配置系统时......
  • FreeRTOS入门教程(队列详细使用示例)
    (文章目录)前言上篇文章我们已经讲解了队列的概念和队列相关的API函数,那么本篇文章的话就开始带大家来学习使用队列。一、队列基本使用这个例子将会创建三个任务,其中两个任务用来发送数据到队列中,另一个任务用来从队列中读取数据。voidTask1Function(void*param){ intv......
  • 十九、STM32移植FreeRTOS操作系统
    1.环境安装下载FreeRTOS源码2.移植2.1在STM32项目下创建freertos文件夹,然后在文件夹下创建inc、src、port文件夹2.2将FreeRTOS源码目录下的FreeRTOS/Source/include文件夹下的.h头文件全部复制到STM32项目的freertos/inc文件夹下2.3 将FreeRTOS源码目录下的FreeRTOS/Sourc......
  • FreeRTOS入门教程(同步与互斥)
    (文章目录)前言前几篇文章一直在围绕FreeRTOS中的任务创建,删除,优先级,调度算法进行讲解,那么从本篇文章开始将围绕同步与互斥来展开讲解。一、同步与互斥概念当多个任务或线程共享资源并发执行时,同步和互斥是两个关键的概念。1.同步(Synchronization)是指协调多个任务或线程的执......