zoukankan      html  css  js  c++  java
  • Cubieboard2裸机开发之(五)看门狗操作

    前言

           说到看门狗,应该不会陌生,看门狗说白了就是一个定时器,但是它有一个非常重要的功能就是复位系统。在A20里,看门狗的操作非常简单,只有两个寄存器,不需要操作时钟相关的东西,系统起来后可以直接使用,它的最大定时时间为16秒。

    一、目的

           学习使用A20的看门狗,实现软件复位系统。

    二、源代码说明

         start.S文件。首先禁止CPU的IRQ和FIQ,设置为管理模式,需要注意的是,这里设置异常向量表的起始地址为start.S文件里的第一指令的地址,学过ARM的都知道,ARM的异常向量表可以设置在低地址(0地址),也可以设置在高地址(0xffff0000地址,通常在使能了MMU后使用),但是目前Cortex-A7体系结构已经可以指定异常向量表的地址,这样就省去了搬移的操作。然后设置堆栈指针,最后调用C语言的main函数。

     1 /*
     2  * (C) Copyright 2014 conan liang <lknlfy@163.com>
     3  * 
     4  */
     5 
     6 
     7 /* global entry point */
     8 .global _start
     9 _start:
    10     b    reset
    11     
    12 
    13 reset:
    14     /* disable IRQ & FIQ, set the cpu to SVC32 mode */
    15     mrs r0, cpsr
    16     and r1, r0, #0x1f
    17     teq r1, #0x1a
    18     bicne r0, r0, #0x1f
    19     orrne r0, r0, #0x13
    20     orr r0, r0, #0xc0
    21     msr cpsr, r0
    22 
    23     /* set exception vector table */
    24     ldr r0, =_start
    25     mcr p15, 0, r0, c12, c0, 0
    26 
    27     /* setup stack, so we can call C code */
    28     ldr sp, =(1024 * 10)
    29     
    30     /* jump to main function */
    31     bl main
    32 loop:
    33     b loop

          main.c文件。首先初始化看门狗,设置它在3秒后执行系统复位操作(如果参数值小于0则表示关闭看门狗),然后初始化LED所在IO管脚,设置为输出功能,并且输出低电平,即一开始两个LED是熄灭的,接着是一段延时,目的是可以看到两个LED闪烁,如果观察现象时看到两个LED闪烁,那也说明了看门狗正常工作了。

     1 #include "io.h"
     2 #include "watchdog.h"
     3 
     4 
     5 #define SUNXI_PIO_BASE   (0x01C20800)
     6 #define PH_CFG2          (SUNXI_PIO_BASE + 0x104)
     7 #define PH_DAT           (SUNXI_PIO_BASE + 0x10C)
     8 
     9 
    10 /* set two LEDs on */
    11 static void set_led_on(void)
    12 {
    13     unsigned int tmp;
    14     
    15     /* PH20 and PH21 output 1 */
    16     tmp = readl(PH_DAT);
    17     tmp |= (0x1 << 20);
    18     tmp |= (0x1 << 21);
    19     writel(tmp, PH_DAT);
    20 }
    21 
    22 /* init two PIOs */
    23 static void led_init(void)
    24 {
    25     unsigned int tmp;
    26     
    27     /* configure PH20 and PH21 output */
    28     tmp = readl(PH_CFG2);
    29     tmp &= ~(0x7 << 16);
    30     tmp &= ~(0x7 << 20);
    31     tmp |= (0x1 << 16);
    32     tmp |= (0x1 << 20);
    33     writel(tmp, PH_CFG2);
    34     /* PH20 and PH21 output 0 */
    35     tmp = readl(PH_DAT);
    36     tmp &= ~(0x1 << 20);
    37     tmp &= ~(0x1 << 21);
    38     writel(tmp, PH_DAT);
    39 }
    40 
    41 
    42 int main(void)
    43 {
    44     int i;
    45 
    46     /* let watchdog reset the system after 3 second */
    47     sunxi_watchdog_init(3);
    48     /* init LEDs */
    49     led_init();
    50     /* some delay, so we can see two LEDs off a while */
    51     for (i = 0; i < 50000; i++);
    52     /* set two LEDs on */
    53     set_led_on();
    54     while (1);
    55     
    56     return 0;
    57 }

          watchdog.c文件。看门狗的驱动程序,非常简单。

     1 #include "watchdog.h"
     2 #include "io.h"
     3 
     4 /* watchdog interval value */
     5 static unsigned int watchdog_intv_val [] = {
     6     0b0000, // 0.5s
     7     0b0001, // 1s
     8     0b0010, // 2s
     9     0b0011, // 3s
    10     0b0100, // 4s
    11     0b0101, // 5s
    12     0b0110, // 6s
    13     0b0111, // 8s
    14     0b0111, // 8s
    15     0b1000, // 10s
    16     0b1000, // 10s
    17     0b1001, // 12s
    18     0b1001, // 12s
    19     0b1010, // 14s
    20     0b1010, // 14s
    21     0b1011, // 16s
    22     0b1011  // 16s
    23 };
    24 
    25 /* reg bits */
    26 #define WDOG_OFF     (-1)
    27 #define WDOG_RST_EN  (1) 
    28 #define WDOG_EN      (0)
    29 #define WDOG_RSTART  (0)
    30 
    31 static void sunxi_watchdog_set(int time)
    32 {
    33     if (time >= 0) {
    34         /* should not larger than 16 seconds */
    35         if(time > 16)
    36             time = 16;
    37         writel((watchdog_intv_val[time] << 3) | (1 << WDOG_RST_EN) | (1 << WDOG_EN), SUNXI_WDOG_MODE_REG);
    38     } else {
    39         /* disable watchdog */
    40         writel(0, SUNXI_WDOG_MODE_REG);
    41     }
    42     /* restart watchdog */
    43     writel(1 << WDOG_RSTART, SUNXI_WDOG_CTRL_REG);
    44 }
    45 
    46 int sunxi_watchdog_init(int val)
    47 {
    48     sunxi_watchdog_set(val);
    49     
    50     return 0;
    51 }

    三、验证

           使用arm-linux-gnueabihf工具编译后生成watchdog.b文件,再使用mksunxiboot工具在watchdog.b文件前面加上一个头部,最终生成watchdog.bin文件,使用以下命令将watchdog.bin文件烧写到TF中:

    #sudo dd if=./watchdog.bin of=/dev/sdb bs=1024 seek=8

         将TF卡插入Cubieboard2,上电即可看到两个LED出现短时的周期闪烁,效果不好用图片展示,因此就不上图了。

  • 相关阅读:
    转:全面理解Javascript闭包和闭包的几种写法及用途
    VS2010 AnkhSvn
    silverlight 子UserControl获取父UserControl
    IIS相关
    (转)Javascript中console.log()用法
    (转)Sql Server 保留几位小数的两种做法
    asp.net Web API
    (转)C#中数组、ArrayList和List三者的区别
    PowerDesigner
    (转)jQuery.fn.extend与jQuery.extend到底区别在哪?
  • 原文地址:https://www.cnblogs.com/lknlfy/p/3601275.html
Copyright © 2011-2022 走看看