uCOS-III实时操作系统在MCU平台被广泛使用,在这里我们将简单的记录如何将uCOS-III实时操作系统移植到目标平台上并运行。

1、必要的准备

在开始uCOS-III实时操作系统的移植前,我们还需要做一些必要的准备,如确定目标板、准备目标工程及uCOS-III实时操作系统源码等。

1.1、获取uCOS-III源码

在移植uCOS-III之前,首先要获取它的源码。其源码可以从Micrium 的官方网站:www.micrium.com得到。为了方便移植,我们建议直接下载Micrium移植好的基于目标平台的例子。例如我们就下载了uCOS-III V3.0.4基于STM32F4的实例。

解压下载得到的压缩包,我们可以发现4个文件夹,分别是EvalBoards、uC-CPU、uC-LIB、uCOS-III,如下图所示:

其中EvalBoards文件夹下是基于该评估版的应用层实现,在我们的移植中有部分文件可以移过来使用。当然

uC-CPU文件夹这是和 CPU 紧密相关的文件,里面的一些文件很重要,都是我们需要使用的。

uC-LIB文件夹,Micrium 公司提供的官方库,诸如字符串操作、内存操作等接口,可用可不用。一般能用于代替标准库中的一些函数,使得在嵌入式中应用更加方便安全。

uCOS-III文件夹,是操作系统内核文件夹,都是系统核心文件。这些文件是我们全部需要的,移植时将这些拷贝过去就可以。

1.2、建立目标项目

在这里我们的目标MCU选用的是STM32F407ZG,所以在移植之前我们需要建立一个面向STM32F407ZG的裸机工程。当然方法有多种,我们使用STM32CubeMX工具配置硬件然后生成一个基础的项目。

2uCOS-III的移植

我们此次移植基于STM32F407平台,使用HAL库,并使用IAR开发工具来完成。首先,我们创建一个空项目,并添加必要的HAL库函数,以及启动文件,主函数等。总之是一个可以运行的干净的项目即可。

接下来就是移植uCOS-III的过程。移植的过程并不复杂,先将必要的文件复制到我们的项目中来。一是将uC-CPU、uC-LIB、uCOS-III三个文件夹全部复制到我们的项目中。

并将EvalBoards文件夹下的EvalBoards\ST\STM32F429II-SK\uCOS-III目录下的一些文件拷贝到我们的项目中。具体如下图红框中所示:

一般来说我们可以拷贝这8个文件直接使用就可以,但并不说明这8个文件是必须的。其中一些配置文件在系统中会引用到,所以文件名称不要改,而且配置参数按需设定。其他文件实际上可以根据我们的意愿修改。为简便起见,我们还可以复制两个文件,在EvalBoards\ST\STM32F429II-SK\BSP目录之下的bsp文件:

其实,这两个文件与具体硬件联系紧密,一般需要自己编写,不过因为我们知识移植,所以有几个函数我们可以直接拿过来使用,我们将其复制过来加以修改。

文件已经准备好了,接下来就是将其移植到我们的项目中,将uCOS-III下的核心代码添加到项目中,如下:

同时将uC-CPU和uC-LIB文件夹下的内容添加到项目中,具体如下:

然后,将我们从例程中复制的相关文件也添加到项目中,具体如下:

然后修改项目属性中的文件引用路径:

到这了,工程项目就已经创建完成了,但并不可用,此时若编译会出现许多错误。因为例程使用的是标准库,而我们使用了HAL库,据此首先要将bsp.h文件中的#include <stm32f4xx_conf.h>修改为:#include <stm32f4xx_hal.h>。根据需要修改bsp.c文件中的具体驱动代码。

还有一个重要的修改,那就是PendSV中断处理,在STM32F4的启动文件startup_stm32f407xx.s中定义了该中断的中断处理函数PendSV_Handler。同时uCOS-III在os_cpu_a.asm文件中也定义了该中断的中断处理函数OS_CPU_PendSVHandler。所以我们我们需要让他们统一起来,怎么办呢?可以修改startup_stm32f407xx.s文件,也可以修改os_cpu_a.asm文件。在这里我们是修改了startup_stm32f407xx.s文件。不过通常情况下,我们不建议修改别人写好的文件,事实上,原厂例程中提供的一个方法是编写一段汇编程序使用PendSV_Handler调用OS_CPU_PendSVHandler达到相应的目的。不管采用哪种方式都需要在stm32f4xx_it.c文件中注释掉PendSV_Handler函数的实现。

同样的,SysTick_Handler中断处理函数需要做类式的处理。但是由于HAL库本身也是需要使用该中断的,而且在uCOS-III中OS_CPU_SysTickHandler函数是以C代码实现的,所以我们可在stm32f4xx_it.c文件中的SysTick_Handler函数中直接调用。

到这里移植工作基本就完不成了,编译也没有错,但需要跑起来,我们还需要编写相应的多任务处理代码。

3、移植测试

在前面我们已经完成了uCOS-III移植的基本工作。接下来我们实现多任务的测试代码。在开始任务编写前,我们需要修改bsp.c文件的内容。除了具体的应用驱动外,需要实现几个与时钟相关的函数:BSP_CPU_ClkFreq、CPU_TS_TmrInit、CPU_TS_TmrRd、CPU_TS32_to_uSec和CPU_TS64_to_uSec。在我们拷贝来的实例中,其实都有,除BSP_CPU_ClkFreq外,其他都不需要修改。BSP_CPU_ClkFreq函数实现如下:

CPU_INT32U  BSP_CPU_ClkFreq (void)
{CPU_INT32U hclk_freq;hclk_freq=HAL_RCC_GetHCLKFreq();return hclk_freq;
}

然后我们就可以开始具体任务的实现,在这里我们实现1个启动任务和3个普通任务,当然这些任务都非常简单,我们先声明任务控制块和任务栈如下:

static OS_TCB AppTaskStartTCB;
static CPU_STK AppTaskStartStk[APP_CFG_TASK_START_STK_SIZE];
static OS_TCB AppTaskUpdateTCB;
static CPU_STK AppTaskUpdateStk[APP_CFG_TASK_UPDATE_STK_SIZE];
static OS_TCB AppTaskCOMTCB;
static CPU_STK AppTaskCOMStk[APP_CFG_TASK_COM_STK_SIZE];
static OS_TCB AppTaskUserIFTCB;
static CPU_STK AppTaskUserIFStk[APP_CFG_TASK_USER_IF_STK_SIZE];

接着我们在主函数中创建启动任务,并启动任务调度。这时操作系统已经开始任务调度。

//生成启动任务OSTaskCreate((OS_TCB *)&AppTaskStartTCB,(CPU_CHAR *)"App Task Start",(OS_TASK_PTR )AppTaskStart,(void *)0,(OS_PRIO )APP_CFG_TASK_START_PRIO,(CPU_STK *)&AppTaskStartStk[0],(CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE / 10,(CPU_STK_SIZE )APP_CFG_TASK_START_STK_SIZE,(OS_MSG_QTY )0,(OS_TICK )0,(void *)0,(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),(OS_ERR *)&err);OSStart(&err); //启动任取调度

在启动任务的任务函数中我们创建3个具体业务处理的任务,这三个任务创建后,启动任务将自己删除掉。

static void  AppTaskStart (void *p_arg)
{OS_ERR err;(void)p_arg;CPU_Init();#if OS_CFG_STAT_TASK_EN > 0uOSStatTaskCPUUsageInit(&err);
#endif#ifdef CPU_CFG_INT_DIS_MEAS_ENCPU_IntDisMeasMaxCurReset();
#endifOSTaskCreate((OS_TCB       *)&AppTaskUpdateTCB,            (CPU_CHAR     *)"App Task Update",(OS_TASK_PTR   )AppTaskGUIUpdate,(void         *)0,(OS_PRIO       )APP_CFG_TASK_UPDATE_PRIO,(CPU_STK      *)&AppTaskUpdateStk[0],(CPU_STK_SIZE  )APP_CFG_TASK_UPDATE_STK_SIZE / 10,(CPU_STK_SIZE  )APP_CFG_TASK_UPDATE_STK_SIZE,(OS_MSG_QTY    )1,(OS_TICK       )0,(void         *)0,(OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),(OS_ERR       *)&err);OSTaskCreate((OS_TCB       *)&AppTaskCOMTCB,           (CPU_CHAR     *)"App Task COM",(OS_TASK_PTR   )AppTaskCOM,(void         *)0,(OS_PRIO       )APP_CFG_TASK_COM_PRIO,(CPU_STK      *)&AppTaskCOMStk[0],(CPU_STK_SIZE  )APP_CFG_TASK_COM_STK_SIZE / 10,(CPU_STK_SIZE  )APP_CFG_TASK_COM_STK_SIZE,(OS_MSG_QTY    )2,(OS_TICK       )0,(void         *)0,(OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),(OS_ERR       *)&err);OSTaskCreate((OS_TCB       *)&AppTaskUserIFTCB,            (CPU_CHAR     *)"App Task UserIF",(OS_TASK_PTR   )AppTaskUserIF,(void         *)0,(OS_PRIO       )APP_CFG_TASK_USER_IF_PRIO,(CPU_STK      *)&AppTaskUserIFStk[0],(CPU_STK_SIZE  )APP_CFG_TASK_USER_IF_STK_SIZE / 10,(CPU_STK_SIZE  )APP_CFG_TASK_USER_IF_STK_SIZE,(OS_MSG_QTY    )0,(OS_TICK       )0,(void         *)0,(OS_OPT        )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),(OS_ERR       *)&err);OSTaskDel(&AppTaskStartTCB,&err);while (1){                                        OSTimeDly(100, OS_OPT_TIME_DLY, &err);}
}

编译运行没有错误,至此我们将uCOS-III移植到目标MCU平台的工作就完成了。

4、小结

本篇中我们简单的介绍了uCOS-III移植到目标MCU平台的过程,并对移植后的系统进行了简单的测试。系统的运行与我们预期的一致,移植本身没有问题。

在本篇中我们对PendSV和SysTick中断处理,采用的是修改启动文件startup_stm32f407xx.s来实现的。事实上我们觉得更好的方式是编写一段汇编程序,在PendSV_Handler和SysTick_Handler中断处理函数中调用OS_CPU_PendSVHandler和OS_CPU_SysTickHandler,这样就不用修改startup_stm32f407xx.s和os_cpu_a.asm这两个文件了。当然之所以能如此操作,是因为在startup_stm32f407xx.s文件中PendSV_Handler和SysTick_Handler函数是弱定义。

欢迎关注:

uCOS-III应用开发笔记之一:uCOS-III在STM32的移植相关推荐

  1. FreeRTOS应用开发笔记之一:FreeRTOS在STM32的移植

    FreeRTOS是如今在小型嵌入式领域应用比较广泛的一种实时操作系统.它是一种开源且免费的操作系统,而且移植和使用都非常的简单.在这里我们将学习并移植FreeRTOS. 1.必要的准备 工欲善其事,必 ...

  2. ATECC508A芯片开发笔记(十一):NXP 平台移植ATECCx08 CryptoAuthLib库(I2C)

    目录 ATECC508A芯片开发笔记(十一):NXP 平台移植x08库(I2C) 一.CryptoAuthLib 二.Nxp RT10xx平台上移植CryptoAuthLib 2.1.在官网下载最新的 ...

  3. DW1000开发笔记(三)基于STM32 HAL库裸机工程移植DW1000官方驱动

    系列文章 DW1000开发笔记(一)DW1000芯片概览 DW1000开发笔记(二)使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信 一.官方驱动 Decawave官方提 ...

  4. LwIP应用开发笔记之一:LwIP无操作系统基本移植

    现在,TCP/IP协议的应用无处不在.随着物联网的火爆,嵌入式领域使用TCP/IP协议进行通讯也越来越广泛.在我们的相关产品中,也都有应用,所以我们结合应用实际对相关应用作相应的总结. 1.技术准备 ...

  5. DW1000开发笔记(二)使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信

    本篇详细的记录了如何使用STM32CubeMX配置STM32F103C8T6的硬件SPI外设与DW1000通信,为移植DW1000官方驱动打下基础. 1. 准备工作 硬件准备 开发板 首先需要准备一个 ...

  6. 华大半导体 HC32F4A0 系列开发笔记

    HC32F4A0 系列开发笔记目录 选用芯片 对比STM32的优势 踩过的坑和一些总结: 1--串口空中断bug 2--标志位的寄存器 3--写IAP遇到的问题 4--CPU主频配置 5--RTC时钟 ...

  7. STM32开发笔记77: 内部看门狗长延时的产生

    单片机型号:STM32L053R8T6 开发笔记STM32开发笔记45:看门狗驱动程序的移植介绍了看门狗驱动程序的基本设计方法.今天项目中看门狗的延时时间达到10秒,则实际运行效果只有3秒. 以下是看 ...

  8. DW1000开发笔记(五)DW1000使用轮询方式接收数据

    系列文章 DW1000开发笔记(一)DW1000芯片概览 DW1000开发笔记(二)使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信 DW1000开发笔记(三)基于STM ...

  9. DW1000开发笔记(六)DW1000发送数据并等待另一个DW1000回应

    系列文章 DW1000开发笔记(一)DW1000芯片概览 DW1000开发笔记(二)使用STM32硬件SPI+STM32cubeMX+HAL库测试DW1000通信 DW1000开发笔记(三)基于STM ...

最新文章

  1. [Config]如何利用ConfigurationSettings.AppSettings.GetValues读取配置文件中多个同Key的value...
  2. BSP 二叉树再次讨论
  3. C++位运算详解(转)
  4. AI CC2019软件安装教程
  5. 找出矩阵中绝对值最大的元素及其位置_线性代数之——矩阵范数和条件数
  6. Flask爱家租房--订单支付(支付过程)
  7. C++ 採集音频流(PCM裸流)实现录音功能
  8. SharePoint 上传附件
  9. 检讨:丢了我女儿和项目设计感想
  10. Anaconda下载太慢
  11. 服务器显示跨域请求,出现跨域问题的原因及其解决方法
  12. 同步发电机励磁调节实验原理_发电机组自动控制系统工作原理
  13. FFT蝶形算法的verilog实现专题——从FFT算法的定义开始入手
  14. ae2018怎么打开2019_AE CC 2019新功能全面解析!
  15. 【剖析 | SOFARPC 框架】系列之SOFARPC序列化比较
  16. Spring bean配置单例或多例模式
  17. php ios表情包,php处理APP中emoji表情包的方法
  18. 10-N个你可能不知道的Mixly软件操作小技巧 | Mixly技巧系列
  19. 2021年中国白酒市场现状分析,产量持续下降,利润持续增长,市场集中度提升「图」
  20. Flutter 使用自定义 fluro 路由转场动画实现个性化页面切换

热门文章

  1. day34 数据库入门
  2. UVA 1599 Ideal Path
  3. BZOJ 4819: [Sdoi2017]新生舞会
  4. android 瀑布流
  5. 计算机专业英语基础篇
  6. 数据结构C语言实现—队列操作
  7. 特老的文章:三层应该怎么划分。不知大家还有用否
  8. Windows 程序设计技巧
  9. Leetcode--145. 二叉树的后序遍历(迭代递归)
  10. 和移动对接短信http协议和cmpp协议那个好_python网络爬虫之HTTP原理,爬虫的基本原理,Cookies和代理介绍...