243 lines
11 KiB
C
243 lines
11 KiB
C
/*----------------------------------------------------------------------------
|
|
* Copyright (c) TJD Technologies Co., Ltd. 2020. All rights reserved.
|
|
*
|
|
* Description: task_service_timer.c
|
|
*
|
|
* Author: saimen
|
|
*
|
|
* Create: 2024-4-23
|
|
*--------------------------------------------------------------------------*/
|
|
//lib
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
//os
|
|
#include "securec.h"
|
|
#include "common_def.h"
|
|
#include "debug_print.h"
|
|
#include "soc_osal.h"
|
|
#include "cmsis_os2.h"
|
|
//sdk
|
|
//drv
|
|
//user
|
|
#include "sys_typedef.h"
|
|
#include "sys_config.h"
|
|
#include "sys_dlist.h"
|
|
#include "task_service_timer.h"
|
|
|
|
/**********************************************************************************************************************
|
|
* DEFINE
|
|
*/
|
|
#define ENABLE_STATIC_PRINT_INFO false
|
|
#define ENABLE_STATIC_PRINT_WARN true
|
|
#define ENABLE_STATIC_PRINT_ERROR true
|
|
#if ENABLE_STATIC_PRINT_INFO
|
|
#define static_print_debug(...) sys_common_printf(__VA_ARGS__)
|
|
#else
|
|
#define static_print_debug(...)
|
|
#endif
|
|
#if ENABLE_STATIC_PRINT_WARN
|
|
#define static_print_warn(...) sys_common_printf(__VA_ARGS__)
|
|
#else
|
|
#define static_print_warn(...)
|
|
#endif
|
|
#if ENABLE_STATIC_PRINT_ERROR
|
|
#define static_print_error(...) sys_common_printf(__VA_ARGS__)
|
|
#else
|
|
#define static_print_error(...)
|
|
#endif
|
|
|
|
#define QUEUE_SERVICE_TIMER_COUNT 16
|
|
#define LIST_SERVICE_TIMER_COUNT 16
|
|
#define OSAL_MSGQ_WAIT_MIN_MS (9)
|
|
#define OSAL_MSGQ_WAIT_MAX_MS (9000)
|
|
|
|
typedef struct
|
|
{
|
|
tjd_sys_dlist_t dlist;
|
|
queue_default_info_t queue_handler;
|
|
unsigned int last_time;
|
|
} service_timer_dlist_t;
|
|
|
|
typedef struct
|
|
{
|
|
unsigned int *task_handle;
|
|
unsigned long queue;
|
|
unsigned int queue_wait;
|
|
unsigned int min_interval;
|
|
} model_service_timer_info_t;
|
|
/**********************************************************************************************************************
|
|
* VARIABLES
|
|
*/
|
|
model_service_timer_info_t g_model_service_timer_info = {0};
|
|
service_timer_dlist_t g_service_timer_list = {0};
|
|
|
|
/**********************************************************************************************************************
|
|
* LOCAL FUNCTIONS
|
|
*/
|
|
static int function_dlist_cmpr_handle(const tjd_sys_dlist_item_t *item_a, const tjd_sys_dlist_item_t *item_b)
|
|
{
|
|
service_timer_dlist_t *temp_item_a = (service_timer_dlist_t *) item_a;
|
|
service_timer_dlist_t *temp_item_b = (service_timer_dlist_t *) item_b;
|
|
if(temp_item_a == NULL || temp_item_b == NULL) {
|
|
return RET_ERROR;
|
|
}
|
|
if(temp_item_a->queue_handler.func_event_handler == temp_item_b->queue_handler.func_event_handler && temp_item_a->queue_handler.param == temp_item_b->queue_handler.param) {
|
|
return RET_SUCCESS;
|
|
}
|
|
return RET_FAIL_BASE;
|
|
}
|
|
|
|
static int function_dlist_find_run(tjd_sys_dlist_t *dlist, unsigned int cur_sys_tick)
|
|
{
|
|
tjd_sys_dlist_t *curr_item = NULL;
|
|
tjd_sys_dlist_t *next_item = NULL;
|
|
service_timer_dlist_t *curr_node = NULL;
|
|
unsigned int node_count = 0;
|
|
g_model_service_timer_info.min_interval = OSAL_MSGQ_WAIT_MAX_MS;
|
|
|
|
if (dlist == NULL) {
|
|
return RET_ERROR;
|
|
}
|
|
|
|
TJD_SYS_DLIST_FOR_EACH(curr_item, next_item, dlist) {
|
|
curr_node = (service_timer_dlist_t *)curr_item;
|
|
node_count++;
|
|
if (cur_sys_tick - curr_node->last_time >= curr_node->queue_handler.value) {
|
|
if(curr_node->queue_handler.func_event_handler) {
|
|
curr_node->last_time += curr_node->queue_handler.value;
|
|
//curr_node->last_time = cur_sys_tick;
|
|
curr_node->queue_handler.value = curr_node->queue_handler.func_event_handler(curr_node->queue_handler.param);
|
|
static_print_debug("function_dlist_find_run()1:node=%d-%p-%d,time=%d-%d\r\n", node_count, curr_node->queue_handler.func_event_handler, curr_node->queue_handler.value, cur_sys_tick, curr_node->last_time);
|
|
}
|
|
|
|
if(curr_node->queue_handler.value <= 0) {
|
|
tjd_sys_dlist_remove(curr_item);
|
|
osal_kfree(curr_item);
|
|
}
|
|
}
|
|
if (cur_sys_tick - curr_node->last_time >= curr_node->queue_handler.value) {
|
|
g_model_service_timer_info.min_interval = OSAL_MSGQ_WAIT_MIN_MS;
|
|
} else {
|
|
unsigned int temp_interval = curr_node->queue_handler.value - (cur_sys_tick - curr_node->last_time);
|
|
g_model_service_timer_info.min_interval = (g_model_service_timer_info.min_interval > temp_interval)? temp_interval:g_model_service_timer_info.min_interval;
|
|
}
|
|
}
|
|
|
|
if(node_count == 0){
|
|
g_model_service_timer_info.queue_wait = OSAL_MSGQ_WAIT_MAX_MS;
|
|
} else {
|
|
g_model_service_timer_info.queue_wait = (g_model_service_timer_info.min_interval<OSAL_MSGQ_WAIT_MIN_MS)? OSAL_MSGQ_WAIT_MIN_MS:g_model_service_timer_info.min_interval;
|
|
}
|
|
curr_node = (service_timer_dlist_t *)dlist;//get head point, head list node no used.
|
|
curr_node->queue_handler.value = node_count;
|
|
static_print_debug("function_dlist_find_run() END:node=%d-%d-%d\r\n", node_count, g_model_service_timer_info.min_interval, g_model_service_timer_info.queue_wait);
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
/**********************************************************************************************************************
|
|
* PUBLIC FUNCTIONS
|
|
*/
|
|
unsigned int *tjd_task_service_timer_get_task_handle(void)
|
|
{
|
|
return g_model_service_timer_info.task_handle;
|
|
}
|
|
|
|
unsigned long tjd_task_service_timer_get_queue_id(void)
|
|
{
|
|
return g_model_service_timer_info.queue;
|
|
}
|
|
|
|
void tjd_task_service_timer_entry(void *param)
|
|
{
|
|
unused(param);
|
|
int32_t ret = OSAL_FAILURE;
|
|
unsigned int msg_size = sizeof(queue_default_info_t);
|
|
unsigned int cur_sys_tick = 0;
|
|
unsigned int max_interval = 0;
|
|
service_timer_dlist_t *cur_service_node = NULL;
|
|
service_timer_dlist_t *find_service_node = NULL;
|
|
tjd_sys_dlist_create(&g_service_timer_list.dlist);
|
|
|
|
while (1) {
|
|
if(cur_service_node == NULL) {
|
|
cur_service_node = (service_timer_dlist_t *)osal_kmalloc(sizeof(service_timer_dlist_t), OSAL_GFP_KERNEL);
|
|
if(cur_service_node == NULL) {
|
|
osDelay(5000);
|
|
continue;
|
|
}
|
|
memset_s(&cur_service_node->queue_handler, sizeof(queue_default_info_t), 0, sizeof(queue_default_info_t));
|
|
}
|
|
|
|
ret = osal_msg_queue_read_copy(g_model_service_timer_info.queue, &cur_service_node->queue_handler, &msg_size, g_model_service_timer_info.queue_wait);
|
|
cur_sys_tick = osKernelGetTickCount();
|
|
if (ret == OSAL_SUCCESS) {
|
|
static_print_debug("queue_service_timer_default_info_t: service_node:0x%X-0x%X-%d\r\n", cur_service_node, cur_service_node->queue_handler.func_event_handler, cur_service_node->queue_handler.value);
|
|
find_service_node = (service_timer_dlist_t *)tjd_sys_dlist_find(&g_service_timer_list.dlist, &cur_service_node->dlist, function_dlist_cmpr_handle);
|
|
if(find_service_node == NULL) {
|
|
if(cur_service_node->queue_handler.value <= 0) {
|
|
static_print_debug("service_timer delete list: NOT FIND\r\n");
|
|
memset_s(&cur_service_node->queue_handler, sizeof(queue_default_info_t), 0, sizeof(queue_default_info_t));
|
|
} else {
|
|
cur_service_node->last_time = cur_sys_tick;
|
|
if(cur_service_node->queue_handler.value <= 2 )//注释本行代表:所有服务首次都是立即执行。
|
|
{
|
|
cur_service_node->last_time = cur_sys_tick - cur_service_node->queue_handler.value;
|
|
}
|
|
tjd_sys_dlist_append(&g_service_timer_list.dlist, &cur_service_node->dlist);
|
|
static_print_debug("service_timer add list: service_node:0x%X-0x%X-%d\r\n", find_service_node, &cur_service_node->dlist, g_service_timer_list.queue_handler.value);
|
|
cur_service_node = NULL;
|
|
}
|
|
}else{
|
|
if(cur_service_node->queue_handler.value <= 0) {
|
|
static_print_debug("service_timer delete list: service_node:0x%X\r\n", find_service_node);
|
|
tjd_sys_dlist_remove(&find_service_node->dlist);
|
|
osal_kfree(find_service_node);
|
|
}
|
|
static_print_debug("service_timer in list: service_node:0x%X-0x%X-%d\r\n", find_service_node, &cur_service_node->dlist, find_service_node->queue_handler.value);
|
|
memset_s(&cur_service_node->queue_handler, sizeof(queue_default_info_t), 0, sizeof(queue_default_info_t));
|
|
}
|
|
}
|
|
|
|
function_dlist_find_run(&g_service_timer_list.dlist, cur_sys_tick);
|
|
}
|
|
}
|
|
|
|
void tjd_task_service_timer_init(unsigned short stack_depth, unsigned short priority)
|
|
{
|
|
osal_msg_queue_create("tjd_q_service_timer", QUEUE_SERVICE_TIMER_COUNT, &g_model_service_timer_info.queue, 0, sizeof(queue_default_info_t));
|
|
|
|
#define APP_MAIN_STACK_SIZE 0x1000
|
|
#define TASK_PRIORITY_APP (osPriority_t)(17)
|
|
osThreadAttr_t task_attr = { "tjd_t_service_timer", 0, NULL, 0, NULL, APP_MAIN_STACK_SIZE, TASK_PRIORITY_APP, 0, 0 };
|
|
if(stack_depth>APP_MAIN_STACK_SIZE){
|
|
task_attr.stack_size = stack_depth;
|
|
}
|
|
if(priority>TASK_PRIORITY_APP){
|
|
//task_attr.priority = priority;
|
|
}
|
|
task_attr.stack_mem = memalign(16, task_attr.stack_size);//add
|
|
g_model_service_timer_info.task_handle = osThreadNew(tjd_task_service_timer_entry, NULL, &task_attr);
|
|
g_model_service_timer_info.queue_wait = OSAL_MSGQ_WAIT_MAX_MS;
|
|
static_print_warn("tjd_task_service_timer_init() END: task-0x%X queue-0x%X-%d\r\n", g_model_service_timer_info.task_handle, g_model_service_timer_info.queue, sizeof(queue_default_info_t));
|
|
}
|
|
|
|
/**********************************************************************************************************************
|
|
* TEST FUNCTIONS
|
|
*/
|
|
static unsigned long s_test_param;
|
|
signed int tjd_task_service_timer_test_handle(void *param)
|
|
{
|
|
unsigned long *p_param = (unsigned long *)param;
|
|
static_print_debug("tjd_task_service_timer_test_handle(): param=%d\r\n", *p_param);
|
|
s_test_param++;
|
|
return 1000; //定时执行间隔单位为ms
|
|
}
|
|
|
|
void tjd_task_service_timer_test_send(void)
|
|
{
|
|
queue_default_info_t msg_data = { tjd_task_service_timer_test_handle, &s_test_param, 500, NULL };//500ms首次执行的等待时间。
|
|
osal_msg_queue_write_copy(tjd_task_service_timer_get_queue_id(), (void *)&msg_data, sizeof(queue_default_info_t), 0);
|
|
}
|
|
|