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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM