RTT之SysTick做了什么

经过好几天的摸索,终于正常驱动了一个串口设备,并成功移植到雅特力的板子上!当然,还得继续努力把RTT的内核搞清楚,这样才会构建整个项目程序,毕竟项目是有时间限制的。

因为之前接触过只有两个任务的OS,在那个OS中SysTick的用处非常大,一方面是执行一些周期的设备任务,另一方面定时切换线程,是不是RTT也有类似的机制呢??

先从官方文件开始:程序先调用启动文件后,再调用内核文件 components.c 文件中的int $Sub$$main(void),调用rtthread_startup();函数。其调用的函数如下:

RTT之SysTick做了什么_第1张图片

RTT之SysTick做了什么_第2张图片

RTT之SysTick做了什么_第3张图片

drv_common.c中的rt_hw_board_init() 中完成系统时钟设置,为硬件系统提供心跳、串口初始化,将系统输入输出终端绑定
到这个串口,后续系统运行信息就会从串口打印出来。在此函数中调用了 rt_hw_systick_init()函数,设定了系统的工作时间片。实际指向rtconfig.h中的    #define RT_TICK_PER_SECOND 1000。

调用的这几个函数分别位的的.c文件对应关系为:

rt_hw_board_init()      -----------------------------------------         drv_common.c文件中同时属于drivers文件夹

rt_show_version()      -----------------------------------------         kservice.c文件中属于Kernel文件夹

rt_system_timer_init()      -----------------------------------------        timer.c文件中属于Kernel文件夹

rt_system_scheduler_init()      -----------------------------------------        scheduler.c文件中属于Kernel文件夹

rt_system_signal_init()      -----------------------------------------         signal.c文件中属于Kernel文件夹

rt_application_init()      -----------------------------------------        components.c 文件中属于Kernel文件夹

rt_system_timer_thread_init() -----------------------------------------       timer.c文件中属于Kernel文件夹

rt_thread_idle_init()      -----------------------------------------        idle.c 文件中属于Kernel文件夹

rt_hw_spin_lock()      -----------------------------------------     rthw.h 文件中属于include文件夹,变相调用关中断

 rt_system_scheduler_start()      -----------------------------------------        scheduler.c文件中属于Kernel文件夹

可见,rt_hw_board_init() ---->   rt_hw_systick_init()后就启动了SysTick了,看中断里做了什么呢?

void SysTick_Handler(void)
{
    /* enter interrupt */
    rt_interrupt_enter();  //关总中断

    HAL_IncTick();//自增一个全局变量,作为应用的时间基准
    rt_tick_increase();

    /* leave interrupt */
    rt_interrupt_leave();//关中断
}

其中,rt_tick_increase()-------位于clock.c文件中,属于Kernel文件夹;正是自己有疑问的地方,进去一看,果然是进行了内核线程切换,分析如下:首先明白,rt_tick_increase()就是通知系统过去了一个时间片。

/**
 * This function will notify kernel there is one tick passed. Normally,
 * this function is invoked by clock ISR.
 */
void rt_tick_increase(void)
{
    struct rt_thread *thread;

    /* increase the global tick */
#ifdef RT_USING_SMP
    rt_cpu_self()->tick ++;
#else
    ++ rt_tick;  //自增滴答时钟
#endif

    /* check time slice */
    thread = rt_thread_self();//检查线程自身的时间片

    -- thread->remaining_tick;//剩余时间--
    if (thread->remaining_tick == 0)
    {
        /* change to initialized tick */
        thread->remaining_tick = thread->init_tick;//重新分配初始时钟

        thread->stat |= RT_THREAD_STAT_YIELD;

        /* yield */
        rt_thread_yield();//线程挂起,在这里进行了内核线程切换。
    }

    /* check timer */
    rt_timer_check();//在中断中,rt_timer_check()用于检查系统硬件计时器链接列表。
如果存在计时器超时,则将调用相应的超时功能。
如果超时,将从计时器链接列表中删除所有计时器,并在再次启动时将定期计时器添加到计时器链接列表中。
}

基本与自己设想的一样,看来RTOS的内核相似性真的是挺大的。

 

你可能感兴趣的:(嵌入式开发零星时间堆记)