zoukankan      html  css  js  c++  java
  • 系统监控组件(基于嵌入式实时操作系统FreeRTOS)(优化版)

    /**
     * @file ci110x_task_monitor.c
     * @brief  系统监控组件
     *
     * 负责监视控制加入监控队列里的每一个任务,以防有任务出现异常情况,
     * 避免因异常未及时处理而造成的损失。
     *
     * @version 0.1
     * @date 2019-04-02
     *
     * @copyright Copyright (c) 2019  Chipintelli Technology Co., Ltd.
     *
     */
    
    #include "ci110x_task_monitor.h"
    
    /*监控任务的个数,最大为23*/
    #define MONITOR_TAST_MAX_COUNT (23)/* 范围:0 - 23 根据实际情况合理设置*/
    /*监控周期(单位:MS)*/
    #define MONITOR_PERIOD (1000)
    
    typedef struct
    {
        uint8_t state;
        uint8_t id;
        uint8_t flag;
        uint8_t priority;
        uint32_t time;
        uint32_t last_time;
        TaskHandle_t handle;
    }monitor_t;
    
    static monitor_t join_monitor_list[MONITOR_TAST_MAX_COUNT];
    static uint8_t join_monitor_count = 0;
    static EventGroupHandle_t eventgroup = NULL;
    
    typedef void (*func)(void);
    func iwdg_callback = NULL;
    
    /**
     * @brief 监控事件组创建函数
     *
     * @param call_back 系统异常复位前的回调函数
     */
    void monitor_creat(void (*call_back)(void))
    {
        /*创建事件标志组*/
        eventgroup = xEventGroupCreate();
        if(NULL == eventgroup)
        {
            /*事件标志组创建失败*/
            ci_logdebug(LOG_SYS_MONITOR,"xEventGroupCreate Failed
    ");
        }
        ci_logdebug(LOG_SYS_MONITOR,"xEventGroupCreate Success
    ");
        iwdg_callback = call_back;
    }
    
    /**
     * @brief 任务加入监控队列
     *
     * @param id 分配给任务的监控ID
     * @param time_ms 每次上报运行状态的最大时间间隔
     * @param handle 任务句柄(用来调节任务优先级)
     */
    void join_monitor(uint8_t* id,uint32_t time_ms, TaskHandle_t handle)
    {
        if(join_monitor_count > MONITOR_TAST_MAX_COUNT)
        {
            ci_logdebug(LOG_SYS_MONITOR,"已经达到监控任务的最大个数.
    ");
            CI_ASSERT(0,"已经达到监控任务的最大个数.
    ");
        }
        for(int i = 0;i < join_monitor_count;i++)
        {
            if(0 == join_monitor_list[i].state)
            {
                *id = join_monitor_list[i].id;
                join_monitor_list[i].state = 1;
                join_monitor_list[i].flag = 0;
                join_monitor_list[i].time = time_ms;
                join_monitor_list[i].handle = handle;
                return;
            }
        }
        /*给加入监控的任务编号,对应事件组的某个bit*/
        *id = join_monitor_count;
        /* 保存任务属性 */
        join_monitor_list[join_monitor_count].state = 1;
        join_monitor_list[join_monitor_count].flag = 0;
        join_monitor_list[join_monitor_count].id = join_monitor_count;
        join_monitor_list[join_monitor_count].time = time_ms;
        join_monitor_list[join_monitor_count].handle = handle;
        /*准备下个加入监控任务的编号*/
        join_monitor_count++;
        ci_logdebug(LOG_SYS_MONITOR,"已经监控 %d 个任务.
    ",join_monitor_count);
    }
    
    /**
     * @brief 任务退出监控队列
     *
     * @param id 分配给任务的监控ID
     */
    void exit_monitor(uint8_t id)
    {
        join_monitor_list[id].state = 0;
    }
    
    /**
     * @brief 被监控任务状态上报函数
     *
     * @param id 任务的监控ID
     */
    void task_alive(uint8_t id)
    {
        xEventGroupSetBits(eventgroup, (0x1 << id));
    }
    
    /**
     * @brief 监控任务函数
     *
     * @param pvparameters 任务参数
     */
    void task_monitor(void *pvparameters)
    {
        /* 计算事件组的所有有效位 */
        uint32_t bit_all;
        EventBits_t bit_rev;
        /* 打开IWDG的时钟 */
        Scu_SetDeviceGate(HAL_IWDG_BASE,ENABLE);
        /* 打开IWDG的复位配置 */
        Scu_Iwdg_RstSys_Config();
        /* 配置IWDG并启动 */
        iwdg_init_t init;
        init.irq = iwdg_irqen_enable;
        init.res = iwdg_resen_enable;
        init.count = (2 * MONITOR_PERIOD) * ((get_ipcore_clk()/0x10)/1000);
        iwdg_init(IWDG,init);
        iwdg_open(IWDG);
        ci_logdebug(LOG_SYS_MONITOR,"IWDG init ok.
    ");
    
        for(;;)
        {
            bit_all = (uint32_t)pow(2,join_monitor_count + 1) - 1;
            /* 等待所有任务发来事件标志 */
            bit_rev = xEventGroupWaitBits(eventgroup,/* 事件标志组句柄 */
                                          bit_all,/* 等待TASK_BIT_ALL被设置 */
                                          pdTRUE,/* 退出前TASK_BIT_ALL被清除*/
                                          pdTRUE,/* 等待TASK_BIT_ALL都被设置*/
                                          pdMS_TO_TICKS(MONITOR_PERIOD));/* 等待延迟时间 */
            xEventGroupClearBits(eventgroup,bit_all);
            /*监控任务正常,喂狗*/
            iwdg_feed(IWDG);
            ci_logdebug(LOG_SYS_MONITOR,"IWDG feed ok.
    ");
            /* 判断任务是否正常喂狗 */
            for (int i = 0; i < join_monitor_count; i++)
            {
                if(join_monitor_list[i].state)
                {
                    /* 该bit有没有被设置 */
                    if((bit_rev & (0x1 << join_monitor_list[i].id)) != (0x1 << join_monitor_list[i].id))
                    {
                        join_monitor_list[i].last_time += MONITOR_PERIOD;
                        if(join_monitor_list[i].last_time >= join_monitor_list[i].time)
                        {
                            ci_logdebug(LOG_SYS_MONITOR,"task flag is :%d
    ",join_monitor_list[i].flag);
                            if(join_monitor_list[i].flag == 0)
                            {
                                ci_logdebug(LOG_SYS_MONITOR,"task id is :%d
    ",join_monitor_list[i].id);
                                if(join_monitor_list[i].handle != NULL)
                                {
                                    ci_logdebug(LOG_SYS_MONITOR,"调整任务优先级
    ");
                                    /*存储任务优先级*/
                                    join_monitor_list[i].priority = uxTaskPriorityGet(join_monitor_list[i].handle);
                                    if(configMAX_PRIORITIES >= (join_monitor_list[i].priority + 1))
                                    {
                                        /*临时修改任务优先级*/
                                        vTaskPrioritySet(join_monitor_list[i].handle,join_monitor_list[i].priority + 1);
                                    }
                                }
    
                                ci_logdebug(LOG_SYS_MONITOR,"task handle is :0x%x
    ",join_monitor_list[i].handle );
    
                                join_monitor_list[i].last_time = 0;
                                join_monitor_list[i].flag = 1;
                            }
                            else
                            {
                                ci_loginfo(LOG_SYS_MONITOR,"task id is :%d
    ",join_monitor_list[i].id);
                                if(NULL != iwdg_callback)
                                {
                                    iwdg_callback();
                                }
                                ci_loginfo(LOG_SYS_MONITOR,"系统复位
    ");
                                //FIXME:防止打印未完成而复位
                                ci_loginfo(LOG_SYS_MONITOR, "----------------------------------
    ");
                                ci_loginfo(LOG_SYS_MONITOR, "----------------------------------
    ");
                                ci_loginfo(LOG_SYS_MONITOR, "----------------------------------
    ");
                                ci_loginfo(LOG_SYS_MONITOR, "----------------------------------
    ");
                                ci_loginfo(LOG_SYS_MONITOR, "----------------------------------
    ");
                                ci_loginfo(LOG_SYS_MONITOR, "----------------------------------
    ");
                                /* 任务死掉,复位系统 */
                                Scu_SoftwareRst_System();
                                while(1);
                            }
                        }
                    }
                    else
                    {
                        ci_logdebug(LOG_SYS_MONITOR,"%d:该bit已经被设置
    ",join_monitor_list[i].id);
                        join_monitor_list[i].last_time = 0;
                        if(join_monitor_list[i].flag == 1)
                        {
                            ci_logdebug(LOG_SYS_MONITOR,"task id is :%d
    ",join_monitor_list[i].id);
                            if(join_monitor_list[i].handle)
                            {
                                ci_logdebug(LOG_SYS_MONITOR,"还原任务优先级
    ");
                                /*还原任务优先级*/
                                vTaskPrioritySet(join_monitor_list[i].handle, join_monitor_list[i].priority);
                            }
                            join_monitor_list[i].flag = 0;
                        }
                    }
                }
            }
        }
    }
  • 相关阅读:
    定位图片的特殊例子+上传图片
    mysql 视图 安全性( mysql 表能读,但是视图不能读问题 )
    关于mysql 的 autoCommit 参数
    @Transactional 可以写在 Controller 方法上面了
    微信 支付宝 同时支付一个订单的解决方案
    Illegalmixofcollations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT)foroperation '= 连表查询排序规则问题
    Transaction rolled back because it has been marked as rollback-only 原因 和解决方案
    RabbitMQ 死信队列 延时
    好久没考虑过的 sql 注入
    基于redis的 分布式锁 Java实现
  • 原文地址:https://www.cnblogs.com/wangyanwen/p/11652799.html
Copyright © 2011-2022 走看看