SylixOS 系统Tick实现

1.Tick的做用

操做系统的Tick仿佛是人的脉搏,不停的向各个器官提供血液。Tick是操做系统实现调度的基础,是分时调度的组成部分。函数

Tick对操做系统尤为重要。例如,操做系统能够为多个任务许以不一样数目的时间片,确保没有一个任务能霸占系统;或者把每一个定时器周期的某个时间范围赋予特定的任务等;还有操做系统提供的各类定时功能,都与Tick有关。ui

在SylixOS中,Tick通常经过芯片自带的Tick定时器或者通用定时器实现。spa

2.系统Tick实现

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);
}