SylixOS最小系统开发(二)

本文详细介绍了MPC8313芯片中系统Tick和高速定时器的实现原理与过程。通过Decrementer寄存器触发异常实现Tick中断,进而构建系统Tick机制。高速定时器则通过读取Decrementer寄存器值,精确统计比Tick更小的时间单位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

  1. 系统Tick

    MPC8313芯片的Tick实现比较特殊,因为在MPC8313芯片中存在名为Decrementer的寄存器,如图 1.1 Decrementer寄存器所示。

    图 1.1 Decrementer寄存器

    Decrementer寄存器中保存的数据会每4个总线周期减1,当Decrementer寄存器递减到0时,触发Decrementer异常,CPU会执行异常服务程序。Decrementer的异常服务函数需要在startup.S文件中设置,如图 1.2 startup.S所示。

    图 1.2 startup.S

  2. Decrementer异常流程解析

    第一步:当Decrementer寄存器递减到0时,触发Decrementer异常,CPU会执行异常服务程序,系统通过异常向量表跳转到archDecrementerInterruptEntry函数。

    第二步:archDecrementerInterruptEntry函数会执行archDecrementerInterruptHandle函数,在archDecrementerInterruptHandle中会对Decrementer寄存器进行设置并调用系统的中断服务函数。

    第三步:系统的中断服务函数会根据archDecrementerInterruptHandle传入的用户注册的伪中断向量查找用户注册的Tick中断服务函数。

  3. Tick实现

    根据上文所述,可以看出MPC8313的系统Tick可以在Decrementer寄存器的基础之上实现。由于Decrementer寄存器的控制接口已经在PowerPC的系统Base中实现,所以笔者无需自己实现,只需要调用系统接口即可。

    Tick的实现分以下三个步骤:

    第一步:使用非已有中断向量号并且大于255的非负数作为Tick的伪中断向量注册中断,如图 1.3 注册Tick中断所示。

    图 1.3注册Tick中断

    第二步:声明archDecrementerInit函数,如图 1.4 声明archDecrementerInit所示

    图 1.4声明archDecrementerInit

    第三步:初始化Decrementer,如图 1.5 初始化Decrementer所示

    图 1.5初始化Decrementer

  4. 高速定时器

    由于系统Tick是基于Decrementer寄存器实现的,所以高速定时器也需要基于Decrementer寄存器实现。

  5. 高速定时器原理简述

    高速定时器实质上是为了补偿系统Tick的不足,用于统计比一个Tick粒度更小的时间。在MPC8313中笔者通过读取Decrementer寄存器中的值来实现高速定时器的功能。

  6. 高速定时器的实现

    由于Decrementer寄存器无状态位可读取,无法通过读取硬件获得是否产生了Tick中断,因此在base中添加了状态全局变量_G_bTickinterTag,并且在系统进入archDecrementerInterruptHandle时把_G_bTickinterTag置为LW_TRUE。

    高速定时器在bspLib.c下的bspTickHighResolution函数实现,如程序清单 2.1 高速定时器所示。

    程序清单 2.1高速定时器

    VOIDbspTickHighResolution (struct timespec *ptv)
    
    {
    
        REGISTER UINT32uiCntCur,uiDone;
    
        ULONG    ulCPUId =LW_CPU_GET_CUR_ID();
    
    
        uiCntCur = ppcGetDEC ();
    
        uiDone =GuiFullCnt - uiCntCur;
    
    
    /*
    
    * 由于Decrementer寄存器无状态位可读取,无法通过读取硬件获得是否产生
    
    * 了Tick中断,因此在base中添加了状态全局变量_G_bTickinterTag
    
    */
    
        if (_G_bTickinterTag[ulCPUId] ==LW_TRUE) {
    
    /*
    
    * 这里由于 TICK 没有及时更新, 所以需要重新获取并且加上一个 TICK 的时间
    
    */
    
            uiCntCur= ppcGetDEC ();
    
            uiDone =GuiFullCnt - uiCntCur;
    
    
            if (uiCntCur != 0) {
    
                 uiDone +=GuiFullCnt;
    
            }
    
        }
    
    
        ptv->tv_nsec += (LONG)((Gui64NSecPerCnt7 * uiDone) >> 7);
    
        if (ptv->tv_nsec >= 1000000000) {
    
        ptv->tv_nsec -= 1000000000;
    
        ptv->tv_sec++;
    
        }
    
    }

     

  7. 参考资料

转载于:https://my.oschina.net/doumenghan/blog/955572

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值