Rt-thread源码剖析(2)——时钟与定时器

前言

        时钟是所有系统工作的心脏,单片机有自己的主频,每一步逻辑算术运算都发生在时钟信号的翻转时刻;RTOS自然也有自己的时钟系统,本文着眼于RTT的系统时钟以及定时器两个方向对RTT的内核进行阐述

系统时钟

        RTOS的时钟是线程运行的最小时间片,也是系统调度发生的最小单位,接下来我们依次来看OS tick从哪来,怎么起作用

系统时钟的源头

        在rtt_port.c内,MCU厂商会在此通过自己的硬件时钟(mchtimer)设置一个周期性的中断,在这个硬件中断中,调用 rt_tick_increase()接口,实现tick的自增

        

        需要注意的是,RT_TICK_PER_SECOND是定义在rtconfig.h中的一个常量,因此,在这个硬件中断中,你需要根据自身MCU的主频来设置相应的中断触发间隔。

时钟增长做了什么

        在硬件时钟的中断中,除了将下一次中断触发的时间设置成一个预期的时间点,其他只调用了rt_tick_increase();我们看一下他做了什么

void rt_tick_increase(void)
{
    struct rt_thread *thread;
    rt_base_t level;

    RT_OBJECT_HOOK_CALL(rt_tick_hook, ());

    level = rt_hw_interrupt_disable();

    /* increase the global tick */
#ifdef RT_USING_SMP
    rt_cpu_self()->tick ++;
#else
    ++ rt_tick;
#endif /* RT_USING_SMP */

    /* 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;

        rt_hw_interrupt_enable(level);
        rt_schedule();
    }
    else
    {
        rt_hw_interrupt_enable(level);
    }

    /* check timer */
    rt_timer_check();
}

概括来说,当OS tick增长时,会依次进行以下操作:

        1.如果你注册了tick hook,那么会自动执行

        2.禁用全局中断

        3.全局变量rt_tick自增

        4.获取当前运行线程的句柄,将其剩余时间减少一个tick

        5.如果当前运行线程剩余时间为0,则打开全局中断,进行一次线程调度

        6.打开全局中断

        7.检查是否有定时器超时

关于线程调度的详细内容,会展其他文章内进行展开,接下来着重讲一下第7点,与定时器有关的内容

定时器

定时器结构体

        首先我们来看下timer struct的源码,结构体的成员就是创建时需要传入的参数

struct rt_timer
{
    struct rt_object parent;                            /**< inherit from rt_object */

    rt_list_t        row[RT_TIMER_SKIP_LIST_LEVEL];

    void (*timeout_func)(void *parameter);              /**< timeout function */
    void            *parameter;                         /**< timeout function's parameter */

    rt_tick_t        init_tick;                         /**< timer timeout tick */
    rt_tick_t        timeout_tick;                      /**< timeout tick */
};
typedef struct rt_timer *rt_timer_t;

        首先的第一个成员是rt_object parent,该成员就是本系列第一篇文章中提到的内核成员的公共部分,在此不再展开

        其次需要传入超时回调函数,回调函数所需的参数以及超时时间

这里展开一下row[RT_TIMER_SKIP_LIST_LEVEL];

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值