Files
kunlun/common/share_task/iot_share_task.c
2024-09-28 14:24:04 +08:00

375 lines
10 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_mem.h"
/* common includes */
#include "iot_errno.h"
#include "iot_module.h"
#include "iot_config.h"
#include "iot_share_task.h"
#include "iot_io_api.h"
#include "os_task.h"
#define IOT_SHARE_TASK_L_POOL_SIZE 64
#define IOT_SHARE_TASK_H_POOL_SIZE 32
#define IOT_SHARE_EVENT_VALID_PATTERN 0xBEBC5489
#if IOT_CRYPTO_ASYNC_SUPPORT
#define IOT_SHARE_TASK_L_STACK_SIZE (IOT_DEFAULT_STACK_SIZE + 256)
#else
#define IOT_SHARE_TASK_L_STACK_SIZE IOT_DEFAULT_STACK_SIZE
#endif
typedef struct _iot_share_task_data
{
iot_task_h task_handle;
iot_task_config_t task_cfg;
}iot_share_task_data_t;
typedef struct _iot_share_task_event
{
int arg;
int valid;
iot_share_event_func handler;
}iot_share_task_event;
typedef struct _iot_share_task_mt
{
/* message type corresponding execute function */
iot_share_msg_func_t exe_func;
/* message type corresponding cancel function */
iot_share_msg_cancel_func_t cancel_func;
} iot_share_task_mt_t;
typedef struct _iot_share_twins_task
{
iot_share_task_data_t faster; /* The higher priority task */
iot_share_task_data_t slower; /* The lower priority task */
iot_share_task_event twins_event[IOT_SHARE_EVENT_END];
/* message type handler array */
iot_share_task_mt_t mt_handle[IOT_SHARE_TASK_MT_MAX];
}iot_share_twins_task;
static iot_share_twins_task twins_task;
#define FASTER() (&twins_task.faster)
#define SLOWER() (&twins_task.slower)
#define EVENT_PNTR(type) (&(twins_task.twins_event[type-1]))
#define EVENT_TYPE_VALID(tp)\
((tp) >= IOT_SHARE_EVENT_START && (tp) <= IOT_SHARE_EVENT_END)
static void iot_share_task_handle_msg(iot_task_h task_h, iot_task_msg_t *msg,
int excute)
{
iot_share_task_msg_t *task_msg = (iot_share_task_msg_t*)msg;
iot_share_task_data_t *p_task = NULL;
iot_share_task_mt_t *mt_handle = NULL;
if (NULL == task_msg)
{
IOT_ASSERT(0);
return;
}
if (task_h == twins_task.faster.task_handle)
{
p_task = &twins_task.faster;
}
else if (task_h == twins_task.slower.task_handle)
{
p_task = &twins_task.slower;
}
else
{
IOT_ASSERT(0);
return;
}
if (task_msg->msg.type && task_msg->msg.type <= IOT_SHARE_TASK_MT_MAX) {
mt_handle = &twins_task.mt_handle[task_msg->msg.type - 1];
IOT_ASSERT(mt_handle);
if (excute) {
mt_handle->exe_func(&task_msg->msg.link);
} else {
mt_handle->cancel_func(&task_msg->msg.link);
}
} else {
/* unkown message */
IOT_ASSERT(0);
}
iot_task_free_msg(p_task->task_handle, &task_msg->msg);
return;
}
static void iot_share_task_handle_msg_cancel
(iot_task_h task_h, iot_task_msg_t *msg)
{
iot_share_task_handle_msg(task_h, msg, 0);
}
static void iot_share_task_handle_msg_excute
(iot_task_h task_h, iot_task_msg_t *msg)
{
iot_share_task_handle_msg(task_h, msg, 1);
}
static void iot_share_task_handle_event
(iot_task_h task_h, uint32_t event)
{
iot_share_task_event *p_event = NULL;
uint32_t type, mask;
for (type = IOT_SHARE_EVENT_START; type < IOT_SHARE_EVENT_END; type++)
{
mask = (1 << type);
if (mask & event)
{
p_event = EVENT_PNTR(type);
if (p_event->handler)
{
p_event->handler(p_event->arg);
}
}
}
(void)task_h;
return;
}
static inline iot_share_task_data_t * IRAM_ATTR iot_share_task_route_task
(uint32_t prio)
{
return (IOT_SHARE_TASK_QUEUE_HP == prio) ? FASTER() : SLOWER();
}
uint32_t iot_share_task_post_msg(uint32_t prio, uint16_t msg_type,
uint16_t msg_id, uint32_t data1, void *data2)
{
iot_task_msg_t *msg;
iot_share_task_msg_t *task_msg;
iot_share_task_data_t *p_task = NULL;
if (NULL == (p_task = iot_share_task_route_task(prio)))
{
iot_printf("iot_share_task_post_msg, return - prio error.\n");
return ERR_FAIL;
}
msg = iot_task_alloc_msg_with_reserved(p_task->task_handle, 0);
if (msg == NULL)
{
iot_printf("iot_share_task_post_msg, return - no msg for queue.\n");
return ERR_FAIL;
}
task_msg = (iot_share_task_msg_t*)msg;
task_msg->msg.type = msg_type;
task_msg->msg.id = msg_id;
task_msg->data1 = data1;
task_msg->data2 = data2;
iot_task_queue_msg(p_task->task_handle, &task_msg->msg, 0);
return ERR_OK;
}
void iot_share_task_clean_msg(uint16_t msg_type, uint16_t msg_id)
{
iot_share_task_data_t *p_task = NULL;
p_task = FASTER();
iot_task_clean_msg(p_task->task_handle, msg_type, msg_id);
p_task = SLOWER();
iot_task_clean_msg(p_task->task_handle, msg_type, msg_id);
return;
}
uint32_t iot_share_task_msg_register(uint16_t msg_type,
iot_share_msg_func_t exe_func, iot_share_msg_cancel_func_t cancel_func)
{
iot_share_task_mt_t *mt_handle;
if (msg_type == 0 || msg_type > IOT_SHARE_TASK_MT_MAX)
return ERR_INVAL;
if (exe_func == NULL || cancel_func == NULL)
return ERR_INVAL;
mt_handle = &twins_task.mt_handle[msg_type - 1];
if (mt_handle->exe_func || mt_handle->cancel_func)
return ERR_EXIST;
mt_handle->exe_func = exe_func;
mt_handle->cancel_func = cancel_func;
return ERR_OK;
}
static uint32_t IRAM_ATTR iot_share_task_post_event
(uint32_t prio, iot_share_event_type type, int isr)
{
iot_share_task_data_t *p_task = NULL;
uint32_t event;
if (NULL == (p_task = iot_share_task_route_task(prio))
|| (!EVENT_TYPE_VALID(type)))
{
return ERR_FAIL;
}
event = (1 << type);
if(isr)
{
os_set_task_event_with_v_from_isr(
iot_task_get_os_task_h(p_task->task_handle), event);
}
else
{
os_set_task_event_with_v(iot_task_get_os_task_h(p_task->task_handle),
event);
}
return ERR_OK;
}
uint32_t iot_share_task_event_register
(iot_share_event_type type, iot_share_event_func func, int arg)
{
iot_share_task_event *p_event = NULL;
if (!EVENT_TYPE_VALID(type)
|| NULL == func)
{
return ERR_FAIL;
}
p_event = EVENT_PNTR(type);
/* Compare with initialized value '0' */
if(!os_atomic_check_set
(&(p_event->valid), 0, IOT_SHARE_EVENT_VALID_PATTERN))
{
return ERR_FAIL;
}
if (p_event->handler && p_event->handler != func)
{
return ERR_FAIL;
}
p_event->handler = func;
p_event->arg = arg;
return ERR_OK;
}
uint32_t IRAM_ATTR iot_share_task_post_event_from_isr
(uint32_t prio, iot_share_event_type type)
{
return iot_share_task_post_event(prio, type, 1);
}
uint32_t iot_share_task_post_event_from_task
(uint32_t prio, iot_share_event_type type)
{
return iot_share_task_post_event(prio, type, 0);
}
uint32_t iot_share_task_init()
{
iot_share_task_data_t *p_task = NULL;
p_task = SLOWER();
if (p_task->task_handle == NULL)
{
p_task->task_cfg.stack_size = IOT_SHARE_TASK_L_STACK_SIZE;
p_task->task_cfg.task_prio = IOT_SHARE_TASK_L_PRIO;
p_task->task_cfg.msg_size = sizeof(iot_share_task_msg_t);
p_task->task_cfg.msg_cnt = IOT_SHARE_TASK_L_POOL_SIZE;
p_task->task_cfg.queue_cnt = 1;
p_task->task_cfg.queue_cfg[0].quota = 0;
p_task->task_cfg.task_event_func = iot_share_task_handle_event;
p_task->task_cfg.msg_exe_func = iot_share_task_handle_msg_excute;
p_task->task_cfg.msg_cancel_func = iot_share_task_handle_msg_cancel;
p_task->task_handle = iot_task_create(IOT_SHARE_TASK,
&p_task->task_cfg);
if (NULL == p_task->task_handle)
{
return ERR_FAIL;
}
}
p_task = FASTER();
if (p_task->task_handle == NULL)
{
p_task->task_cfg.stack_size = 0;
p_task->task_cfg.task_prio = IOT_SHARE_TASK_H_PRIO;
p_task->task_cfg.msg_size = sizeof(iot_share_task_msg_t);
p_task->task_cfg.msg_cnt = IOT_SHARE_TASK_H_POOL_SIZE;
p_task->task_cfg.queue_cnt = 1;
p_task->task_cfg.queue_cfg[0].quota = 0;
p_task->task_cfg.task_event_func = iot_share_task_handle_event;
p_task->task_cfg.msg_exe_func = iot_share_task_handle_msg_excute;
p_task->task_cfg.msg_cancel_func = iot_share_task_handle_msg_cancel;
p_task->task_handle = iot_task_create(IOT_SHARE_TASK,
&p_task->task_cfg);
if (NULL == p_task->task_handle)
{
/* Roll back */
p_task = SLOWER();
iot_task_delete(p_task->task_handle);
p_task->task_handle = NULL;
return ERR_FAIL;
}
}
os_mem_set(&twins_task.twins_event[0], 0x0,
IOT_SHARE_EVENT_END * sizeof(twins_task.twins_event[0]));
os_mem_set(twins_task.mt_handle, 0x0, sizeof(twins_task.mt_handle));
return ERR_OK;
}
void iot_share_task_deinit()
{
iot_share_task_data_t *p_task = NULL;
p_task = SLOWER();
if (p_task->task_handle != NULL)
{
iot_task_delete(p_task->task_handle);
p_task->task_handle = NULL;
}
p_task = FASTER();
if (p_task->task_handle != NULL)
{
iot_task_delete(p_task->task_handle);
p_task->task_handle = NULL;
}
return;
}