zynq看门狗

一、背景和用途

  1. 项目程序在运行过程中出现了内核崩溃的问题,在本质问题没解决情况下,又想推进项目的进行,可以考虑使用看门狗可以立即恢复

  2. 在解决问题后,可以使用看门狗规避整个系统程序长时间运行后可能跑飞的情况

二、zynq7000的看门狗配置

查看文档描述

  • 文档ug585-Zynq-7000-TRM-2018.pdf,可以看到看门狗和复位的描述

  • 由于zynq私有看门狗属于PS端,所以在vivado环境中不需要对pl进行配置

配置

内核配置

  • 打开menuconfig,选择Device Drivers ---> [] Watchdog Timer Support ---> <> Xilinx Watchdog timer

设备树配置

  • 编辑系统设备树zynq-7000.dtsi,找到watchdog,添加reset-on-timeout
watchdog0: watchdog@f8005000 {
                clocks = <&clkc 45>;
                compatible = "cdns,wdt-r1p2";
                interrupt-parent = <&intc>;
                interrupts = <0 9 1>;
                reg = <0xf8005000 0x1000>;
                timeout-sec = <10>;
                reset-on-timeout;  //加上这一行
};

三、应用程序测试

  • 说明:程序编译运行,ctrl+c停止程序运行3s后系统重启
#include <stdio.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <linux/ioctl.h>
#include <linux/types.h>

#define    WATCHDOG_IOCTL_BASE    'W'

#define    WDIOC_GETSUPPORT     _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
#define    WDIOC_GETSTATUS      _IOR(WATCHDOG_IOCTL_BASE, 1, int)
#define    WDIOC_GETBOOTSTATUS  _IOR(WATCHDOG_IOCTL_BASE, 2, int)
//#define    WDIOC_GETTEMP        _IOR(WATCHDOG_IOCTL_BASE, 3, int)
#define    WDIOC_SETOPTIONS     _IOR(WATCHDOG_IOCTL_BASE, 4, int)
#define    WDIOC_KEEPALIVE      _IOR(WATCHDOG_IOCTL_BASE, 5, int)
#define    WDIOC_SETTIMEOUT     _IOWR(WATCHDOG_IOCTL_BASE, 6, int)
#define    WDIOC_GETTIMEOUT     _IOR(WATCHDOG_IOCTL_BASE, 7, int)

int errnon = -1;

#define HI_APPCOMM_MAX_PATH_LEN (64)
#define HAL_FD_INITIALIZATION_VAL (-1)
#define HAL_WATCHDOG_DEV "/dev/watchdog"
static int s_s32HALWATCHDOGfd = HAL_FD_INITIALIZATION_VAL;

int WATCHDOG_Init(int s32Time_s)
{
    int s32Ret = 1;

    if (s32Time_s < 2 || s32Time_s > 1000)
    {
        printf("Interval time should not be less then two and bigger then 100. %d\n", s32Time_s);
        return -1;
    }

    s_s32HALWATCHDOGfd = open(HAL_WATCHDOG_DEV, O_RDWR);

    if (s_s32HALWATCHDOGfd < 0)
    {
        printf("open [%s] failed\n",HAL_WATCHDOG_DEV);
        return -1;
    }

    s32Ret = ioctl(s_s32HALWATCHDOGfd, WDIOC_SETTIMEOUT, &s32Time_s);
    if(-1 == s32Ret)
    {
        printf("WDIOC_SETTIMEOUT: failed, errnon(%d)\n", errnon);
        return -1;
    }
    printf("WDIOC_SETTIMEOUT: timeout=%ds\n", s32Time_s);

    s32Ret = ioctl(s_s32HALWATCHDOGfd, WDIOC_KEEPALIVE);/**feed dog */
    if(-1 == s32Ret)
    {
        printf("WDIOC_KEEPALIVE: failed, errnon(%d)\n", errnon);
        return -1;
    }

    return 1;
}

int HAL_WATCHDOG_Feed(void)
{
    int s32Ret = 1;
    s32Ret = ioctl(s_s32HALWATCHDOGfd, WDIOC_KEEPALIVE);/**feed dog */
    if(-1 == s32Ret)
    {
        printf("WDIOC_KEEPALIVE: failed, errnon(%d)\n", errnon);
        return -1;
    }
    return 1;
}

int HAL_WATCHDOG_Deinit(void)
{
    int s32Ret;

    s32Ret = close(s_s32HALWATCHDOGfd);
    if (0 > s32Ret)
    {
        printf("wdrfd[%d] close,fail,errnon(%d)\n",s_s32HALWATCHDOGfd,errnon);
        return -1;
    }

    return 1;
}

int main()
{

        WATCHDOG_Init(3);

        while(1)
        {
                sleep(1);
                HAL_WATCHDOG_Feed();
        }

        return 1;
}
posted @ 2021-11-02 14:09  回忆浅唱  阅读(924)  评论(0编辑  收藏  举报