完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
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文件夹下的EvalBoardsSTSTM32F429II-SKuCOS-III目录下的一些文件拷贝到我们的项目中。具体如下图红框中所示: 一般来说我们可以拷贝这8个文件直接使用就可以,但并不说明这8个文件是必须的。其中一些配置文件在系统中会引用到,所以文件名称不要改,而且配置参数按需设定。其他文件实际上可以根据我们的意愿修改。为简便起见,我们还可以复制两个文件,在EvalBoardsSTSTM32F429II-SKBSP目录之下的bsp文件: 其实,这两个文件与具体硬件联系紧密,一般需要自己编写,不过因为我们知识移植,所以有几个函数我们可以直接拿过来使用,我们将其复制过来加以修改。 文件已经准备好了,接下来就是将其移植到我们的项目中,将uCOS-III下的核心代码添加到项目中,如下: 同时将uC-CPU和uC-LIB文件夹下的内容添加到项目中,具体如下: 然后,将我们从例程中复制的相关文件也添加到项目中,具体如下: 然后修改项目属性中的文件引用路径: 到这了,工程项目就已经创建完成了,但并不可用,此时若编译会出现许多错误。因为例程使用的是标准库,而我们使用了HAL库,据此首先要将bsp.h文件中的#include 还有一个重要的修改,那就是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 > 0u OSStatTaskCPUUsageInit(&err); #endif #ifdef CPU_CFG_INT_DIS_MEAS_EN CPU_IntDisMeasMaxCurReset(); #endif OSTaskCreate((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函数是弱定义。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1614 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1541 浏览 1 评论
970 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
682 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1592 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 19:39 , Processed in 0.786255 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号