当前位置:首页 > > ZYNQ

看门狗定时器复位

看门狗定时器复位在启用时由看门狗定时器内部产生并且计时器到期。

PS 中有三种不同的看门狗定时器:

一个系统级定时器(SWDT)和两个ARM内核(AWDT0和AWDT1)中的每个内核中的一个专用计时器。

系统级计时器重置信号始终重置整个系统,而专用看门狗计时器可以重置只是它所在的ARM内核,或者整个系统。

安全违规锁定

当检测到安全冲突时,将重置并锁定整个PS。

安全锁后发生向下,PS仅通过断言和取消断言PS_POR_B复位而再次变为活动状态。

Zynq-7000 SoC设备提供以下安全启动功能:

  • 先进的加密标准

    • 带有256位密钥的AES-CBC(FIPS197)

    • 加密密钥存储在芯片上,存储在eFuse或电池供电的RAM(BBRAM)中

  • 带密钥的消息验证码(HMAC,FIPS198-1)

    • SHA-256验证引擎(FIPS180-4)

  • RSA公钥认证(FIPS186-3)

    • 2048位公钥

私有看门狗与系统看门狗

每个Cortex-A9处理器都有自己私有的32位定时器和32位看门狗定时器,这两个处理器共享一个全局64位计数器,它们的频率都为CPU频率的1/2。

而在系统级,有一个24位看门狗计时器和两个16位三重计时器/计数器,系统级看门狗定时器的频率为CPU频率的1/4或1/6,下图为系统内部两个看门狗所处位置以及关系图。

配置WDT程序

由于私有看门狗属于PS端,所以在vivado环境中不需要对block块进行设置。在vivado下配置如下:

看门狗配置

int watchdogConfig(XScuWdt * WdtInstancePtr, u16 DeviceId,float number) { int Status;
 XScuWdt_Config *ConfigPtr;
 u32 result; //用来配置WDT的设备ID号,ID号在#include "xparameters.h"中可以找到。 xil_printf("start the watchdog time``r successful! \r\n");
 ConfigPtr = XScuWdt_LookupConfig(DeviceId); //初始化WDT计数器 Status = XScuWdt_CfgInitialize(WdtInstancePtr, ConfigPtr,
 ConfigPtr->BaseAddr); if (Status != XST_SUCCESS) { return XST_FAILURE;
 } //通过设置看门狗控制寄存器的WD模式位,将看门狗定时器置于看门狗模式 XScuWdt_SetWdMode(WdtInstancePtr); //给WDT计数器装初值,这里我对此函数进行了封装。已知CPU的时钟频率为666.6666Mhz, //即WDT的时钟频率为333.33Mhz,可得倒计时1s计数器需要配置的初值为333_333_333, //对计数器赋的初值可以直接写在number变量中(本文赋值为10s)。 result = (unsigned long)(333333333*number);
 XScuWdt_LoadWdt(WdtInstancePtr,result); //开启看门狗计数器。 XScuWdt_Start(WdtInstancePtr); return XST_SUCCESS;
}

开始测试

给计数器赋初值为10s,在循环中启动喂狗程序,程序会在5S后跳出循环,之后在10s后由于没有喂狗功能,系统复位,代码如下:

#include "xparameters.h" #include "xscuwdt.h" #include "xil_printf.h" #include  #include "stdio.h" #define WDT_DEVICE_ID    XPAR_SCUWDT_0_DEVICE_ID XScuWdt Watchdog; /* Cortex SCU Private WatchDog Timer Instance */ int main(void) { int Status; int Count = 0;
 Status = watchdogConfig(&Watchdog, WDT_DEVICE_ID,10); if (Status != XST_SUCCESS) {
 xil_printf("start the watchdog timer fail!\r\n"); return XST_FAILURE;
 } while (Count < 5) {
 sleep(1);
 Count++;
 XScuWdt_RestartWdt(Watchdog); printf("the second is %d \n",Count);
 }
 xil_printf("the watchdog timer will restart the system \r\n"); return XST_SUCCESS;
}

同样给计数器赋初始值为10s,禁用喂狗程序,程序会直接在10s后进行系统复位。

#include "xparameters.h" #include "xscuwdt.h" #include "xil_printf.h" #include  #include "stdio.h" #define WDT_DEVICE_ID    XPAR_SCUWDT_0_DEVICE_ID XScuWdt Watchdog; /* Cortex SCU Private WatchDog Timer Instance */ int main(void) { int Status; int Count = 0;
 Status = watchdogConfig(&Watchdog, WDT_DEVICE_ID,10); if (Status != XST_SUCCESS) {
 xil_printf("start the watchdog timer fail!\r\n"); return XST_FAILURE;
 } while (Count < 5) {
 sleep(1);
 Count++; printf("the second is %d \n",Count);
 }
 xil_printf("the watchdog timer will restart the system \r\n"); return XST_SUCCESS;
}

总结

在嵌入式系统中,为了使系统在工作异常情况下能自动重启,一般都需要引入看门狗程序,用来监测程序以免“跑飞”。

看门狗其实就是一个可以在一定时间内被复位的计数器,当看门狗启动后,计数器开始自动计数;

经过一定时间,如果没有被复位,计数器清零就会对CPU产生一个复位信号使系统重启(俗称“被狗咬”),这个是我们经常需要用到的。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
关闭