UCOSIII中时钟系统的移植

序言
FreeRTOS的代码写得真的像是一坨坨的shit,我一点看的欲望都没有。相比之下,UCOSIII的代码写得就好看多了,我看着看着就看回了UCOSIII,今天我重点看了移植部分与滴答定时器有关的内容,下面我就来表达一下我是如何理解这个部分内容的,本篇文章主要分为如下两个部分
- CM3的滴答定时器介绍
- 将滴答定时器用作UCOSIII的系统时钟
CM3滴答定时器介绍
SysTick 是一 个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值。下图展示了与SysTick相关的寄存器

- SysTick有两种时钟源可以选择:内核时钟、外部时钟,通过图中CLKSOURCE位控制;
- 当计数值从1跳到0时,会触发一个异常,如果想要使能这个异常,需要将TICKINT置位;
- 通过将Enable置位使能定时器;
将滴答定时器用作UCOSIII的系统时钟
这是一个移植的过程,下面是CM3的中断服务函数在启动文件的中断向量表里,同时也是UCOSIII的心跳函数,我们将二者绑定
void SysTick_Handler (void)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
OSIntNestingCtr++; /* Tell uC/OS-III that we are starting an ISR */
CPU_CRITICAL_EXIT();
OSTimeTick(); /* Call uC/OS-III's OSTimeTick() */
OSIntExit(); /* Tell uC/OS-III that we are leaving the ISR */
}
其实SysTick_Handler在本来的UCOSIII中叫做OS_CPU_SysTickHandler,按照源码注释中的建议,我应该通过修改启动文件把这个函数名放到中断向量表里,但是我还是倾向于修改系统文件,而不是芯片文件,毕竟我是要将系统移植到芯片上,而不是将芯片移植到系统上,所以我没有改动启动文件,而是改动了系统文件,把OS_CPU_SysTickHandler换成了启动文件中的SysTick_Handler。当SysTick异常发生的时候,这个函数就会被执行,心脏准备好了,下面我们要去配置这个心脏并且让它跳动起来
void OS_CPU_SysTickInit (CPU_INT32U cnts)
{
CPU_INT32U prio;
CPU_REG_NVIC_ST_RELOAD = cnts - 1u;
/* Set SysTick handler prio. */
prio = CPU_REG_NVIC_SHPRI3;
prio &= DEF_BIT_FIELD(24, 0);
prio |= DEF_BIT_MASK(OS_CPU_CFG_SYSTICK_PRIO, 24);
CPU_REG_NVIC_SHPRI3 = prio;
/* Enable timer. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_CLKSOURCE |
CPU_REG_NVIC_ST_CTRL_ENABLE;
/* Enable timer interrupt. */
CPU_REG_NVIC_ST_CTRL |= CPU_REG_NVIC_ST_CTRL_TICKINT;
}
这是一个与名字与UCOSIII绑定,内容与CPU相关的函数,主要作用就是配置SysTick,它的形参是cnts,这是SysTick的重装载值,是需要我们计算的,所以我自己又写了一个函数用来计算这个重装载值,如下所示
CPU_INT32U SysTickCntCacul (void)
{
return 72000000/OSCfg_TickRate_Hz;
}
OSCfg_TickRate_Hz是我们期望的操作系统心跳频率,也就是一秒钟SysTick要发生多少次异常,我们设为N次,那么跳一次的时间就是1/N秒,设SysTick频率为Rate,也就是一秒钟有Rate次计数,那么1/N秒就有Rate/N次计数。这里Rate是72000000,是我配置的。
下面我们让心脏跳起来,但是我到底在哪里启动呢?我觉得系统心率和系统是紧紧地绑在一起的,所以我把它放在了OSInit()里面。
注:我有个顾虑就是把心跳启动函数放在OSInit()里面是否合适,目前看来没什么问题,如果有哪位小伙伴看出什么问题希望指出来,谢谢!!!
浙公网安备 33010602011771号