esp8266-std/user/ne_monitor.c

211 lines
4.1 KiB
C
Raw Permalink Normal View History

2018-11-23 01:43:17 +00:00
/*
* ne_monitor.c -- provide iot-system thread protect operation interface.
*
*
* ORIGINAL AUTHOR:
*
* Copyright (c) 2018 Netease Corporation
*/
#include "c_types.h"
#include "ne_device.h"
#include "user_main.h"
#include "cfg.h"
#include "log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/timers.h"
#include "ne_monitor.h"
static ne_thread_monitor_t ne_thread_monitor;
/*
* system get ticks.
*/
uint32 ne_os_ticks_ms(uint32 ticks)
{
return (ticks) * (portTICK_RATE_MS);
}
/*
* system thread monitor check name.
*/
static int32 ne_thread_monitor_check_name(uint8 *name, ne_thread_monitor_t *ctx)
{
int i;
for(i=0;i<NE_THREAD_MONITOR_MAX;i++){
if(!ctx->thread_handle[i].is_valid)
continue;
if(strcmp(ctx->thread_handle[i].name, name))
continue;
return i;
}
return -ERR_FAIL;
}
/*
* system thread monitor unregister.
*/
int32 ne_thread_monitor_unregister(uint8 *name)
{
int32 index;
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
/* lock and check name whether exist */
xSemaphoreTake(ctx->sema, portMAX_DELAY);
index = ne_thread_monitor_check_name(name, ctx);
if (index < 0) {
LOG_EX(LOG_Error, "not found!\r\n");
/* unlock */
xSemaphoreGive(ctx->sema);
return -ERR_FAIL;
}
/* unregistered */
memset(&ctx->thread_handle[index], 0, sizeof(ne_thread_handle_t));
/* unlock */
xSemaphoreGive(ctx->sema);
return ERR_OK;
}
/*
* system thread monitor register.
*/
int32 ne_thread_monitor_register(void *thread_name, uint32 check_interval, int32 (* is_sick)(uint32 cmsec))
{
int32 i,ret;
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
if(thread_name == NULL || is_sick == NULL)
return -ERR_FAIL;
/* lock and check name whether registered */
xSemaphoreTake(ctx->sema, portMAX_DELAY);
ret = ne_thread_monitor_check_name(thread_name, ctx);
if(ret >= 0){
LOG_EX(LOG_Error, "already exit!\r\n");
}
/* register */
for(i=0;i<NE_THREAD_MONITOR_MAX;i++){
if(!ctx->thread_handle[i].is_valid){
ctx->thread_handle[i].is_valid = 1;
memcpy(ctx->thread_handle[i].name, thread_name, strlen(thread_name));
ctx->thread_handle[i].check_interval = check_interval;
ctx->thread_handle[i].is_sick = is_sick;
break;
}
}
/* unlock */
xSemaphoreGive(ctx->sema);
if(i >= NE_THREAD_MONITOR_MAX){
LOG_EX(LOG_Error, "register fail!\r\n");
return -ERR_FAIL;
}
return ERR_OK;
}
/*
* system thread monitor loop work.
*/
static void ne_thread_monitor_loop(void *arg)
{
int32 i,ret;
uint32 cmsec;
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
ctx->run_flag = 1;
while(ctx->run_flag){
xSemaphoreTake(ctx->sema, portMAX_DELAY);
for(i=0;i<NE_THREAD_MONITOR_MAX;i++){
cmsec = ne_os_ticks_ms(xTaskGetTickCount());
/* check valid */
if(!ctx->thread_handle[i].is_valid){
continue;
}
if(cmsec < ctx->thread_handle[i].lmsec + ctx->thread_handle[i].check_interval * 1000){
continue;
}
if(ctx->thread_handle[i].is_sick){
/* check thread */
ctx->thread_handle[i].is_sick(cmsec);
ctx->thread_handle[i].lmsec = cmsec;
}
}
xSemaphoreGive(ctx->sema);
vTaskDelay(100 / portTICK_RATE_MS);
}
}
/*
* system thread monitor start.
*/
int32 ne_thread_monitor_start(void)
{
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
if(!ctx->init_flag)
return -ERR_FAIL;
if(ctx->start_flag)
return ERR_OK;
if(xTaskCreate(ne_thread_monitor_loop, "thread_manage", 256, NULL, 5, NULL) !=pdPASS){
LOG_EX(LOG_Error, "start error!\r\n");
return -ERR_FAIL;
}
ctx->start_flag = 1;
return ERR_OK;
}
/*
* system thread monitor init.
*/
int32 ne_thread_monitor_init(void)
{
int32 ret;
ne_thread_monitor_t *ctx = NE_THREAD_MONITOR_CTX;
if(ctx->init_flag)
return ERR_OK;
ctx->sema = xSemaphoreCreateMutex();
if (ctx->sema == NULL) {
LOG_EX(LOG_Info, "init fail!\r\n");
return -ERR_FAIL;
}
ctx->init_flag = 1;
return ERR_OK;
}