最近项目需要在STM32F103板子上移植uCOS-III系统,移植过程参考安富莱STM32F407之uCOS-III教程,参考网址
移植uCOS-III系统
虽然教程是关于F407的板子,但大体是相同的。为了省事,我直接在原来的工程中加上uCOS-III源代码。首先在工程目录下创建一个uCOS-III文件夹,然后把安富莱的uCOS-III代码拷贝到新建的uCOS-III文件夹中,对应的目录如下:
这里我把原来uCOS-III下Ports和Source目录分开为uCOS-Ports和uCOS-Source。uCOS-User目录存放的是安富莱User目录下文件,是需要自己配置修改的一些文件,这里把bsp.h、bsp.c文件重新更名为bsp_os.h、bsp_os.c,并且原来像诸如ARM-Cortex-M3目录下有多个平台的文件夹:
这里把其他的都删除,只保留RealView下面的文件。然后把这些文件分文件夹添加到原来的工程中,工程结构如下:
uCOS-User目录下文件:
人家F407用的是startup_stm32f429_439xx.s汇编文件,我这里用的是startup_stm32f10x_hd.s,因此还要在这个文件里修改中断向量表,把PendSV_Handler和SysTick_Handler替换为OS_CPU_PendSVHandler和OS_CPU_SysTickHandler:
然后下面定义的地方也需要相应的替换下:
源文件添加完了,别忘了添加头文件的路径:
这样uCOS-III源代码就算添加完成了,但这里有一处源码需要修改,uCOS-PortsARM-Cortex-M3os_cpu_c.c文件:
#include "../../../../Source/os.h"
由于原来文件在uCOS-IIIPortsARM-Cortex-M3GenericRealView目录,这里目录发生变化了,找不到os.h文件,得修改如下:
#include "../../uCOS-Source/os.h"
创建任务
main函数中按照安富莱的例子写:
int main(void)
{
OS_ERR err;
OSInit(&err);
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);
(void)&err;
return (0);
}
AppTaskStart函数中创建其他任务:
static void AppTaskStart (void *p_arg)
{
OS_ERR err;
(void)p_arg;
CPU_Init();
bsp_Init();
BSP_Tick_Init();
#if OS_CFG_STAT_TASK_EN > 0u
OSStatTaskCPUUsageInit(&err);
#endif
#ifdef CPU_CFG_INT_DIS_MEAS_EN
CPU_IntDisMeasMaxCurReset();
#endif
AppTaskCreate();
while (1)
{
if(Sys_RunInfo.PowerDownFlag == 0)
{
Key_Process();
}
OSTimeDly(10, OS_OPT_TIME_DLY, &err);
}
}
创建完其他任务,这个任务只负责按键处理。简单测试代码写好了,赶紧调试一下看看能运行不。
调试
为了调试方便,这里先不拿实际板子调试,先进行软件仿真:
结果发现总是过不了OSInit函数,总卡在CPU_TS_TmrRd函数最后:
查了查相关资料,这是计算时间戳相关的函数,难道是软件仿真不能计算任务的执行时间,以及CPU利用率?那么关闭这项功能试试,打开cpu_cfg.h文件:
原来宏CPU_CFG_TS_32_EN是打开的,把它关掉:
#define CPU_CFG_TS_32_EN DEF_DISABLED
再编译,居然出错了:
#35: #error directive: "CPU_CFG.H, CPU_CFG_TS_32_EN must be Enabled (1) to use time stamp feature"
定位到os.h文件中报错地方:
看来关闭CPU_CFG_TS_EN宏就必须同时关闭OS_CFG_TS_EN宏,那么CPU_CFG_TS_EN宏是哪来的呢,在cpu_core.h文件中有相关配置:
关闭了CPU_CFG_TS_32_EN就意味着CPU_CFG_TS_EN宏也关闭,那么要不报错,就得关闭OS_CFG_TS_EN宏,在os_cfg.h文件中:
#define OS_CFG_TS_EN DEF_DISABLED
改完再编译,又报错了:
#error directive: “OS_CFG.H, OS_CFG_TS_EN must be Enabled (1) to measure scheduler lock time”
再次定位问题,还是在os.h文件:
看来还得关闭OS_CFG_SCHED_LOCK_TIME_MEAS_EN宏,因为这个宏是包含测量调度锁定时间的代码,同样修改os_cfg.h文件:
#define OS_CFG_SCHED_LOCK_TIME_MEAS_EN DEF_ENABLED
再次编译,还是报错:
error: #20: identifier "OSIntDisTimeMax" is undefined
这次定位到os_dbg.c文件:
是因为CPU_CFG_INT_DIS_MEAS_EN宏导致错误,而在cpu_cfg.h文件中开启了这个宏:
再把这个宏屏蔽掉,如下图:
这次编译终于没有错误了,赶紧调试一下吧,这次终于通过了OSInit函数,这样便可以进行软件仿真了:
记住,如果要测试任务调度时间和CPU使用率的话还是要把上面关掉的宏都打开的,只有去真正板子上进行测试了。
上一篇:STM32不用固件库易产生的问题:Undefined symbol SystemInit
下一篇:编写STM32项目遇到的报错
推荐阅读最新更新时间:2024-11-03 05:38
设计资源 培训 开发板 精华推荐
- 使用 LTC2380IDE-16、16 位、2Msps SAR ADC 的典型应用
- 开关稳压电源
- AM2M-1212S-NZ 12 Vout、2W 单路输出 DC-DC 转换器的典型应用
- LT3091IDE 用于极低输出电压的低压差操作的典型应用
- 具有 12V VDD 输入的 LTC2945IMS-1 3.3V 输入电源监视器的典型应用
- LT1021DCS8-7 用于处理更高负载电流的电压基准的典型应用
- 使用 Infineon Technologies AG 的 OM7641SM 的参考设计
- DER-43 - 1.8W非隔离电源
- 原神9cm小尺子
- 附开发全流程#100米±2mm高精度激光测距仪