6. The use of M601 watchdog

1 Software watchdog API


The data structure and API introduced in this article can refer to the zyf_wtd.h file in the SDK


1.1 Usage


In the OpenCPU solution, the hardware watchdog is enabled in the library by default, and it will feed the dog regularly, so the developer does not need to deal with this logic. In addition, this solution provides developers with a software watchdog. The software watchdog is turned on by calling ZYF_Wdt_Enable. After it is turned on, if the software watchdog counter value is not cleared within the specified time, the module will restart. Clear the software watchdog counter through ZYF_FeedDog. In case the module restarts. The watchdog can be turned off through ZYF_Wdt_Disable.


1.2 API functions


1.2.1 ZYF_Wdt_Enable
This function is used to enable the watchdog
· Function prototype
bool ZYF_Wdt_Enable(uint32_t max_interval_ms);
· Parameter
max_interval_ms:
[input]: Watchdog trigger time
· Return value
The result of enabling the watchdog


1.2.2 ZYF_Wdt_Disable
This function is used to turn off the watchdog
. Function prototype
bool ZYF_Wdt_Disable(void);

· Parameter
NONE
· Return value
The result of turning off the watchdog


1.2.3 ZYF_FeedDog feeds the
dog, that is, clears the value in the register to zero.
· Function prototype
void ZYF_FeedDog(void);
· Parameter
NONE
· Return value
NONE

 

2 Introduction to watchdog routines

This chapter mainly introduces how to use example_wtd.c in the SDK to test the watchdog function separately.

In the example, start a thread SMSThread_Example to test the watchdog function. ZYF_WtdTest() is
used to set the timer parameters. The function of ZYF_Wtd() is to set the timeout time of the watchdog to 10 seconds; on the other
hand, it is to set the feeding period of the timer to 9 seconds. details as follows:


#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");
}







 

Guess you like

Origin blog.csdn.net/w_hizyf_m/article/details/107084052