• [笔记].怎样使用Nios II中的watchdog_timer?


    本文简单描述如何使用watchdog_timer服务,并给出一个简单范例。

    使用环境:Altera Quartus 9.1 SP1 + Nios II  9.1 Software Build Tools for Eclipse SP1

    步骤1 在SOPC Builder中例化Interval Timer核:

    1. 在SOPC Builder中例化Interval Timer核,命名为watchdog_timer。

    图1 添加Interval Timer核

    图1 例化Interval Timer核

    2. 配置Interval Timer核

    图2 配置Interval Timer核

    图2 配置Interval Timer核

    在Hardware options的预设置处,选择Watchdog。

    注意:Timeout period所设置的值,即看门狗的溢出时间值。此处设置为1s;即一旦开启看门狗后,1s内不喂狗,看门狗将复位处理器。

    表1 Watchdog寄存器选项

    表1 Watchdog寄存器选项

    表2 Watchdog输出信号选项

    表2 Watchdog输出信号选项

    步骤2 NIOS II EDS中编写相应的C程序

    1. 查看system.h中的相应内容

    #define ALT_MODULE_CLASS_watchdog_timer altera_avalon_timer
    #define WATCHDOG_TIMER_ALWAYS_RUN 1
    #define WATCHDOG_TIMER_BASE 0x1002040
    #define WATCHDOG_TIMER_COUNTER_SIZE 32
    #define WATCHDOG_TIMER_FIXED_PERIOD 1
    #define WATCHDOG_TIMER_FREQ 125000000u
    #define WATCHDOG_TIMER_IRQ 4
    #define WATCHDOG_TIMER_IRQ_INTERRUPT_CONTROLLER_ID 0
    #define WATCHDOG_TIMER_LOAD_VALUE 124999999ULL
    #define WATCHDOG_TIMER_MULT 1.0
    #define WATCHDOG_TIMER_NAME "/dev/watchdog_timer"
    #define WATCHDOG_TIMER_PERIOD 1
    #define WATCHDOG_TIMER_PERIOD_UNITS "s"
    #define WATCHDOG_TIMER_RESET_OUTPUT 1
    #define WATCHDOG_TIMER_SNAPSHOT 0
    #define WATCHDOG_TIMER_SPAN 32
    #define WATCHDOG_TIMER_TICKS_PER_SEC 1u
    #define WATCHDOG_TIMER_TIMEOUT_PULSE_OUTPUT 0
    #define WATCHDOG_TIMER_TYPE "altera_avalon_timer"

    第6行,Nios II软核的输入时钟频率,此处为125MHz。

    2. 查看altera_avalon_timer_regs.h中的控制寄存器内容

    /* CONTROL register */
    #define ALTERA_AVALON_TIMER_CONTROL_REG             1
    #define IOADDR_ALTERA_AVALON_TIMER_CONTROL(base) \
      __IO_CALC_ADDRESS_NATIVE(base, ALTERA_AVALON_TIMER_CONTROL_REG)
    #define IORD_ALTERA_AVALON_TIMER_CONTROL(base) \
      IORD(base, ALTERA_AVALON_TIMER_CONTROL_REG) 
    #define IOWR_ALTERA_AVALON_TIMER_CONTROL(base, data) \
      IOWR(base, ALTERA_AVALON_TIMER_CONTROL_REG, data)
    #define ALTERA_AVALON_TIMER_CONTROL_ITO_MSK         (0x1)
    #define ALTERA_AVALON_TIMER_CONTROL_ITO_OFST        (0)
    #define ALTERA_AVALON_TIMER_CONTROL_CONT_MSK        (0x2)
    #define ALTERA_AVALON_TIMER_CONTROL_CONT_OFST       (1)
    #define ALTERA_AVALON_TIMER_CONTROL_START_MSK       (0x4)
    #define ALTERA_AVALON_TIMER_CONTROL_START_OFST      (2)
    #define ALTERA_AVALON_TIMER_CONTROL_STOP_MSK        (0x8)
    #define ALTERA_AVALON_TIMER_CONTROL_STOP_OFST       (3)

    3. 示范程序

    #include "system.h"
    #include "altera_avalon_timer_regs.h"     // Interval Timer核的存储映射头文件
    #include "altera_avalon_pio_regs.h"       // PIO核的存储映射头文件
    #include "alt_types.h"
    #include 
    
    #define Q_LED_ON  IOWR_ALTERA_AVALON_PIO_DATA(Q_LED_BASE, 1)
    #define Q_LED_OFF IOWR_ALTERA_AVALON_PIO_DATA(Q_LED_BASE, 0)
    
    /*
     * 功能:初始化看门狗
     * 备注:看门狗一旦初始化后,就不能再被停止
     */
    #define Init_WDT  \
      IOWR_ALTERA_AVALON_TIMER_CONTROL(WATCHDOG_TIMER_BASE, \
          ALTERA_AVALON_TIMER_CONTROL_START_MSK)
    /*
     * 功能:喂狗操作
     * 使用方法:向PERIODL、PERIODH写入任意值
     */
    #define Feed_WDT  \
      IOWR_ALTERA_AVALON_TIMER_PERIODL(WATCHDOG_TIMER_BASE, 0x1234)
    
    int main(void)
    {
      alt_u8  i;
      Init_WDT;                             // 初始化看门狗
      Feed_WDT;                             // 进行喂狗操作
    
      /*
       * LED先快速亮灭10次
       */
      for(i=0; i<10; i++)
      {
        Q_LED_ON;
        usleep(100*1000);
        Feed_WDT;                           // 进行喂狗操作
    
        Q_LED_OFF;
        usleep(100*1000);
        Feed_WDT;                           // 进行喂狗操作
      }
    
      /*
       * LED保持熄灭状态2s,再重新打开
       */
      Q_LED_OFF;
      usleep(500*1000);
      Feed_WDT;                             // 进行喂狗操作
      usleep(500*1000);
      Feed_WDT;                             // 进行喂狗操作
      usleep(500*1000);
      Feed_WDT;                             // 进行喂狗操作
      usleep(500*1000);
      Feed_WDT;                             // 进行喂狗操作
      Q_LED_ON;
    
      while(1)
      {
    
      }
    
      return 0;
    }

    注:</unistd.h>是发博客发出来的,不属于该代码。

    第14-16行,初始化看门狗,即启动看门狗;具体操作,就是给控制寄存器的START位置一。注意,看门狗一旦启动,就不能再被关闭。

    第21-22行,是喂狗操作。无论给PERIODL、PERIODH写任何值,看门狗都会在所设置的溢出时间后复位。本文中的看门狗的溢出时间是1s,是在SOPC Builder中配置Interval Timer的时候所设置的。大家可自行设置为其他值。因此为了保证不被复位,我们要在喂狗后的溢出时间内再次喂狗。

    4. 运行结果

    LED经过亮灭闪烁10次、灭2秒、亮1秒后,复位后重新开始亮灭闪烁等现象。

    注意灭2秒是延时所致,而亮1秒是由于看门狗的溢出时间到了自动复位的缘故;如果没有看门狗,LED将一直亮下去。

    参考资料

    1. Volume5: Embedded Peripherals, QuartusII  Handbook Version 9.1

    http://www.altera.com/literature/hb/nios2/n2cpu_nii5v3.pdf

  • 相关阅读:
    从头带你撸一个Springboot Starter
    Spring Cache 带你飞(二)
    2021年终总结
    数据中台(介绍篇)
    NetCore实现全局模型绑定异常信息统一处理
    [源码解析] PyTorch 分布式之弹性训练(2)启动&单节点流程
    [源码解析] PyTorch 分布式(18) 使用 RPC 的分布式管道并行
    [源码解析] PyTorch 分布式之弹性训练(1) 总体思路
    [源码解析] PyTorch 分布式之弹性训练(3)代理
    [源码解析] PyTorch 分布式之弹性训练(5)Rendezvous 引擎
  • 原文地址:https://www.cnblogs.com/yuphone/p/1715525.html
Copyright © 2020-2023  润新知