Timer使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 04/18/2023

    1. 概述

    ‌定时器(Timer)‌是一种在计算机和微控制器系统中用于测量时间间隔或产生精确定时事件的硬件模块。定时器的基本工作原理是通过一个时钟源驱动计数器,当计数器达到预设值时,产生一个事件,通常是通过中断来通知处理器。

    2. 关键字说明

    • PM-timer

      由PM-domain供电的timer。

    • NonPMtimer

      由NonPM domain供电的timer。

    • OneShoot mode

      Timer的一种工作模式,timer到达时间后值触发中断。

    • RunLoop mode

      Timer的一种工作模式,timer触发后将重置计数核循环触发。

    3. 功能描述

    无论是PM-timer还是NonPMtimer,定时器的使用有这相同的步骤,从开发角度来看,有五个环节

    1. 注册定时器

    2. 开启定时器

    3. 系统执行定时器的中断函数和调用定时器的处理函数

    4. 关闭定时

    5. 注销定时器

    除此之外,使用timer的时候还需要考虑到以下一些因素:

    • 硬件数量

      • PM-timer 8个

      • NonPM-timer 4个

    • CLK 介绍

      • PM-timer0 ~ PM-timer3 和 NonPM-timer 采用同一个时钟,默认频率12MHz, PM-timer4 ~ PM-timer7各自采用不同的时钟。

      • PM-timer0 ~ PM-timer3 各自使用不同的硬件中断号,PM-timer4 ~ PM-timer7 采用同一个硬件中断号。

    • Limitation 介绍

      • 软件限制:riscv侧和arm侧不能同时使用同一个timer,会导致中断混乱。
    • 工作模式介绍

      • Timer 有两种工作模式,一种是oneshoot 模式,另一种是 RunLoop 模式。

    4. 硬件连接介绍

    SOC内置

    5. Uboot用法介绍

    目前uboot下未实现timer驱动。

    6. Kernel用法介绍

    6.1. Kernel Config配置

    1. Enable 对应的驱动模块:

      在编译kernel时需要选择的配置如下:

      Device Drivers-->
          [*] SStar SoC platform drivers-->
              [*] Sigmastar Timer Driver
      

    6.2. Dts配置

    可以通过配置dtsi中pm-timer0 ~ pm-timer7 和nonpm-timer0 ~ nonpm-timer3设定各个timer的基本参数。dtsi的参数展示如下:

    1.    PMtimer0: pm-timer0 {
    2.        compatible = "sstar,timer";
    3.        reg = <0x0 0x1F006040 0x0 0x40>;
    4.        interrupts = <GIC_SPI INT_IRQ_PM_TIMER_OR IRQ_TYPE_LEVEL_HIGH>;
    5.        clocks = <&CLK_mcu_pm>;
    6.        status = "disabled";
    7.    };
    8.    ...
    9.
    10.
    11.   nonpm-timer1 {
    12.       compatible = "sstar,timer";
    13.       reg = <0x0 0x1F2CDE80 0x0 0x40>;
    14.       interrupts = <GIC_SPI INT_IRQ_NONPM_TIMER_1 IRQ_TYPE_LEVEL_HIGH>;
    15.       clocks = <&CLK_mcu>;
    16.       status = "okay";
    17.   };
    18.   ...
    

    如上图展示,pm-timer和nonpm-timer的dts内容类似,其属性包含的属性释义分别为:

    属性 描述 设定值 备注
    compatible 匹配驱动进行驱动注册 "sstar,timer" 禁止修改
    reg 设定寄存器bank地址 硬件决定 禁止修改
    interrupts 中断类型/中断号/触发类型 硬件决定 禁止修改
    clocks 配置的时钟 硬件决定 禁止修改
    status 选择是否使能该timer "ok" or "disable" 可根据需要修改

    6.3. Padmux配置

    NA

    6.4. 模块使用介绍

    6.4.1. SYSFS 使用方法

    NA

    6.4.2. ioctl使用方法

    NA

    6.5. Sample code

    void sstar_timer_ut_callback(void *pdata)
    {
       int *timer_done = pdata;
    
       *timer_done = 1;
      }
    
    static int __init sstar_timer_ut_init(void)
    {
      int                timer_done   = 0;
      unsigned int       timer_id     = 0;
    
      handle = sstar_timer_register(timer_id, SSTAR_TIMER_MODE_RUNLOOP,
                                    sstar_timer_ut_callback, &timer_done)))
      if (handle == NULL)
      {
        pr_err("register timer fail\n");
        return -1;
      }
    
      sstar_timer_start(handle, 2000);
      msleep(2000);
      if (!timer_done)
      {
          pr_err("[TIMER%d][UT] result : FAILED\n", timer_id);
      }
    
      sstar_timer_unregister(handle);
      return 0;
    

    }

    6.6. UT case

    定时器的内核单元测试用例定义在kernel/drivers/sstar/timer/ut目录中。在目录下执行make 进行编译将得到测试用例timer_ut.ko。将timer_ut.ko拷贝到单板上, 执行insmod timer_ut.ko就可进行测试。

    7. API参考

    该功能模块提供以下接口:

    API名称 功能
    sstar_timer_register 注册timer
    sstar_timer_unregister 注销timer
    sstar_timer_start 启动timer
    sstar_timer_stop 关闭timer
    sstar_timer_get_current 获取timer从启动到现在过去的时间
    sstar_timer_device_count 获取timer数量
    sstar_timer_find_idle 寻找第一个可用timer

    相关头文件为 kernel/drivers/sstar/include/drv_timer.h。

    7.1. sstar_timer_register

    • 功能

      注册timer

    • 语法

      sstar_timer_handle sstar_timer_register(unsigned int timer_id,
                                        enum sstar_timer_mode mode,
                                        sstar_timer_callback callback,
                                        void *pdata);
      
      • 参数
      参数名称 描述
      timer_id timer编号 [1,max]
      mode timer工作模式, oneshoot/RunLoop两种可选
      callback 回调函数,Timer产生中断的时候会调用该函数
      *pdata 传递给回调函数的私有数据
    • 返回值

      返回值 描述
      handle 指向特定timer的指针

    7.2. sstar_timer_unregister

    • 功能

      注册timer

    • 语法

      int sstar_timer_unregister(sstar_timer_handle handle)
      
    • 参数

      参数 描述
      handle 指向特定timer的指针
    • 返回值

      返回值 描述
      0 成功
      other 失败

    7.3. sstar_timer_start

    • 功能

      启动Timer

    • 语法

      int sstar_timer_start(sstar_timer_handle handle,
                          unsigned long long exp_time)
      
    • 参数

      参数 描述
      handle 指向特定timer的指针
      exp_time Timer过期时间(ms)
    • 返回值

      返回值 描述
      0 成功
      other 失败

    7.4. sstar_timer_stop

    • 功能

      关闭timer

    • 语法

      int sstar_timer_stop(sstar_timer_handle handle)
      
    • 参数

      参数 描述
      handle 指向特定timer的指针
    • 返回值

      返回值 描述
      0 成功
      other 失败

    7.5. sstar_timer_get_current

    • 功能

      获取timer从启动到现在过去的时间

    • 语法

      int sstar_timer_get_current(sstar_timer_handle handle,
                                  unsigned long long *ptime)
      
    • 参数

      参数 描述
      handle 指向特定timer的指针
      ptime timer启动到现在的时间(ms)
    • 返回值

      返回值 描述
      0 成功
      other 失败

    7.6. sstar_timer_device_count

    • 功能

      获取timer数量

    • 语法

      int sstar_timer_device_count(void)
      
    • 参数

      参数名称 描述
      void
    • 返回值

      返回值 描述
      int timer的数量

    7.7. sstar_timer_find_idle

    • 功能

      寻找第一个可用timer

    • 语法

      int sstar_timer_find_idle(void)
      
    • 参数

      参数名称 描述
      void
    • 返回值

      返回值 描述
      int 第一个可用timer编号

    8. FAQ

    NA