⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wdt.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
字号:
//----------------------------------------------------
//Copyright (C), 2004-2009,  lst.
//版权所有 (C), 2004-2009,   lst.
//所属模块: 看门狗模块
//作者:lst
//版本:V1.0.0
//文件描述: 看门狗模块
//其他说明:
//修订历史:
//    2. 日期:2009-02-25
//       作者:lst
//       新版本号:1.0.1
//       修改说明: 修正了wdt_create函数的一处错误,该bug由网友sniper提交
//    1. 日期:
//       作者:
//       新版本号:
//       修改说明:
//------------------------------------------------------
#include "inc_os.h"
static struct hard_reg_wdt volatile * const pg_wdt_reg
                        = (struct hard_reg_wdt *)0x53000000;
static struct wdt_rsc tg_wdt_rsc_pool[cn_wdt_limit];
static struct mem_cell_pool *pg_wdt_rsc_pool;              //内存池头指针。
static struct wdt_rsc *pg_wdt_rsc;
static uint32_t u32g_timeout_GCD;       //看门狗溢出时间的最大公约数
static uint16_t u16g_wdt_evtt;

void __wdt_init_hard(void);
void __wdt_star(void);
void __wdt_reset(void);
void __wdt_clear(void);

//----初始化看门狗模块--------------------------------------------------------
//功能:初始化看门狗模块,建立根资源结点,创建信号量(用于保护看门狗资源队列)
//参数:无
//返回:true = 成功创建,false = 创建失败。因为无需申请动态资源,总是会成功
//----------------------------------------------------------------------------
bool_t module_init_wdt(void)
{
    static struct wdt_rsc wdt_root;
    __wdt_init_hard();
    pg_wdt_rsc_pool = mb_create(&tg_wdt_rsc_pool,cn_wdt_limit,
                                sizeof(struct wdt_rsc),"wdt pool");
    //建立根资源节点
    pg_wdt_rsc = (struct wdt_rsc*)
           rsc_add_root_node(&wdt_root.wdt_node,sizeof(struct wdt_rsc),"watch dog");
    __semp_create_knl(&wdt_root.wdt_semp,1,1,"watch dog");
    u32g_timeout_GCD = 1;
    u16g_wdt_evtt = y_evtt_regist(true,false,cn_prio_wdt,1,wdt_check,
                                100,"wdt service");
    if(u16g_wdt_evtt != cn_invalid_evtt_id)
        return true;
    else
        return false;
}

//----求新的最大公约数---------------------------------------------------------
//功能: 加入溢出周期为new_num的看门狗以后,重新计算看门狗溢出周期的最大公约数
//参数:new_num,新看门狗的溢出周期
//返回:最大公约数
//----------------------------------------------------------------------------
uint32_t __wdt_inc_GCD(uint32_t new_num)
{
    return 1;
}

//----重新计算最大公约数-------------------------------------------------------
//功能: 删除一只看门狗以后,需重新计算最大公约数
//参数:无
//返回:最大公约数
//----------------------------------------------------------------------------
uint32_t __wdt_get_GCD(void)
{
    return 1;
}

//----添加一只看门狗-----------------------------------------------------------
//功能:创建一个看门狗
//参数:wdt,被初始化的看门狗指针
//      judge,用户提供的用于判断是否狗叫的函数指针
//      timeout,调用judge的时间间隔,单位是毫秒,不能为0,将被向上调整为
//      cn_tick_ms的整数倍
//返回:无
//-----------------------------------------------------------------------------
struct wdt_rsc * wdt_create(bool_t (*judge)(void),
                  uint32_t (*yip_remedy)(void),
                  uint32_t timeout,char *wdt_name)
{
    struct wdt_rsc *wdt;
    if(judge == NULL)
        return NULL;
    wdt = mb_malloc(pg_wdt_rsc_pool,0);
    if(wdt == NULL)
        return NULL;
    wdt->judge = judge;
    wdt->yip_remedy = yip_remedy;
    if(wdt->timeout == 0)
        wdt->timeout = 1;
    wdt->timeout = (timeout + cn_tick_ms -1)/cn_tick_ms;
    semp_pend(&pg_wdt_rsc->wdt_semp,cn_timeout_forever);
    if(rsc_get_son(&pg_wdt_rsc->wdt_node))  //资源队列中已经有看门狗
    {
        rsc_add_son(&pg_wdt_rsc->wdt_node,&wdt->wdt_node,
                     sizeof(struct wdt_rsc),wdt_name);
        u32g_timeout_GCD = __wdt_inc_GCD(wdt->timeout);
    }else                                   //这是添加的第一只看门狗
    {
        rsc_add_son(&pg_wdt_rsc->wdt_node,&wdt->wdt_node,
                     sizeof(struct wdt_rsc),wdt_name);
        u32g_timeout_GCD = wdt->timeout;
        y_event_pop(u16g_wdt_evtt,0,0,0);
    }
    semp_post(&pg_wdt_rsc->wdt_semp);
    return wdt;
}

//----删除一只看门狗-----------------------------------------------------------
//功能:删除一只存在的看门狗,重新计算狗溢出时间的最大公约数
//参数:wdt,被初始化的看门狗指针
//返回:无
//-----------------------------------------------------------------------------
void wdt_delete(struct wdt_rsc *wdt)
{
    if(wdt == NULL)
        return;
    semp_pend(&pg_wdt_rsc->wdt_semp,cn_timeout_forever);
    rsc_del_node(&wdt->wdt_node);
    u32g_timeout_GCD = __wdt_get_GCD();
    semp_post(&pg_wdt_rsc->wdt_semp);
    mb_free(pg_wdt_rsc_pool,wdt);
    return;
}

//----看门狗事件处理函数-------------------------------------------------------
//功能:本事件除非被信号量阻塞,一致就绪,持续监视系统tick,只要tick有变化,就
//      扫描一遍所有看门狗,按各看门狗设定的时间间隔调用judge函数,如果发现异常,
//      就调用“狗叫善后”函数,按善后函数的指示复位或者清除看门狗。如果没有发现
//      异常,就清除看门狗。
//参数:my_event,看门狗事件指针。
//返回:无
//-----------------------------------------------------------------------------
void wdt_check(struct event_script *my_event)
{
    static uint32_t old_tick,new_tick;
    struct rsc_node *current_node;
    struct wdt_rsc *wdt;
    uint32_t wdt_action;

    old_tick = y_get_time();
    while(1)
    {
        y_timer_sync(u32g_timeout_GCD);
        new_tick = y_get_time();        //取系统tick
        if(new_tick != old_tick)        //看系统tick是否变化
        {
            current_node = &pg_wdt_rsc->wdt_node;   //取看门狗的根资源指针
            while(1)        //遍历看门狗资源树并处理之
            {
                //取下一个看门狗资源结点,需要用信号量保护
                semp_pend(&pg_wdt_rsc->wdt_semp,cn_timeout_forever);
                current_node = rsc_trave_scion(&pg_wdt_rsc->wdt_node,
                                                current_node);
                semp_post(&pg_wdt_rsc->wdt_semp);
                if(current_node == NULL)        //已经遍历完所有看门狗节点
                    break;
                else                            //尚未遍历完所有看门狗节点
                {
                    wdt = (struct wdt_rsc *)current_node;
                    //看时钟是否已经跨过timeout时间点
                    if(new_tick / wdt->timeout != old_tick / wdt->timeout)
                    {
                        if(! wdt->judge())      //狗叫
                        {
                            y_error_login(enum_wdt_yip,"watch dog yip");
                            wdt_action = wdt->yip_remedy();     //调用善后程序
                            switch(wdt_action)
                            {
                                case cn_wdt_action_none:break;
                                case cn_wdt_action_reset:       //需复位
                                {
                                    __wdt_reset();
                                }break;
                                default:break;
                            }
                        }
                    }
                }
            }
            old_tick = new_tick;
        }
        __wdt_clear();        //清除看门狗
    }
}

//以下函数移植敏感

//----看门狗硬件初始化---------------------------------------------------------
//功能:看门狗硬件初始化
//参数:无
//返回:无
//-----------------------------------------------------------------------------
void __wdt_init_hard(void)
{
}

void __wdt_star(void)
{
}

void __wdt_reset(void)
{
    while(1);
}

void __wdt_clear(void)
{
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -