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

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个文件夹,分别是EvalBoardsuC-CPUuC-LIBuCOS-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函数是弱定义。

欢迎关注:

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

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

相关文章

外设驱动库开发笔记10:SHT2x系列温湿度传感器驱动

温湿度检测是嵌入式编程中经常应用到的一项功能。在我们的产品中亦经常使用。SHT2x系列温湿度传感器作为一种高精度低成本的集成模块&#xff0c;一直应用于我们的产品中。在这里我们讨论如何封装SHT2x系列温湿度传感器的驱动。 1、功能概述 SHT20配有一个全新设计的CMOSens芯…

Modbus协议栈应用实例之二:Modbus RTU从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将使用协议栈实现一个Modbus RTU从站应用。 1、何为RTU从站 Modbus协议是一…

外设驱动库开发笔记11:SHT3x系列温湿度传感器驱动

在我们的产品中经常会遇到温湿度检测的需求。可以用于检测温湿度的传感器元件也有很多。我们经常使用的SHT各系列数字温湿度传感器来实现应用需求。在这里我们将设计并实现SHT3x系列温湿度传感器的驱动。 1、功能概述 SHT3x系列温湿度传感器是适用于各种应用的高品质湿度传感…

LwIP应用开发笔记之十:LwIP带操作系统基本移植

现在&#xff0c;TCP/IP协议的应用无处不在。随着物联网的火爆&#xff0c;嵌入式领域使用TCP/IP协议进行通讯也越来越广泛。在我们的相关产品中&#xff0c;也都有应用&#xff0c;所以我们结合应用实际对相关应用作相应的总结。 1、技术准备 我们采用的开发平台是STM32F407…

ThreadX应用开发笔记之一:移植ThreadX到STM32平台

现在一些小型系统中也往往有多任务处理的需求&#xff0c;这就为实时操作系统提供了用武之地。事实上国内外各种各样的RTOS有很多&#xff0c;而且基本都在走开源的路线&#xff0c;ThreadX也不例外&#xff0c;在这一篇中我们就来学习ThreadX初步应用并将其移植到STM32平台中。…

外设驱动库开发笔记12:TSEV01CL55红外温度传感器驱动

有时候我们需要检测一些无法直接接触的器件的温度。为了实现这一需求&#xff0c;我们通常会选择红外温度传感器来实现这一功能。考虑到复用的问题&#xff0c;我们一般会将操作元器件的代码抽象为驱动函数以备调用。这里我们就来设计并实现TSEV01CL55红外温度传感器的驱动。 …

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

FreeRTOS是如今在小型嵌入式领域应用比较广泛的一种实时操作系统。它是一种开源且免费的操作系统&#xff0c;而且移植和使用都非常的简单。在这里我们将学习并移植FreeRTOS。 1、必要的准备 工欲善其事&#xff0c;必先利其器&#xff0c;在开始学习和移植之前&#xff0c;相…

外设驱动库开发笔记13:MLX90614红外温度传感器驱动

红外温度传感器一般用于非接触式的温度检测。在我们的系统中经常会有这样的需求。所以我们将其设计为通用的驱动库以备复用。这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现。 1、功能概述 MLX90614是一种红外温度计&#xff0c;用于非接触式温度测量。红外测温是根…

Modbus协议栈应用实例之三:Modbus TCP客户端应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们将解说如何使用协议栈实现一个Modbus TCP客户端。 1、何为TCP客户端 Modbus…

Modbus协议栈应用实例之四:ModbusTCP服务器应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来简述如何使用协议栈实现一个Modbus TCP服务器应用。 1、何为TCP服务器 Mo…

外设驱动库开发笔记14:DS18B20温度变送器驱动

在一时候我们需要相对简单的检测温度信号&#xff0c;而DS18B20就是一款功能和应用都相对简单的温度传感器&#xff0c;通过单线就可以实现检测温度信号的需求。这一篇我们就来实现操作DS18B20获取温度数据的驱动。 1、功能概述 DS18B20是常用的数字温度传感器&#xff0c;其…

Modbus协议栈应用实例之五:Modbus ASCII主站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来使用协议栈实现Modbus ASCII主站应用。 1、何为ASCII主站 我们知道Modbus…

Modbus协议栈应用实例之六:Modbus ASCII从站应用

自从开源了我们自己开发的Modbus协议栈之后&#xff0c;有很多朋友建议我针对性的做几个示例。所以我们就基于平时我们的应用整理了几个简单但可以说明基本的应用方法的示例&#xff0c;这一篇中我们来使用协议栈实现Modbus ASCII从站应用。 1、何为ASCII从站 我们知道Modbus…

外设驱动库开发笔记15:DHT11温湿度传感器驱动

与DS18B20一样DHT11也是采用单总线&#xff0c;但所不同的是DHT11可同时实现温度和湿度的检测。在我们的产品中经常使用它来检测环境的温湿度信息。这一篇我们将设计并封装DHT11的驱动程序&#xff0c;以方便重复使用。 1、功能概述 DHT11数字温湿度传感器是一款含有已校准数…

外设驱动库开发笔记16:MS5536C压力变送器驱动

压力检测也是经常会遇到的需求&#xff0c;比如环境压力或者低压气体等都会用到压力检测。这类检测压力都比较低&#xff0c;一般不会超过大气压&#xff0c;有时甚至是负压。这一篇我们要讨论的MS5536C就属于这类器件。接下来我们将设计并实现MS5536C的驱动。 1、功能概述 M…

外设驱动库开发笔记17:MS5803压力变送器驱动

很多时候我们需要检测被控对象的绝对压力&#xff0c;而且在我们的多款产品中也有这样的需求。当然检测绝对压力的传感器有很多&#xff0c;我们经常使用MS5803来实现压力检测。本篇中我们将设计并实现MS5803系列压力传感器的驱动。 1、功能概述 MS5803系列产品包含压阻传感器…

通讯接口应用笔记1:RS485通讯上下拉电阻的选择

RS485是一种常见的通讯接口方式&#xff0c;在我们的实际产品中也是多次使用。但我们平常并不会去过多考虑某一实现的细节问题&#xff0c;不过最近我们遇到了一个因如上下拉电阻的选择问题而造成的通讯故障&#xff0c;所以在这一片中我们来讨论一下RS485总线上下拉电阻的选择…

外设驱动库开发笔记18:MS5837压力变送器驱动

绝对压力的检测是常见的需求。在我们的系统中也常常会遇到。而MS5837压力传感器也是我们进场会采用的方案。在这篇里我们将讨论并实现MS5837压力传感器的驱动。 1、功能概述 MS5837压力传感器是一种可用于电路板上&#xff0c;适用于检测10-1200mbar压力范围的传感器&#xf…

外设驱动库开发笔记19:BMP280压力温度传感器驱动

压力和温度监测在嵌入式系统开发中是非常常见的需求&#xff0c;特别是对环境大气压力和温度的检测需求就更常见了。我们一般都会选择一些封装较小操作比较方便的压力传感器。BMP280就是满足这一要求的器件。在这一篇中我们将设计并实现BMP280的驱动。 1、功能概述 BMP280是一…

一个简单的空气质量数据监测站项目

大气质量数据监测站用于测试空气质量监测及数据采集&#xff0c;实现野外或者室内空气质量的检测。并通过网络将数据上传到OneNet​显示。​ 1、项目概述 本项目是一个定制项目&#xff0c;要求采集大气的压力、温度、湿度、PM25、位置等数据并上传到指定的后台服务器。但有时…