1.Tick的作用
操作系统的Tick仿佛是人的脉搏,不停的向各个器官提供血液。Tick是操作系统实现调度的基础,是分时调度的组成部分。
Tick对操作系统尤其重要。例如,操作系统可以为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赋予特定的任务等;还有操作系统提供的各种定时功能,都与Tick有关。
在SylixOS中,Tick一般通过芯片自带的Tick定时器或者通用定时器实现。
2.系统Tick实现
SylixOS系统Tick通常是采用通用定时器的周期性中断实现,一次中断表示一个Tick。
Tick的初始化在内核启动时被调用,具体调用流程如图2.1所示。
l 系统启动时调用API_KernelStart,API_KernelPrimaryStart函数进入系统内核;
l 在API_KernelPrimaryStart函数中最后调_KernelPrimaryEntry函数启动内核;
l 在_KernelPrimaryEntry函数中调bspTickInit函数初始化操作系统时钟。
图 2.1 Tick初始化
bspTickInit函数即为SylixOSTick具体实现,其大致流程如图2.2所示。
l 通过API_KernelStartParam函数修改内核启动参数进行配置,将数据保存于全局结构体中。例如:参数“hz=100”表示设置系统Tick频率为10ms;
l 对指定定时器进行初始化,设置定时时长并使能定时器中断;
l 定时器产生中断时会产生调度,在中断处理函数中通知内核Tick。
图2.2 Tick具体实现
Tick初始化函数对定时器进行初始化并设置定时时长,使能定时器中断,如程序清单2.1所示。
程序清单2.1 Tick初始化
VOID bspTickInit (VOID)
{
…
GuiFullCnt = sysClockGet(SYS_PCLK) * 1000 * 1000 / LW_TICK_HZ;
Gui64NSecPerCnt7 = ((1000 * 1000 * 1000 / LW_TICK_HZ) << 7) / GuiFullCnt;
tickETimerInit(HW_ETIMER, GuiFullCnt); /* 系统TICK的频率为LW_TICK_HZ */
API_InterVectorConnect(ulVector,
(PINT_SVR_ROUTINE)__tickTimerIsr,
LW_NULL,
"tick_timer");
API_InterVectorEnable(ulVector);
}
定时器产生中断时,会产生调度,并在中断处理函数中进行内核Tick通知,如程序清单3.2所示。
程序清单2.2 Tick中断服务函数
static irqreturn_t __tickTimerIsr (VOID)
{
etimerIsr(HW_ETIMER);
API_KernelTicksContext(); /* 保存被时钟中断的线程控制块 */
#if TICK_IN_THREAD > 0
API_ThreadResume(htKernelTicks);
#else
API_KernelTicks(); /* 内核 TICKS 通知 */
API_TimerHTicks(); /* 高速 TIMER TICKS 通知 */
#endif /* TICK_IN_THREAD > 0 */
return (LW_IRQ_HANDLED);
}
转载于:https://blog.51cto.com/12380892/1975596