系统监控组件(基于嵌入式实时操作系统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\n");
 56     }
 57     ci_logdebug(LOG_USER,"xEventGroupCreate Success\n");
 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,"已经达到监控任务的最大个数.\n");
 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 个任务.\n",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.\n");
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.\n");
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\n",monitor_list[i].id);
143                         #if ADJUST_TASK_PRIORITY_EN
144                         ci_logdebug(LOG_USER,"调整任务优先级\n");
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\n",monitor_list[i].id);
158                         if(NULL != iwdg_callback)
159                         {
160                             iwdg_callback();
161                         }
162                         ci_logdebug(LOG_USER,"系统复位\n");
163                         /* 任务死掉,复位系统 */
164                         Scu_SoftwareRst_System();
165                         while(1);
166                     }
167                 }
168             }
169             else
170             {
171                 ci_logdebug(LOG_USER,"%d:该bit以及被设置\n",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\n",monitor_list[i].id);
176                     #if ADJUST_TASK_PRIORITY_EN
177                     ci_logdebug(LOG_USER,"还原任务优先级\n");
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\n");
}
​
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 [记]

posted @ 2019-09-02 14:59  wangyanwen  阅读(1098)  评论(0)    收藏  举报