操作系统的Tick仿佛是人的脉搏,不停的向各个器官提供血液。Tick是操作系统实现调度的基础,是分时调度的组成部分。
Tick对操作系统尤其重要。例如,操作系统可以为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赋予特定的任务等;还有操作系统提供的各种定时功能,都与Tick有关。
在SylixOS中,Tick一般通过芯片自带的Tick定时器或者通用定时器实现。
2.系统Tick实现
SylixOS系统Tick通常是采用通用定时器的周期性中断实现,一次中断表示一个Tick。
Tick的初始化在内核启动时被调用,具体调用流程如图3.1所示。
l 系统启动时调用API_KernelStart,API_KernelPrimaryStart函数进入系统内核;
l 在API_KernelPrimaryStart函数中最后调_KernelPrimaryEntry函数启动内核;
l 在_KernelPrimaryEntry函数中调bspTickInit函数初始化操作系统时钟。
图 3.1 Tick初始化
bspTickInit函数即为SylixOSTick具体实现,其大致流程如图3.2所示。
l 通过API_KernelStartParam函数修改内核启动参数进行配置,将数据保存于全局结构体中。例如:参数“hz=100”表示设置系统Tick频率为10ms;
l 对指定定时器进行初始化,设置定时时长并使能定时器中断;
l 定时器产生中断时会产生调度,在中断处理函数中通知内核Tick。
图3.2 Tick具体实现
Tick初始化函数对定时器进行初始化并设置定时时长,使能定时器中断,如程序清单3.1所示。
程序清单3.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所示。
程序清单3.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); }