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; | ||
|  | } |