STM32F103移植uCOS-III,keil4调试卡在CPU_TS_TmrRd函数过不去

最近项目需要在STM32F103板子上移植uCOS-III系统,移植过程参考安富莱STM32F407之uCOS-III教程,参考网址

  1. 移植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目录文件
    这里把其他的都删除,只保留RealView下面的文件。然后把这些文件分文件夹添加到原来的工程中,工程结构如下:
    工程结构
    uCOS-User目录下文件:
    uCOS-User目录下
    人家F407用的是startup_stm32f429_439xx.s汇编文件,我这里用的是startup_stm32f10x_hd.s,因此还要在这个文件里修改中断向量表,把PendSV_Handler和SysTick_Handler替换为OS_CPU_PendSVHandler和OS_CPU_SysTickHandler:
    替换中断向量表
    然后下面定义的地方也需要相应的替换下:
    替换中断定义
    源文件添加完了,别忘了添加头文件的路径:
    工程配置头文件
    头文件路径
    这样uCOS-III源代码就算添加完成了,但这里有一处源码需要修改,uCOS-Ports\ARM-Cortex-M3\os_cpu_c.c文件:
#include  "../../../../Source/os.h"

由于原来文件在uCOS-III\Ports\ARM-Cortex-M3\Generic\RealView目录,这里目录发生变化了,找不到os.h文件,得修改如下:

#include  "../../uCOS-Source/os.h"
  1. 创建任务
    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);
    }
}

创建完其他任务,这个任务只负责按键处理。简单测试代码写好了,赶紧调试一下看看能运行不。

  1. 调试
    为了调试方便,这里先不拿实际板子调试,先进行软件仿真:
    仿真调试
    结果发现总是过不了OSInit函数,总卡在CPU_TS_TmrRd函数最后:
    卡在CPU_TS_TmrRd
    查了查相关资料,这是计算时间戳相关的函数,难道是软件仿真不能计算任务的执行时间,以及CPU利用率?那么关闭这项功能试试,打开cpu_cfg.h文件:
    关闭CPU_CFG_TS_32_EN
    原来宏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文件中报错地方:
os.h文件
看来关闭CPU_CFG_TS_EN宏就必须同时关闭OS_CFG_TS_EN宏,那么CPU_CFG_TS_EN宏是哪来的呢,在cpu_core.h文件中有相关配置:
CPU_CFG_TS_EN宏
关闭了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.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文件:
OSIntDisTimeMax未定义
是因为CPU_CFG_INT_DIS_MEAS_EN宏导致错误,而在cpu_cfg.h文件中开启了这个宏:
CPU_CFG_INT_DIS_MEAS_EN宏
再把这个宏屏蔽掉,如下图:
关闭CPU_CFG_INT_DIS_MEAS_EN
这次编译终于没有错误了,赶紧调试一下吧,这次终于通过了OSInit函数,这样便可以进行软件仿真了:
通过OSInit函数
记住,如果要测试任务调度时间和CPU使用率的话还是要把上面关掉的宏都打开的,只有去真正板子上进行测试了。

猜你喜欢

转载自blog.csdn.net/xinxin_2011/article/details/84852306