操做系统的Tick仿佛是人的脉搏,不停的向各个器官提供血液。Tick是操做系统实现调度的基础,是分时调度的组成部分。函数
Tick对操做系统尤为重要。例如,操做系统能够为多个任务许以不一样数目的时间片,确保没有一个任务能霸占系统;或者把每一个定时器周期的某个时间范围赋予特定的任务等;还有操做系统提供的各类定时功能,都与Tick有关。ui
在SylixOS中,Tick通常经过芯片自带的Tick定时器或者通用定时器实现。spa
SylixOS系统Tick一般是采用通用定时器的周期性中断实现,一次中断表示一个Tick。操作系统
Tick的初始化在内核启动时被调用,具体调用流程如图2.1所示。线程
l 系统启动时调用API_KernelStart,API_KernelPrimaryStart函数进入系统内核;it
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初始化函数对定时器进行初始化并设置定时时长,使能定时器中断,如程序清单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); }