潍坊住房与城乡建设局网站,网站建设推销话术案例,杭州自助建站模板下载,广州网站 服务器建设uCOS-III实时操作系统在MCU平台被广泛使用#xff0c;在这里我们将简单的记录如何将uCOS-III实时操作系统移植到目标平台上并运行。
1、必要的准备
在开始uCOS-III实时操作系统的移植前#xff0c;我们还需要做一些必要的准备#xff0c;如确定目标板、准备目标工程及uCOS…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工具配置硬件然后生成一个基础的项目。
2、uCOS-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_freqHAL_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函数是弱定义。
欢迎关注