APM32芯得 EP.06 | APM32F407移植uC/OS-III实时操作系统经验分享

article/2025/7/22 6:38:52

《APM32芯得》系列内容为用户使用APM32系列产品的经验总结,均转载自21ic论坛极海半导体专区,全文未作任何修改,未经原文作者授权禁止转载。

最近我开始学习 uC/OS-III 实时操作系统,并着手将其移植到APM32F407 开发板上。在这个过程中,我遇到了许多有趣的挑战和发现,也感受到了操作系统带来的强大功能和灵活性。

在这篇帖子中,我打算分享我的学习经验和移植过程,包括如何开始学习uC/OS-III、配置步骤、移植过程中遇到的问题以及解决方法。我希望通过这篇帖子,能够帮助那些和我一样对操作系统感兴趣的朋友们,一起探索如何在APM32F407 上应用 uC/OS-III。

1. uC/OS-III简介:

uC/OS-III,又称微型C语言编写的操作系统第3版,是一个基于优先级的实时内核,可升级和固化。它无限制地支持任务个数,并且作为第三代内核,拥有现代实时内核所需的基本功能,例如资源管理、同步和任务间通信。值得注意的是,uC/OS-III具有独特的功能,如完整的运行时性能测量、直接向任务发送信号或消息,以及任务可以同时等待多个内核对象。

简单来说,uC/OS-III是一个可扩展和稳固的实时内核,可以管理无限数量的任务。它满足现代实时内核的期望,提供资源管理、同步和任务间通信等功能。它的独特之处在于能够在运行时测量性能、直接向任务发送信号或消息,以及任务可以同时等待多个信号或消息队列。

下面是一个列出了uC/OS-III的功能的简单表格:    

图片

这些功能使得uC/OS-III成为一个强大、灵活且功能丰富的实时操作系统,适用于各种嵌入式系统和实时应用场景。

2.移植流程

一、uCOS-III系统文件获取

我这里提供了两种下载方式,如下。    

1.网盘链接下载:https://pan.baidu.com/s/1nHZjj2A40qW_jbbODOXfOw?pwd=762k

2.官方下载:https://github.com/weston-embedded

以下是点击官方下载的链接后,需要下载的源文件。

① uc-os3源码下载

图片

② uc-lib源码下载

图片

③ uc-cpu源码下载

二、添加ucos-III系统文件

1、去极海官网(https://geehy.com/apm32?id=47)下载APM32F407SDK,打开Examples文件夹,复制一份Template模板,新建ucos-III文件夹,把下载的源码文件全部都复制进去。‍‍

图片

2、打开mdk工程,新建一些文件目录。

图片

3、向ucos_cpu中添加文件

打开uCOSIII\uC-CPU文件目录,添加cpu_core.c文件。‍

图片

打开uCOSIII\uC-CPU\ARM-Cortex-M\ARMv7-M文件目录,添加cpu_c.c。

图片

打开uCOSIII\uC-CPU\ARM-Cortex-M\ARMv7-M\ARM文件目录,添加cpu_a.asm。

图片

4、向ucos_lib中添加文件。

打开uCOSIII\uC-LIB文件目录,添加该文件目录下的所有.c文件。‍

图片

5、向ucos_source中添加文件。

打开uCOSIII\uC-OS3\Source文件目录,添加除了__dbg_uCOS-III.c文件的其余所有文件。‍

图片

6、向ucos_port中添加文件。

打开uCOSIII\uC-OS3\Ports\ARM-Cortex-M\ARMv7-M\ARM文件目录,添加该目录下所有文件。‍

图片

打开uCOSIII\uC-OS3\Ports\ARM-Cortex-M\ARMv7-M文件目录,添加os_cpu_c.c。

7、向ucos_misc中添加文件。

打开uCOSIII\uC-CPU\BSP\Template文件目录,添加bsp_cpu.c。‍

图片

8、添加头文件。

图片

       

图片

三、编写代码

‍1、编写app_cfg.h文件。

ucos-III是没有提供app_cfg.h这个文件的,我们需要手动编写。在uCOSIII下新建app_cfg.h,添加如下代码。    ‍

图片

/*

*********************************************************************************************************

* EXAMPLE CODE

*

* This file is provided as an example on how to use Micrium products.

*

* Please feel free to use any application code labeled as 'EXAMPLE CODE' in

* your application products.  Example code may be used as is, in whole or in

* part, or may be used as a reference only. This file can be modified as

* required to meet the end-product requirements.

*

* Please help us continue to provide the Embedded community with the finest

* software available.  Your honesty is greatly appreciated.

*

* You can find our product's user manual, API reference, release notes and

* more information at https://doc.micrium.com.

* You can contact us at www.micrium.com.

*********************************************************************************************************

*/

#ifndef APP_CFG_MODULE_PRESENT

#define APP_CFG_MODULE_PRESENT

/*

*********************************************************************************************************

* MODULE ENABLE / DISABLE

*********************************************************************************************************

*/

/*

*********************************************************************************************************

* TASK PRIORITIES

*********************************************************************************************************

*/

#define APP_CFG_TASK_START_PRIO                       2u

#define APP_CFG_TASK_1_PRIO                           3u

#define APP_CFG_TASK_2_PRIO                           4u

/*

*********************************************************************************************************

* TASK STACK SIZES

*********************************************************************************************************

*/

#define APP_CFG_TASK_START_STK_SIZE                   128u

#define APP_CFG_TASK_BLINKY_STK_SIZE                  128u

#define APP_CFG_TASK_1_STK_SIZE                       512u

#define APP_CFG_TASK_2_STK_SIZE                       512u

/*

*********************************************************************************************************

* TRACE / DEBUG CONFIGURATION

*********************************************************************************************************

*/

#ifndef TRACE_LEVEL_OFF

#define TRACE_LEVEL_OFF                               0

#endif

#ifndef TRACE_LEVEL_INFO                              

#define TRACE_LEVEL_INFO                              1

#endif

#ifndef TRACE_LEVEL_DBG                               

#define TRACE_LEVEL_DBG                               2

#endif

#define APP_CFG_TRACE_LEVEL                           TRACE_LEVEL_OFF

#define APP_CFG_TRACE                                 printf

#define BSP_CFG_TRACE_LEVEL                           TRACE_LEVEL_OFF

#define BSP_CFG_TRACE                                 printf

#define APP_TRACE_INFO(x)                             ((APP_CFG_TRACE_LEVEL >= TRACE_LEVEL_INFO)  ? (void)(APP_CFG_TRACE x) : (void)0)

#define APP_TRACE_DBG(x)                              ((APP_CFG_TRACE_LEVEL >= TRACE_LEVEL_DBG)   ? (void)(APP_CFG_TRACE x) : (void)0)

#define BSP_TRACE_INFO(x)                             ((BSP_CFG_TRACE_LEVEL  >= TRACE_LEVEL_INFO) ? (void)(BSP_CFG_TRACE x) : (void)0)

#define BSP_TRACE_DBG(x)                              ((BSP_CFG_TRACE_LEVEL  >= TRACE_LEVEL_DBG)  ? (void)(BSP_CFG_TRACE x) : (void)0)

#endif

‍这段代码是uC/OS-III示例程序的配置文件,定义了一些任务优先级、任务堆栈大小以及跟踪/调试配置相关的宏。以下是每个定义的宏的作用:

1. 任务优先级(`APP_CFG_TASK_START_PRIO`, `APP_CFG_TASK_1_PRIO`, `APP_CFG_TASK_2_PRIO`):

     - 定义了不同任务的优先级,用于确定任务在多任务系统中的执行顺序。数字越小,优先级越高。‍

‍2. 任务堆栈大小(`APP_CFG_TASK_START_STK_SIZE`, `APP_CFG_TASK_BLINKY_STK_SIZE`,`APP_CFG_TASK_1_STK_SIZE`,   `APP_CFG_TASK_2_STK_SIZE`):

     - 定义了不同任务所使用的堆栈大小。堆栈大小越大,任务能够使用的局部变量和函数调用深度就越大。

3. 跟踪/调试配置:

     - `TRACE_LEVEL_OFF`、`TRACE_LEVEL_INFO` 和`TRACE_LEVEL_DBG` 定义了跟踪信息的级别。在这里,`TRACE_LEVEL_OFF` 表示关闭跟踪,`TRACE_LEVEL_INFO` 表示仅输出信息级别的跟踪,`TRACE_LEVEL_DBG`表示输出调试级别的跟踪。

   -`APP_CFG_TRACE_LEVEL` 和 `BSP_CFG_TRACE_LEVEL` 分别定义了应用程序和 BSP (Board Support Package) 的跟踪级别。

   - `APP_CFG_TRACE` 和 `BSP_CFG_TRACE` 是跟踪输出函数的宏定义。在这里,它们被定义为`printf`,表示将跟踪信息输出到标准输出设备(通常是串口)。‍

‍4. 跟踪输出宏 (`APP_TRACE_INFO`,`APP_TRACE_DBG`, `BSP_TRACE_INFO`, `BSP_TRACE_DBG`):

   - 这些宏用于根据跟踪级别输出相应级别的跟踪信息。当跟踪级别高于宏定义的级别时,才会输出相应级别的跟踪信息,否则会被忽略。

2、编写main函数。

我已经编写了一个使用ucos-iii的简单的示例代码,代码如下。

/*!

 * [url=home.php?mod=space&uid=288409]@file[/url]        main.c

 *

 * [url=home.php?mod=space&uid=247401]@brief[/url]       Main program body

 *

 * [url=home.php?mod=space&uid=895143]@version[/url]     V1.0.3

 *

 * [url=home.php?mod=space&uid=212281]@date[/url]        2023-07-31

 *

 * @attention

 *

 *  Copyright (C) 2021-2023 Geehy Semiconductor

 *

 *  You may not use this file except in compliance with the

 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).

 *

 *  The program is only for reference, which is distributed in the hope

 *  that it will be useful and instructional for customers to develop

 *  their software. Unless required by applicable law or agreed to in

 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT

 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.

 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions

 *  and limitations under the License.

 */

/* Includes */

#include "main.h"

#include "Board.h"

#include <stdio.h>

#include <os.h>

#include <app_cfg.h>

#define DEBUG_USART  USART1

/** @addtogroup Examples

  @{

  */

/** @addtogroup Template

  @{

  */

/** @defgroup Template_Functions Functions

  @{

  */

#define STACK_SIZE 128      // Stack size for LED task

#define LED_TASK_PRIO 5     // Priority for LED task

#define SERIAL_TASK_PRIO 6  // Priority for serial print task

OS_TCB ledTaskTCB;         // Task Control Block for LED task

OS_TCB serialTaskTCB;      // Task Control Block for serial print task

CPU_STK ledTaskStk[STACK_SIZE];    // Stack for LED task

CPU_STK serialTaskStk[STACK_SIZE]; // Stack for serial print task

OS_FLAG_GRP ledFlagGrp;    // Event flag group for LED task

void ledTask(void *p_arg);

void serialPrintTask(void *p_arg);

/*!

 * [url=home.php?mod=space&uid=247401]@brief[/url]       Main program

 *

 * @param       None

 *

 * @retval      None

 */

int main(void)

{

        USART_Config_T usartConfig;

        

    /* Configure US

‍‍‍我们可以简单分析一下这段代码,这段代码实现了两个任务:LED任务 (`ledTask`) 和串行打印任务(`serialPrintTask`)。以下是代码的主要功能和实现细节:

1. 任务优先级和堆栈大小定义:

       - 定义了LED任务和串行打印任务的优先级 (`LED_TASK_PRIO` 和`SERIAL_TASK_PRIO`),以及任务堆栈大小 (`STACK_SIZE`)。

       - 定义了LED任务和串行打印任务的任务控制块 (TCB) 和堆栈数组。

2. uC/OS-III初始化:

       - 使用`OSInit()` 函数初始化uC/OS-III。

3. 串口和LED初始化:

       - 配置了USART1作为调试串口,并初始化LED2和LED3。

4. 任务创建:

       - 使用`OSTaskCreate()` 函数创建LED任务和串行打印任务。

       - `ledTask` 函数用于定期切换LED状态,并通过设置事件标志组通知串行打印任务。

       - `serialPrintTask`函数等待事件标志组的设置,然后通过串口打印消息。

5. 事件标志组创建:

       - 使用`OSFlagCreate()` 函数创建了一个名为 "LED Flags" 的事件标志组 (`ledFlagGrp`)。

6. 多任务启动:

       - 使用`OSStart()` 函数启动uC/OS-III多任务调度。

7. 主循环:

       - 在`main` 函数的无限循环中,没有具体的操作,只是用来保持程序运行。

8. LED控制和定时延迟:

       - `ledTask` 定期切换LED2和LED3的状态,然后通过设置事件标志组通知串行打印任务。

       - `serialPrintTask`等待事件标志组的设置,并在收到通知后通过USART串口打印消息。

9. 系统时钟设置:

       - 使用`SysTick_Config()` 函数配置系统时钟,用于提供定时功能。

总体来说,这份代码展示了如何使用uC/OS-III创建并管理多个任务,通过事件标志组实现任务之间的同步,以及使用USART进行串行通信。

四、编译与下载

图片

初次编译时会报错,原因是ucos-iii系统文件中已经实现了这两个中断服务函数。

图片

注释apm32f4xx_int.c中这两个中断服务函数的实现,再次编译。

图片

编译无误,下载代码。

可以看到LED每隔0.5s翻转一次,当 LED的状态变化时,串口都会打印一串信息。(这里LED翻转的现象就不上传了)

图片

注:文章作者在原帖中提供了例程文件,有需要请至原文21ic论坛下载

原文地址:https://bbs.21ic.com/icview-3364670-1-1.html

图片


http://www.hkcw.cn/article/TfVgEkvbNe.shtml

相关文章

图解gpt之注意力机制原理与应用

大家有没有注意到&#xff0c;当序列变长时&#xff0c;比如翻译一篇长文章&#xff0c;或者处理一个长句子&#xff0c;RNN这种编码器就有点力不从心了。它把整个序列信息压缩到一个固定大小的向量里&#xff0c;信息丢失严重&#xff0c;而且很难记住前面的细节&#xff0c;特…

更新密码--二阶注入攻击的原理

1.原理知识&#xff1a; 二阶SQL注入攻击&#xff08;Second-Order SQL Injection&#xff09;原理详解 一、基本概念 二阶注入是一种"存储型"SQL注入&#xff0c;攻击流程分为两个阶段&#xff1a; ​​首次输入​​&#xff1a;攻击者将恶意SQL片段存入数据库​…

RFID技术助力托盘运输线革新

RFID技术助力托盘运输线革新 湖北某工厂托盘运输线使用上存在的问题&#xff1a; 1、托盘在运输线上受信息录入时间等问题影响&#xff0c;导致效率低下&#xff1b; 2、原先托盘上粘贴的条码容易污损&#xff0c;并且时常需要更新更换&#xff0c;导致信息录入、出入库等步…

EasyRTC嵌入式音视频通信SDK助力1v1实时音视频通话全场景应用

一、方案概述​ 在数字化通信需求日益增长的今天&#xff0c;EasyRTC作为一款全平台互通的实时视频通话方案&#xff0c;实现了设备与平台间的跨端连接。它支持微信小程序、APP、PC客户端等多端协同&#xff0c;开发者通过该方案可快速搭建1v1实时音视频通信系统&#xff0c;适…

java.io.IOException: ZIP entry size is too large or invalid

java.io.IOException: ZIP entry size is too large or invalid 解决方案&#xff1a;pom.xml添加<nonFilteredFileExtension>xlsx</nonFilteredFileExtension>

vue3 项目配置多语言支持,如何从服务端拿多语言配置

在 Vue3 项目中实现多语言支持并从服务端获取配置&#xff0c;可以使用 Vue I18n 库。在初始化阶段可以发送请求获取多语言配置或者通过本地文件加载json文件的方式&#xff0c;都可以实现。我这里是tauri项目&#xff0c;所以使用的是invoke从tauri端拿到配置文件&#xff0c;…

龙舟竞渡与芯片制造的共通逻辑:华芯邦的文化破局之道

端午节承载着中华民族数千年的精神密码&#xff0c;龙舟最初是古人沟通天地、祈求风调雨顺的仪式载体。战国时期&#xff0c;屈原投江的悲壮故事为端午注入了家国情怀&#xff0c;龙舟竞渡从此兼具纪念英雄与祈福避疫的双重意义。这种文化内核&#xff0c;与深圳市华芯邦“以科…

OS9.【Linux】基本权限(下)

目录 1.默认权限 掩码 修改权限掩码 目录的权限说明 r权限 w权限 x权限 结论 家目录权限 2.共享目录 粘滞位t 承接OS8.【Linux】基本权限(上)文章 1.默认权限 创建用户时拥有者所属组都是该用户,而且对其他人没有任何权限 掩码 新建文件new.txt1和目录folder后…

【容器docker】启动容器kibana报错:“message“:“Error: Cannot find module ‘./logs‘

说明&#xff1a; 1、服务器数据盘挂了&#xff0c;然后将以前的数据用rsync拷贝过去&#xff0c;启动容器kibana服务&#xff0c;报错信息如下图所示&#xff1a; 2、可能是拷贝docker文件夹&#xff0c;有些文件没有拷贝过去&#xff0c;导致无论是给文件夹授权用户kibana或者…

【25-cv-05917】HSP律所代理Le Petit Prince 小王子商标维权案

Le Petit Prince 小王子 案件号&#xff1a;25-cv-05917 立案时间&#xff1a;2025年5月28日 原告&#xff1a;SOCIETE POUR LOEUVRE ET LA MEMOIRE DANTOINE DE SAINT EXUPERY - SUCCESSION DE SAINT EXUPERY-DAGAY 代理律所&#xff1a;HSP 原告介绍 《小王子》&#x…

信创国产化

一、硬件国产化 1. 飞腾E2000Q 二、操作系统国产化 1. 麒麟系统 1.1 麒麟嵌入式支持飞腾E2000Q 1.1.1 启动安装盘制作 1. 下载rufus工具,安装,下载麒麟系统ISO镜像文件。 2. 使用rufus制作启动盘,U盘插入(注先备份数据,会格式化盘符),配置参数如图。 3. 点击…

一、Sqoop历史发展及原理

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月30日 专栏&#xff1a;Sqoop教程 在大数据时代&#xff0c;数据往往分散存储在各种不同类型的系统中。其中&#xff0c;传统的关系型数据库 (RDBMS) 如 MySQL, Oracle, PostgreSQL 等&#xff0c;仍然承载着大量的关键业务…

2.从0开始搭建vue项目(node.js,vue3,Ts,ES6)

从“0到跑起来一个 Vue 项目”&#xff0c;重点是各个工具之间的关联关系、职责边界和技术演化脉络。 从你写代码 → 到代码能跑起来 → 再到代码可以部署上线&#xff0c;每一步都有不同的工具参与。 &#x1f63a;&#x1f63a;1. 安装 Node.js —— 万事的根基 Node.js 是…

包管理工具

npx工具 npx是什么捏&#xff1f; npx是npm5.2之后自带的一个命令 npx的作用非常之多&#xff0c;但是比较常见的是它用来调用项目中的某个模块的指令 现在假设一个场景&#xff1a; 你在项目里安装了webpack&#xff0c;也在全局中安装了webpack&#xff0c;但是这俩版本…

信号发生器幅值和偏置设置

Vrms是有效幅度 Vpp是幅度峰峰值 Vp是幅度最大值 幅度 2Vpp, 偏置 0V: 信号范围&#xff1a; -1V (谷底) 到 1V (峰顶) -> 中心点在 0V。 幅度 2Vpp, 偏置 1V: 信号范围&#xff1a; (-1V 1V) 0V (谷底) 到 (1V 1V) 2V (峰顶) -> 中心点在 1V。 形状和 Vpp (2…

深入浅出:Spring IOCDI

什么是IOC IOC IOC(Inversion of Control)&#xff0c;是一种设计思想&#xff0c;在之前的SpringMVC里就在类上添加RestController和Controller注解就是使用了IOC&#xff0c;这两个注解就是在Spring中创建一个对象&#xff0c;并将注解下的类交给Spring管理&#xff0c;Spr…

Java并发

一、进程和线程 进程&#xff1a; 程序的一次执行过程&#xff0c;是系统运行程序的基本单位&#xff0c;因此进程是动态。系统运行一个程序即是一个进程从创建&#xff0c;运行到消亡的过程。 在Java中&#xff0c;当我们启动main函数时其实就是启动了一个JVM进程&#xff…

通过回调函数注册定时器触发事件

1、说明 使用回调函数&#xff0c;注册定时器触发事件的模式&#xff0c;提高定时器中断的可操作性&#xff0c;那如何实现呢&#xff1f; 2、.h文件 下面是定时器句柄的声明 3、.c文件 3.1、静态定时器句柄头 3.2、定时器回调函数处理 下面的函数是放在1ms的中断中的&#…

Visual Studio+SQL Server数据挖掘

这里写自定义目录标题 工具准备安装Visual studio 2017安装SQL Server安装SQL Server Management Studio安装analysis service SSMS连接sql serverVisual studio新建项目数据源数据源视图挖掘结构部署模型设置挖掘预测 部署易错点 工具准备 Visual studio 2017 analysis servi…

大模型-attention汇总解析之-MHA

一、MHA(Multi-Head Attention) 1.1 MHA 原理 MHA&#xff08;Multi-Head Attention&#xff09;称为多头注意力&#xff0c;开山之作所提出的一种 Attention 计算形式&#xff0c;它是当前主流 LLM 的基础工作。在数学原理上&#xff0c;多头注意力 MHA 等价于多个独立的单头…