375 lines
10 KiB
C
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;
|
|
}
|