• DJYOS 定时器组件硬件接口说明


            1 概述

            DJYOS 的定时器管理,分软件定时器(SoftTimer)和硬件定时器(HardTimer)两部分。软件定时器组件,允许用户申请任意多个定时器(受内存容量限制),依用户所需要的精度,它的时钟源可以选择系统 tick,定时精度也不超过 tick 间隔;也可以选择硬件定时器,其精度只受硬件定时器本身和中断响应延迟的限制。

            如何选择 tick 还是硬件定时器做时基呢?软件定时器初始化时,如果参数选择 CN_TIMER_SOURCE_TICK。即: ModuleInit_SoftTimer(CN_TIMER_SOURCE_TICK);则表明使用 tick 作为时钟源。如果选择 CN_TIMER_SOURCE_HARD,则使用硬件定时器作为时钟源。如果用硬件定时器,则需要确认在“工程目录\\src\user\critical\critical.c”文件的 critical 函数中调用 ModuleInit_HardTimer 函数的代码行不被注释。此时,ModuleInit_SoftTimer 函数会调用HardTimer 模块的功能,申请硬件定时器,如果申请不到,则返回错误。

            HardTimer 组件并不是SoftTimer 组件专用的,它可以管理除 Tick 定时器以外的全部硬件定时器,提供通用的高精度定时服务。HardTimer 模块标准化了硬件接口,如果你需要使用硬件定时器服务,就需要编写标准接口函数,否则,本文剩余部分,就不需要阅读了。当然,软件所需要的定时功能千差万别,硬件定时器提供的支持也百花齐放,HardTimer 模块不可能穷举所有可能,它只提供通用的定时服务。如果你所需要的定时功能咱没有提供, 你大可绕开 timer 模块,天马行空,怎么写驱动都行。

            关于 DJYOS 定时器组件的使用方法可详见《都江堰操作系统用户手册》的“定时器组件”章节。

            2  移植的源码目录

            如果使用 CPU 内置定时器,在 eclipse 工程中的目录中将有如下文件:src->OS_code->bsp->cpudrv->src->cpu_peri_timer.c。相应的头文件目录为:src->OS_code->bsp->cpudrv-> src->cpu_peri_timer.h 。在文件系统(硬盘)中的目录结构是: djysdk\djysrc\bsp\cpudrv\cpu_name\src\cpu_peri_timer.c。下面阐述怎么编写这两个文件。

            3 实现标准硬件接口函数

            DJYOS 定时器底层驱动需要提供四个函数,分别ModuleInstall_HardTimer(HardTimer初始化)及硬件定时器模块需要调用的三个钩子函数。

            3.1 硬件定时器初始化

    void ModuleInstall_HardTimer(void);

    头 文 件 : cpu_peri_timer.h 
    参数:无。
    返回值:无。
    说明:

    该函数功能为定时器初始化,需要完成以下四个工作:
    1、使能定时器时钟;
    2、配置时钟频率;
    3、对定时器芯片结构体 tagTimerChip 成员赋值;
    4、调用系统函数 TimerHard_RegisterChip 将该定时器注册到系统时钟芯片中。

            tagTimerChip 在 timer_hard.h 中定义,具体如下:

    1. struct tagTimerChip
    2. {
    3. char *chipname; //chip名字,必须为静态型
    4. fnTimerHardAlloc timerhardalloc; //分配定时器
    5. fnTimerHardFree timerhardfree; //释放定时器
    6. fnTimerHardCtrl timerhardctrl ; //操作控制定时器
    7. };

            tagTimerChip 中 fnTimerHardAlloc、fnTimerHardFree、fnTimerHardCtrl 为上述提及的三个钩子函数指针。

            3.2 分配定时器


    typedef ptu32_t (*fnTimerHardAlloc)(u32 cycle,fnTimerIsr timerisr);

    头文件: timer_hard.h 参数:

    cycle:指定分配定时器的定时周期,该属性可使用 API 函数进行更改设定(单位:微

    秒)。

    timerisr:用户实现的定时器中断服务函数,定时期限到后,由定时器中断调用。fnTimerIsr的原型为:typedef u32 (*fnTimerIsr)(ufast_t irq_no);其中 irq_no 为定时器对应的中断号。在cpu_peri_int_line.h 中定义了 CPU 所有的中断源对应的中断号,在 critical.c 中定义了常量数组 tg_IntUsed,该数组用于配置实际工程使用到的中断源,详情见 cpu_peri_int_line.h 及critical.c。根据实际使用的定时器编号可通过查看 tg_IntUsed 获得该定时器对应的中断号。另外需要注意的是由于硬件定时器中断属性设置为异步信号,DJYOS 内部已经实现了清中断,因此用户实现的中断服务函数 timerisr 不必清中断。

    返回值:
    NULL 分配不成功,否则返回定时器句柄,定时器句柄数据类型为 ptu32_t,其具体内容由BSP 工程师根据各平台实际情况定义。

    说明:
    分配定时器函数需要完成以下工作:

    1、选出一个可使用的定时器并对其句柄进行复制;
    2、设置定时器属性,默认状态下:停止计数、设置定时器中断为异步中断并将其挂接到DJYOS 的中断系统中,设置定时器周期;
    3、返回定时器句柄。

            3.3 释放定时器

    typedef bool_t (*fnTimerHardFree)(ptu32_t timerhandle);

    头文件: timer_hard.h 
    参数:

    timerhandle,待释放定时器句柄。

    返回值:
    true 成功;false 失败。
    说明:
    该过程基本上是分配的逆向过程,将指定的定时器恢复到分配前的状态,一般要停止计数器、切断中断线等。

            3.4 控制定时器

    typedef bool_t (*fnTimerHardCtrl)(ptu32_t timerhandle,

    enum _ENUM_TIMER_CTRL_TYPE_ ctrlcmd, ptu32_t inoutpara);

    头文件: timer_hard.h 
    参数:

    timerhandle:待操作的定时器句柄;

    ctrlcmd: 操作命令;

    inoutpara:输入输出参数,根据不同的情况而定。
    返回值:

    true 操作成功 ;false 操作失败。
    说明:

    该函数用于实现对某个指定定时器进行特定操作,根据操作码实现各自特定操作,在

    timer_hard.h 中定义了定时器以下操作码如下:

    1. enum _ENUM_TIMER_CTRL_TYPE_
    2. {
    3. EN_TIMER_STARTCOUNT = 0, //使能计数
    4. EN_TIMER_PAUSECOUNT, //停止计数
    5. EN_TIMER_SETCYCLE, //设置周期,单位 us
    6. EN_TIMER_SETRELOAD, //设置定时器为单次触发,还是周期性触发
    7. EN_TIMER_ENINT, //中断使能
    8. EN_TIMER_DISINT, //中断禁止
    9. EN_TIMER_SETINTPRO, //中断属性设置,指将定时器中断设置为实时中
    10. //断 or 异步信号。
    11. EN_TIMER_GETTIME, //获取计时时间,指从设定的周期算起,即
    12. // cycle-剩余时间,表示已经走掉的时间
    13. EN_TIMER_GETCYCLE, //获取定时周期
    14. EN_TIMER_GETID, //获取定时器 ID,采用一个 32 位数表示定时器 ID
    15. //号,其中高 16 位为 intID(中断号) ,低 16 位为
    16. // timerID(定时器号)
    17. EN_TIMER_GETSTATE, //获取定时器状态,在 timer_hard.h 中定义了定时
    18. //器的 5 种状态,详情见 timer_hard.h
    19. };

             在该函数中分别实现上述各个操作码对应的操作功能即可。 中断属性设置(EN_TIMER_SETINTPRO)方法为,当中断属性设置为异步信号,则只需调用系统函数 Int_EvttDisConnect(ufast_t  ufl_line)将该中断设置为异步信号(ufl_line 为中断号);如果需要设置为实时信号,需要先调用系统函数 Int_EvttDisConnect(ufast_t ufl_line)将原来挂接的异步信号中断线断开(由于在分配定时器时默认将定时器中断设置为异步信号), 然后调用系统函数 Int_SettoReal(ufast_t ufl_line)将该定时器中断类型设置为实时信号。如果定时器中断属性设为实时中断,则用户实现的中断服务函数 ISR 中必须清中断,且不能调用任何系统服务;如果设定为异步信号,则无须清中断,且允许调用全部系统调用。

    自定义硬件接口

            DJYOS 定时器组件提供了定时器的通用定时服务,但是软件实际需求的功能千变万化, 有可能 DJYOS 的定时器组件不能完全满足用户的实际需求。由于一般硬件定时器个数通常有多个,用户完全可以根据实际情况将一部分定时器注册到 DJYOS 的定时器组件中,另一部分根据实际需要编写相应的驱动函数提供特殊的服务,例如用于PWM。

  • 相关阅读:
    Swift 并发
    2_里氏替换原则
    网站推广常用的方式
    网站被DDOS攻击怎么办?防护经验!
    mybatis中resultMap与resultType的区别
    第12章 网络安全审计技术原理与应用
    【技术积累】Linux中的命令行【理论篇】【一】
    2.K3S+Rancher之在线安装
    笔记本开启WiFi
    vue2全家桶-vuex
  • 原文地址:https://blog.csdn.net/wangjianzhongfj/article/details/72861557