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

    系统监控(SYS MONITOR)

    概述

    SDK内置组件系统监控是系统内尤为重要的一个组件,它负责监视控制加入监控队列里的每一个任务,以防有任务出现异常情况,避免因异常未及时处理而造成的损失。本组件以硬件看门狗为基础,在此基础之上实现了对多个任务同时进行监控的监控策略,以此来保证系统正常稳定的运行。

    ## 使用说明

    该组件源代码包括ci110x_task_monitor.c、ci110x_task_monitor.h、ci110x_task_monitor_test.c三个文件组成,其中ci110x_task_monitor.c、ci110x_task_monitor.h我们已经实现了相关监控策略和外部调用接口,ci110x_task_monitor_test.c中是一份示例代码告诉使用者如何加入监控队列,如何实时对任务进行监控。 

    ci110x_task_monitor.c
      1 /**
      2  * @file ci110x_task_monitor.c
      3  * @brief  系统监控组件
      4  *
      5  * 负责监视控制加入监控队列里的每一个任务,以防有任务出现异常情况,
      6  * 避免因异常未及时处理而造成的损失。
      7  *
      8  * @version 0.1
      9  * @date 2019-04-02
     10  *
     11  * @copyright Copyright (c) 2019  Chipintelli Technology Co., Ltd.
     12  *
     13  */
     14 
     15 #include "ci110x_task_monitor.h"
     16 
     17 /*调节任务优先级开关*/
     18 #define ADJUST_TASK_PRIORITY_EN (1)
     19 /*监控任务的个数,最大为23*/
     20 #define MONITOR_TAST_MAX_COUNT (23)/* 范围:0 - 23 根据实际情况合理设置*/
     21 /*监控周期(单位:MS)*/
     22 #define MONITOR_PERIOD (1000)
     23 
     24 typedef struct
     25 {
     26     uint8_t id;
     27     uint8_t flg;
     28     uint8_t priority;
     29     uint32_t time;
     30     uint32_t last_time;
     31     #if ADJUST_TASK_PRIORITY_EN
     32     TaskHandle_t handle;
     33     #endif
     34 }monitor_t;
     35 
     36 static monitor_t monitor_list[MONITOR_TAST_MAX_COUNT];
     37 static EventGroupHandle_t eventgroup = NULL;
     38 static uint8_t monitor_count = 0;
     39 
     40 typedef void (*func)(void);
     41 func iwdg_callback = NULL;
     42 
     43 /**
     44  * @brief 监控事件组创建函数
     45  *
     46  * @param call_back 系统异常复位前的回调函数
     47  */
     48 void monitor_creat(void (*call_back)(void))
     49 {
     50     /*创建事件标志组*/
     51     eventgroup = xEventGroupCreate();
     52     if(NULL == eventgroup)
     53     {
     54         /*事件标志组创建失败*/
     55         ci_logdebug(LOG_USER,"xEventGroupCreate Failed
    ");
     56     }
     57     ci_logdebug(LOG_USER,"xEventGroupCreate Success
    ");
     58     iwdg_callback = call_back;
     59 }
     60 
     61 /**
     62  * @brief 任务加入监控队列
     63  *
     64  * @param id 分配给任务的监控ID
     65  * @param time_ms 每次上报运行状态的最大时间间隔
     66  * @param handle 任务句柄(用来调节任务优先级)
     67  */
     68 void join_monitor(uint8_t* id,uint32_t time_ms, TaskHandle_t handle)
     69 {
     70     if(monitor_count > MONITOR_TAST_MAX_COUNT)
     71     {
     72         ci_logdebug(LOG_USER,"已经达到监控任务的最大个数.
    ");
     73     }
     74     /*给加入监控的任务编号,对应事件组的某个bit*/
     75     *id = monitor_count;
     76     /* 保存任务属性 */
     77     monitor_list[monitor_count].id = monitor_count;
     78     monitor_list[monitor_count].time = time_ms;
     79     #if ADJUST_TASK_PRIORITY_EN
     80     monitor_list[monitor_count].handle = handle;
     81     #endif
     82     /*准备下个加入监控任务的编号*/
     83     monitor_count++;
     84     ci_logdebug(LOG_USER,"已经监控 %d 个任务.
    ",monitor_count);
     85 }
     86 
     87 /**
     88  * @brief 被监控任务状态上报函数
     89  *
     90  * @param id 任务的监控ID
     91  */
     92 void task_alive(uint8_t id)
     93 {
     94     xEventGroupSetBits(eventgroup, (0x1 << id));
     95 }
     96 
     97 /**
     98  * @brief 监控任务函数
     99  *
    100  * @param pvparameters 任务参数
    101  */
    102 void task_monitor(void *pvparameters)
    103 {
    104     /* 计算事件组的所有有效位 */
    105     uint32_t bit_all = (uint32_t)pow(2,monitor_count + 1) - 1;
    106     EventBits_t bit_rev;
    107 
    108     /* 打开IWDG的复位配置 */
    109     Scu_Iwdg_RstSys_Config();
    110     /* 配置IWDG并启动 */
    111     iwdg_init_t init;
    112     init.irq = iwdg_irqen_enable;
    113     init.res = iwdg_resen_enable;
    114     init.count = (MONITOR_PERIOD + 500) * (get_apb_clk()/1000);
    115     iwdg_init(IWDG,init);
    116     iwdg_open(IWDG);
    117     ci_logdebug(LOG_USER,"IWDG init ok.
    ");
    118 
    119     for(;;)
    120     {
    121         /* 等待所有任务发来事件标志 */
    122         bit_rev = xEventGroupWaitBits(eventgroup,/* 事件标志组句柄 */
    123                                       bit_all,/* 等待TASK_BIT_ALL被设置 */
    124                                       pdTRUE,/* 退出前TASK_BIT_ALL被清除*/
    125                                       pdTRUE,/* 等待TASK_BIT_ALL都被设置*/
    126                                       pdMS_TO_TICKS(MONITOR_PERIOD));/* 等待延迟时间 */
    127         xEventGroupClearBits(eventgroup,bit_all);
    128         /*监控任务正常,喂狗*/
    129         iwdg_feed(IWDG);
    130         ci_logdebug(LOG_USER,"IWDG feed ok.
    ");
    131         /* 判断任务是否正常喂狗 */
    132         for (int i = 0; i < monitor_count; i++)
    133         {
    134             /* 该bit有没有被设置 */
    135             if((bit_rev & (0x1 << monitor_list[i].id)) != (0x1 << monitor_list[i].id))
    136             {
    137                 monitor_list[i].last_time += MONITOR_PERIOD;
    138                 if(monitor_list[i].last_time >= monitor_list[i].time)
    139                 {
    140                     if(monitor_list[i].flg == 0)
    141                     {
    142                         ci_logdebug(LOG_USER,"task id is :%d
    ",monitor_list[i].id);
    143                         #if ADJUST_TASK_PRIORITY_EN
    144                         ci_logdebug(LOG_USER,"调整任务优先级
    ");
    145                         /*存储任务优先级*/
    146                         monitor_list[i].priority = uxTaskPriorityGet(monitor_list[i].handle);
    147                         if(configMAX_PRIORITIES >= (monitor_list[i].priority + 1))
    148                         {
    149                             /*临时修改任务优先级*/
    150                             vTaskPrioritySet(monitor_list[i].handle,monitor_list[i].priority + 1);
    151                             #endif
    152                         }
    153                         monitor_list[i].flg = 1;
    154                     }
    155                     else
    156                     {
    157                         ci_logdebug(LOG_USER,"task id is :%d
    ",monitor_list[i].id);
    158                         if(NULL != iwdg_callback)
    159                         {
    160                             iwdg_callback();
    161                         }
    162                         ci_logdebug(LOG_USER,"系统复位
    ");
    163                         /* 任务死掉,复位系统 */
    164                         Scu_SoftwareRst_System();
    165                         while(1);
    166                     }
    167                 }
    168             }
    169             else
    170             {
    171                 ci_logdebug(LOG_USER,"%d:该bit以及被设置
    ",monitor_list[i].id);
    172                 monitor_list[i].last_time = 0;
    173                 if(monitor_list[i].flg == 1)
    174                 {
    175                     ci_logdebug(LOG_USER,"task id is :%d
    ",monitor_list[i].id);
    176                     #if ADJUST_TASK_PRIORITY_EN
    177                     ci_logdebug(LOG_USER,"还原任务优先级
    ");
    178                     /*还原任务优先级*/
    179                     vTaskPrioritySet(monitor_list[i].handle, monitor_list[i].priority);
    180                     #endif
    181                     monitor_list[i].flg = 0;
    182                 }
    183             }
    184         }
    185     }
    186 }
    ci110x_task_monitor.h
    /**
     * @file ci110x_task_monitor.h
     * @brief  系统监控组件
     * 
     * 负责监视控制加入监控队列里的每一个任务,以防有任务出现异常情况,
     * 避免因异常未及时处理而造成的损失。
     * 
     * @version 0.1
     * @date 2019-04-02
     * 
     * @copyright Copyright (c) 2019  Chipintelli Technology Co., Ltd.
     * 
     */
    
    #include "freertos/FreeRTOS.h"
    #include "freertos/task.h"
    #include "freertos/event_groups.h"
    #include "ci110x_iwdg.h"
    #include "ci110x_scu.h"
    #include "sdk_default_config.h"
    #include "ci_log.h"
    #include <math.h>
    
    /**
     * @addtogroup sys_monitor
     * @{
     */
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void monitor_creat(void (*call_back)(void));
    void join_monitor(uint8_t* id,uint32_t time_ms, TaskHandle_t handle);
    void task_alive(uint8_t id);
    void task_monitor(void *pvparameters);
    
    #ifdef __cplusplus
    }
    #endif
    
    /**
     * @}
     */
    • 相关宏配置说明如下:

    /*调节任务优先级开关*/
    #define ADJUST_TASK_PRIORITY_EN (1)
    /*监控任务的个数,最大为23*/
    #define MONITOR_TAST_MAX_COUNT (23)/* 范围:0 - 23 根据实际情况合理设置*/
    /*监控周期(单位:MS)*/
    #define MONITOR_PERIOD (1000)
    • 相关API接口如下:

    函数描述
    monitor_creat 监控事件组创建函数
    join_monitor 任务加入监控函数
    task_alive 被监控任务上报函数
    task_monitor 监控任务函数

    使用示例:

    #include "ci110x_task_monitor.h"
    ​
    uint8_t vTask_test1_id,vTask_test2_id,vTask_test3_id;
    ​
    void vTask_test1(void *pvParameters)
    {
        int count = 0;
        for(;;)
        {
            vTaskDelay(pdMS_TO_TICKS(500));
            count++;
            task_alive(vTask_test1_id);
        }
    }
    ​
    void vTask_test2(void *pvParameters)
    {
        int count = 0;
        for(;;)
        {
            vTaskDelay(pdMS_TO_TICKS(4000));
            count++;
            task_alive(vTask_test2_id);
        }
    }
    ​
    void vTask_test3(void *pvParameters)
    {
        int count = 0;
        for(;;)
        {
            vTaskDelay(pdMS_TO_TICKS(12000));
            count++;
            task_alive(vTask_test3_id);
        }
    }
    ​
    void call_back(void)
    {
        mprintf("call back func
    ");
    }
    ​
    void iwdg_test(void)
    {
        monitor_creat(call_back);
    ​
        TaskHandle_t task1_handle = NULL,task2_handle = NULL,task3_handle = NULL;
    ​
        xTaskCreate(vTask_test1,"vTask_test1",256,NULL,1,&task1_handle);
        join_monitor(&vTask_test1_id,1000,task1_handle);
    ​
        xTaskCreate(vTask_test2,"vTask_test2",256,NULL,2,&task2_handle);
        join_monitor(&vTask_test2_id,5000,task2_handle);
    ​
        xTaskCreate(vTask_test3,"vTask_test3",256,NULL,3,&task3_handle);
        join_monitor(&vTask_test3_id,10000,task3_handle);
    ​
        xTaskCreate(task_monitor,"task_monitor",256,NULL,4,NULL);
    }

    常见问题

    • (待补充)

                                                                         ------脱命散人 2019.9.2 [记]

  • 相关阅读:
    Oracle备份 还原命令
    maven错误解决一:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile)
    maven File encoding has not been set
    maven 错误: 程序包org.junit不存在
    <转>JDBC获取DB元数据
    <转>SQL语句执行顺序说明
    Oracle 创建/删除 表空间、用户、授权
    lucene/solr 修改评分规则方法总结
    Solr入门之(8)中文分词器配置
    Solr入门之(7)Solr客户端界面简介
  • 原文地址:https://www.cnblogs.com/wangyanwen/p/11446614.html
Copyright © 2011-2022 走看看