6. M601 看门狗的使用

1 软件看门狗 API


本文介绍的数据结构和 API 可以参考 SDK 中 zyf_wtd.h 文件


1.1 用法


在 OpenCPU 方案中,默认在库中有启用硬件看门狗,而且会定时去喂狗,开发者不用去处理这块逻辑。另外,本方案向开发者提供了一个软件看门狗。通过调用 ZYF_Wdt_Enable 对软件看门狗进行开启,开启后,如果规定时间内没有去清除软件看门狗计数器数值,则模块会重启。通过 ZYF_FeedDog 对软件看门狗计数器清零。以防模块重启。通过 ZYF_Wdt_Disable 可关闭看门狗。


1.2 API 函数


1.2.1 ZYF_Wdt_Enable
此功能用于启动看门狗
· 函数原型
bool ZYF_Wdt_Enable(uint32_t max_interval_ms);
· 参数
max_interval_ms:
[输入]:看门狗触发时间
· 返回值
使能看门狗的结果


1.2.2 ZYF_Wdt_Disable
此函数用来关闭看门狗
· 函数原型
bool ZYF_Wdt_Disable(void);

· 参数
NONE
· 返回值
关闭看门狗的结果


1.2.3 ZYF_FeedDog
喂狗,即将寄存器中的数值清零。
· 函数原型
void ZYF_FeedDog(void);
· 参数
NONE
· 返回值
NONE

2 看门狗例程介绍

本章节主要介绍如何在 SDK 中使用 example_wtd.c 单独测试看门狗功能。

例程中,开启一个线程 SMSThread_Example 用来测试看门狗功能。ZYF_WtdTest()
用来设置定时器参数。ZYF_Wtd()的功能一方面是设置好看门狗的超时时间为 10 秒;另一方
面是设置好定时器的喂狗周期为 9 秒。具体如下:


#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "zyf_timer.h"
#include "zyf_wtd.h"

#include "zyf_trace.h"
#include "zyf_app.h"
#include "zyf_uart.h"
#include "zyf_thread.h"



typedef struct
{
    uint32_t max_interval;
    uint32_t feed_interval;
    ZYF_Timer_t *feed_timer;
} ZYF_Wdt_t;

static ZYF_Wdt_t gBsjWdt;

static Uart_Param_t g_uart1param;

void UartWriteCallBack(void* Param) // general com
{
    Uart_Param_t *uartparam = (Uart_Param_t *)Param; 
    if(Param == NULL)
    {
        return;
    }    

    ZYF_UartWrite(uartparam->port,(uint8_t *)"UartWrite succeed\r\n",strlen("UartWrite succeed\r\n"));
    ZYF_UartWriteCallbackSwitch(uartparam->port,false);

}

void UartReadCallBack(void* Param) // 
{
    uint32_t recvlen = 0;
    Uart_Param_t *uartparam = (Uart_Param_t *)Param; 

    ZYF_LOG("Uart%d recv",uartparam->port);

    while(ZYF_UartRead(uartparam->port, &(uartparam->uartbuf[recvlen]), 1))
    {
        ZYF_LOG("recv :%02x",uartparam->uartbuf[recvlen]);
        recvlen++;
    }
    ZYF_UartWrite(uartparam->port,uartparam->uartbuf,recvlen);
    ZYF_UartWriteCallbackSwitch(uartparam->port,true);
}


static void AppUartInit(void)
{
    int32_t ret;
    g_uart1param.port = DEBUG_PORT;
    ZYF_UartRegister(g_uart1param.port, UartReadCallBack,&g_uart1param);
    ZYF_UartWriteCbRegister(g_uart1param.port,UartWriteCallBack,&g_uart1param);
    ZYF_UartOpen(g_uart1param.port, 115200, ZYF_FC_NONE);

    ZYF_LOG("AppUartInit");
    return;
}


static void _feedDog(void *wd_)
{
    ZYF_Wdt_t *wd = (ZYF_Wdt_t *)wd_;
    ZYF_LOG("ZYF_feedDog");

    
    ZYF_FeedDog();
    ZYF_StartTimer(wd->feed_timer, wd->feed_interval);
}

void ZYF_WtdClose(void)
{
    ZYF_Wdt_Disable();
}

bool ZYF_WtdOpen(uint32_t max_interval_ms, uint32_t feed_interval_ms)
{
    ZYF_Wdt_t *wd = &gBsjWdt;
    if (max_interval_ms < feed_interval_ms)
        return false;

    ZYF_Wdt_t *timer = ZYF_CreateTimer(_feedDog, (void *)wd);
    if (timer == NULL)
        return false;

    wd->max_interval = max_interval_ms;
    wd->feed_interval = feed_interval_ms;
    wd->feed_timer = timer;

    bool r = ZYF_Wdt_Enable(max_interval_ms);
    if (!r)
    {
        ZYF_DeleteTimer(timer);
        return false;
    }

    ZYF_StartTimer(wd->feed_timer, wd->feed_interval);
    return true;
}

void ZYF_WtdTest(void)
{
    bool ret = ZYF_WtdOpen(10000, 9000);
    if(!ret)
    {
        ZYF_LOG("ZYF_WTD init failed.");
    }
    ZYF_LOG("ZYF_WTD init success!");
}

void SMSThread_Example(void * Param)
{
    ZYF_MsgQ_t *ptMsg;
    ZYF_AppMsg_t tMsg;
    int iRet = -1;
    ptMsg = ZYF_MsgQCreate(10, sizeof(ZYF_AppMsg_t));
    ZYF_LOG("thread enter!");

    ZYF_WtdTest();
    
    while (1) {
        ZYF_LOG("in while.");
        iRet = ZYF_MsgQGet(ptMsg, (void *)&tMsg);
        if (iRet < 0) {
            ZYF_LOG("Failed to get msg");
            ZYF_ThreadSleep(1000);
        }
    }

}


static void prvInvokeGlobalCtors(void)
{
    extern void (*__init_array_start[])();
    extern void (*__init_array_end[])();

    size_t count = __init_array_end - __init_array_start;
    for (size_t i = 0; i < count; ++i)
        __init_array_start[i]();
}


int appimg_enter(void *param)
{
    AppUartInit();
    ZYF_LOG("application image enter, param 0x%x", param);

    prvInvokeGlobalCtors();

    ZYF_ThreadCreate("SMSThread_Example", SMSThread_Example, NULL, ZYF_PRIORITY_HIGH, 10*1024);
    return 0;
}

void appimg_exit(void)
{
    OSI_LOGI(0, "application image exit");
}







猜你喜欢

转载自blog.csdn.net/w_hizyf_m/article/details/107084052