提交 06cae326 编写于 作者: D daishengdong

add API (tos_task_create_dyn & tos_task_walkthru & tos_task_curr_task_get)

tos_task_create_dyn: create task with dynamic allocated task handler and stack
tos_task_walkthru: API to walk through the statistic list of all the existing task
tos_task_curr_task_get: get current running task handler
上级 c4d928a4
......@@ -11,6 +11,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -11,6 +11,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -11,6 +11,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -11,6 +11,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -11,6 +11,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -13,6 +13,8 @@
// 配置TencentOS tiny是否校验指针合法
#define TOS_CFG_OBJECT_VERIFY 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
// TencentOS tiny 事件模块功能宏
#define TOS_CFG_EVENT_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -11,6 +11,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
#ifndef TOS_CONFIG_H
#define TOS_CONFIG_H
#ifndef TOS_CONFIG_H
#define TOS_CONFIG_H
#include "stm32f4xx.h"
#include "stm32f4xx.h"
#define TOS_CFG_TASK_PRIO_MAX 10u
#define TOS_CFG_TASK_PRIO_MAX 10u
#define TOS_CFG_ROUND_ROBIN_EN 1u
#define TOS_CFG_ROUND_ROBIN_EN 1u
#define TOS_CFG_OBJECT_VERIFY 0u
#define TOS_CFG_OBJECT_VERIFY 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_MMBLK_EN 1u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMHEAP_EN 1u
#define TOS_CFG_MMBLK_EN 1u
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100
#define TOS_CFG_MMHEAP_EN 1u
#define TOS_CFG_MUTEX_EN 1u
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100
#define TOS_CFG_QUEUE_EN 1u
#define TOS_CFG_MUTEX_EN 1u
#define TOS_CFG_TIMER_EN 1u
#define TOS_CFG_QUEUE_EN 1u
#define TOS_CFG_SEM_EN 1u
#define TOS_CFG_TICKLESS_EN 0u
#if (TOS_CFG_QUEUE_EN > 0u)
#define TOS_CFG_MSG_EN 1u
#else
#define TOS_CFG_MSG_EN 0u
#endif
#define TOS_CFG_TIMER_EN 1u
#define TOS_CFG_MSG_POOL_SIZE 10u
#define TOS_CFG_SEM_EN 1u
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u
#define TOS_CFG_TICKLESS_EN 0u
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u
#if (TOS_CFG_QUEUE_EN > 0u)
#define TOS_CFG_MSG_EN 1u
#else
#define TOS_CFG_MSG_EN 0u
#endif
#define TOS_CFG_CPU_CLOCK (SystemCoreClock)
#define TOS_CFG_MSG_POOL_SIZE 10u
#define TOS_CFG_TIMER_AS_PROC 1u
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u
#endif
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u
#define TOS_CFG_CPU_CLOCK (SystemCoreClock)
#define TOS_CFG_TIMER_AS_PROC 1u
#endif
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......@@ -29,7 +31,7 @@
#define TOS_CFG_TICKLESS_EN 0u
#define TOS_CFG_VFS_EN 0u
#define TOS_CFG_VFS_EN 0u
#if (TOS_CFG_QUEUE_EN > 0u)
#define TOS_CFG_MSG_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 0u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 0u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 0u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY 0u // 配置TencentOS tiny是否校验指针合法
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -13,6 +13,8 @@
// 配置TencentOS tiny是否校验指针合法
#define TOS_CFG_OBJECT_VERIFY 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
// TencentOS tiny 事件模块功能宏
#define TOS_CFG_EVENT_EN 1u
......
......@@ -10,6 +10,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 1u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 1u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......@@ -43,7 +45,7 @@
#define TOS_CFG_MSG_POOL_SIZE 3u
#define TOS_CFG_IDLE_TASK_STK_SIZE 512u
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u
......
......@@ -9,6 +9,8 @@
#define TOS_CFG_OBJECT_VERIFY_EN 0u
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#define TOS_CFG_EVENT_EN 1u
#define TOS_CFG_MMBLK_EN 1u
......
......@@ -40,8 +40,12 @@
#error "INVALID config, TOS_CFG_TASK_PRIO_MAX must be >= 8"
#endif
#if (TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u) && (TOS_CFG_MMHEAP_EN == 0u)
#error "INVALID config, must enable TOS_CFG_MMHEAP_EN to support dynamic task create"
#endif
#if (TOS_CFG_QUEUE_EN > 0u) && (TOS_CFG_MSG_EN == 0u)
#error "INVALID config, must enable tos_msg to use tos_queue"
#error "INVALID config, must enable TOS_CFG_MSG_EN to use tos_queue"
#endif
#if ((TOS_CFG_TIMER_EN > 0u) && !defined(TOS_CFG_TIMER_AS_PROC))
......@@ -55,7 +59,7 @@
#endif
#if (TOS_CFG_VFS_EN > 0u) && (TOS_CFG_MMHEAP_EN == 0u)
#error "INVALID config, must enable tos_mmheap to use tos_vfs"
#error "INVALID config, must enable TOS_CFG_MMHEAP_EN to use tos_vfs"
#endif
#ifndef TOS_CFG_CPU_HRTIMER_EN
......
......@@ -33,6 +33,15 @@
/////////////////////////////////////////
/////////////////////////////////////////
// disable dynamic task create
#ifdef TOS_CFG_TASK_DYNAMIC_CREATE_EN
#undef TOS_CFG_TASK_DYNAMIC_CREATE_EN
#endif
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
/////////////////////////////////////////
/////////////////////////////////////////
// disable event
#ifdef TOS_CFG_EVENT_EN
......@@ -167,7 +176,11 @@
#else /* TOS_CFG_EVENT_DRIVEN_EN */
#ifndef TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 0u
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 0u
#endif
#ifndef TOS_CFG_TASK_DYNAMIC_CREATE_EN
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
#endif
#ifndef TOS_CFG_ROUND_ROBIN_EN
......@@ -275,6 +288,13 @@
#endif
#endif
#if (TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u)
#if TOS_CFG_IDLE_TASK_STK_SIZE < 512
#undef TOS_CFG_IDLE_TASK_STK_SIZE
#define TOS_CFG_IDLE_TASK_STK_SIZE 512u
#endif
#endif
#ifndef TOS_CFG_FAULT_BACKTRACE_EN
#define TOS_CFG_FAULT_BACKTRACE_EN 0u
#endif
......
......@@ -91,6 +91,7 @@ typedef enum k_err_en {
K_ERR_TASK_SUSPEND_IDLE,
K_ERR_TASK_STK_OVERFLOW,
K_ERR_TASK_STK_SIZE_INVALID,
K_ERR_TASK_OUT_OF_MEMORY,
K_ERR_TICKLESS_WKUP_ALARM_NOT_INSTALLED = 2000u,
K_ERR_TICKLESS_WKUP_ALARM_NO_INIT,
......
......@@ -44,7 +44,15 @@ extern k_stack_t k_idle_task_stk[];
extern k_stack_t *const k_idle_task_stk_addr;
extern size_t const k_idle_task_stk_size;
/* list to hold all the task delayed or pend for timeout */
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
/* list to hold all the destroyed dynamic created tasks */
extern k_list_t k_dead_task_list;
#endif
/* list to hold all the tasks for statistics */
extern k_list_t k_stat_list;
/* list to hold all the tasks delayed or pend for timeout */
extern k_list_t k_tick_list;
/* how many ticks will be triggered in a second */
......
......@@ -23,8 +23,24 @@
typedef struct k_sem_st {
pend_obj_t pend_obj;
k_sem_cnt_t count;
k_sem_cnt_t count_max;
} k_sem_t;
/**
* @brief Create a semaphore with a limitation of maximum count.
* create a semaphore with a limitation of maximum count.
*
* @attention None
*
* @param[in] sem pointer to the handler of the semaphore.
* @param[in] init_count initial count of the semaphore.
* @param[in] max_count maximum count of the semaphore.
*
* @return errcode
* @retval #K_ERR_NONE return successfully.
*/
__API__ k_err_t tos_sem_create_max(k_sem_t *sem, k_sem_cnt_t init_count, k_sem_cnt_t max_count);
/**
* @brief Create a semaphore.
* create a semaphore.
......@@ -32,6 +48,7 @@ typedef struct k_sem_st {
* @attention None
*
* @param[in] sem pointer to the handler of the semaphore.
* @param[in] init_count initial count of the semaphore.
*
* @return errcode
* @retval #K_ERR_NONE return successfully.
......
......@@ -31,10 +31,11 @@ typedef enum knl_state_en {
typedef enum knl_obj_type_en {
KNL_OBJ_TYPE_NONE = 0x0000,
KNL_OBJ_TYPE_TASK = 0xDAD1,
KNL_OBJ_TYPE_TIMER = 0xDAD2,
KNL_OBJ_TYPE_TASK_DYN = 0xDAD2,
KNL_OBJ_TYPE_TIMER = 0xDAD3,
KNL_OBJ_TYPE_MSG_QUEUE = 0xDAD4,
KNL_OBJ_TYPE_MMBLK_POOL = 0xDAD8,
KNL_OBJ_TYPE_FIFO = 0xDAE1,
KNL_OBJ_TYPE_MMBLK_POOL = 0xDAD5,
KNL_OBJ_TYPE_FIFO = 0xDAD6,
} knl_obj_type_t;
typedef struct knl_object_st {
......
......@@ -61,6 +61,8 @@
typedef void (*k_task_entry_t)(void *arg);
typedef void (*k_task_walker)(k_task_t *task);
/**
* task control block
*/
......@@ -80,6 +82,12 @@ typedef struct k_task_st {
k_stack_t *stk_base; /**< task stack base address */
size_t stk_size; /**< stack size of the task */
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
k_list_t dead_list; /**< when a dynamic allocated task destroyed, we hook the task's dead_list to the k_dead_task_list */
#endif
k_list_t stat_list; /**< list for hooking us to the k_stat_list */
k_tick_t tick_expires; /**< if we are in k_tick_list, how much time will we wait for? */
k_list_t tick_list; /**< list for hooking us to the k_tick_list */
......@@ -131,7 +139,6 @@ typedef struct k_task_st {
* @param[in] stk_base stack base address of the task.
* @param[in] stk_size stack size of the task.
* @param[in] timeslice time slice of the task.
* @param[in] opt option for the function call.
*
* @return errcode
* @retval #K_ERR_TASK_STK_SIZE_INVALID stack size is invalid.
......@@ -161,6 +168,51 @@ __API__ k_err_t tos_task_create(k_task_t *task,
*/
__API__ k_err_t tos_task_destroy(k_task_t *task);
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
/**
* @brief Create a task with a dynamic allocated task handler and stack.
* create a task with a dynamic allocated task handler and stack.
*
* @attention a task created by tos_task_create_dyn, should be destroyed by tos_task_destroy_dyn.
* @param[out] task dynamic allocated task handler.
* @param[in] name name of the task.
* @param[in] entry running entry of the task.
* @param[in] arg argument for the entry of the task.
* @param[in] prio priority of the task.
* @param[in] stk_size stack size of the task.
* @param[in] timeslice time slice of the task.
*
* @return errcode
* @retval #K_ERR_TASK_STK_SIZE_INVALID stack size is invalid.
* @retval #K_ERR_TASK_PRIO_INVALID priority is invalid.
* @retval #K_ERR_TASK_OUT_OF_MEMORY out of memory(insufficient heap memory).
* @retval #K_ERR_NONE return successfully.
*/
__API__ k_err_t tos_task_create_dyn(k_task_t **task,
char *name,
k_task_entry_t entry,
void *arg,
k_prio_t prio,
size_t stk_size,
k_timeslice_t timeslice);
/**
* @brief Destroy a dynamic created task.
* delete a dynamic created task.
*
* @attention the API to destroy a dynamic created task.
*
* @param[in] task pointer to the handler of the task to be deleted.
*
* @return errcode
* @retval #K_ERR_TASK_DESTROY_IDLE attempt to destroy idle task.
* @retval #K_ERR_NONE return successfully.
*/
__API__ k_err_t tos_task_destroy_dyn(k_task_t *task);
#endif
/**
* @brief Delay current task for ticks.
* Delay for a specified amount of ticks.
......@@ -245,6 +297,18 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new);
*/
__API__ void tos_task_yield(void);
/**
* @brief Get current running task.
* Get current running task.
*
* @attention is kernel is not running, you'll get K_NULL
*
* @param None
*
* @return current running task handler
*/
__API__ k_task_t *tos_task_curr_task_get(void);
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
......@@ -264,6 +328,30 @@ __API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth);
#endif
/**
* @brief Walk through all the tasks in the statistic list.
*
* @attention None
*
* @param[in] walker a function involved when meeting each tasks in the list.
*
* @return None
*/
__API__ void tos_task_walkthru(k_task_walker walker);
/**
* @brief A debug API for display all tasks information.
*
* @attention None
*
* @param None
*
* @return None
*/
__DEBUG__ void tos_task_info_display(void);
__KERNEL__ void task_free_all(void);
__KERNEL__ __STATIC_INLINE__ int task_state_is_ready(k_task_t *task)
{
return task->state == K_TASK_STATE_READY;
......@@ -324,5 +412,36 @@ __KERNEL__ __STATIC_INLINE__ void task_state_set_sleeping(k_task_t *task)
task->state |= K_TASK_STATE_SLEEP;
}
__DEBUG__ __STATIC_INLINE__ void task_default_walker(k_task_t *task)
{
char *state_str;
tos_kprintln("tsk name: %s", task->name);
if (task->state == K_TASK_STATE_PENDTIMEOUT_SUSPENDED) {
state_str = "PENDTIMEOUT_SUSPENDED";
} else if (task->state == K_TASK_STATE_PEND_SUSPENDED) {
state_str = "PEND_SUSPENDED";
} else if (task->state == K_TASK_STATE_SLEEP_SUSPENDED) {
state_str = "SLEEP_SUSPENDED";
} else if (task->state == K_TASK_STATE_PENDTIMEOUT) {
state_str = "PENDTIMEOUT";
} else if (task->state == K_TASK_STATE_SUSPENDED) {
state_str = "SUSPENDED";
} else if (task->state == K_TASK_STATE_PEND) {
state_str = "PEND";
} else if (task->state == K_TASK_STATE_SLEEP) {
state_str = "SLEEP";
} else if (task->state == K_TASK_STATE_READY) {
state_str = "READY";
}
tos_kprintln("tsk stat: %s", state_str);
tos_kprintln("stk size: %d", task->stk_size);
tos_kprintln("stk base: 0x%x", task->stk_base);
tos_kprintln("stk top : 0x%x", (cpu_addr_t)task->stk_base + task->stk_size);
tos_kprintln("");
}
#endif /* _TOS_TASK_H_ */
......@@ -36,6 +36,12 @@ k_tick_t k_cpu_tick_per_second = TOS_CFG_CPU_TICK_PER_SECOND;
k_cycle_t k_cpu_cycle_per_tick = (k_cycle_t)0u;
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
TOS_LIST_DEFINE(k_dead_task_list);
#endif
TOS_LIST_DEFINE(k_stat_list);
TOS_LIST_DEFINE(k_tick_list);
#if TOS_CFG_FAULT_BACKTRACE_EN > 0u
......
......@@ -96,27 +96,6 @@ __KERNEL__ void readyqueue_init(void)
}
}
__DEBUG__ void readyqueue_walkthru(void)
{
uint8_t i;
k_task_t *task;
k_list_t *task_list, *curr;
tos_kprintf("==========================\n");
tos_kprintf("%d\n", k_rdyq.highest_prio);
for (i = 0; i < TOS_CFG_TASK_PRIO_MAX; ++i) {
task_list = &k_rdyq.task_list_head[i];
if (!tos_list_empty(task_list)) {
TOS_LIST_FOR_EACH(curr, task_list) {
task = TOS_LIST_ENTRY(curr, k_task_t, pend_list);
tos_kprintf("---- %d %d [%d] %s\n", task->prio, i, task->state, task->name);
}
}
}
tos_kprintf("\n\n");
}
__KERNEL__ void readyqueue_add_head(k_task_t *task)
{
k_prio_t task_prio;
......
......@@ -19,16 +19,22 @@
#if TOS_CFG_SEM_EN > 0u
__API__ k_err_t tos_sem_create(k_sem_t *sem, k_sem_cnt_t init_count)
__API__ k_err_t tos_sem_create_max(k_sem_t *sem, k_sem_cnt_t init_count, k_sem_cnt_t max_count)
{
TOS_PTR_SANITY_CHECK(sem);
pend_object_init(&sem->pend_obj, PEND_TYPE_SEM);
sem->count = init_count;
sem->count = init_count;
sem->count_max = max_count;
return K_ERR_NONE;
}
__API__ k_err_t tos_sem_create(k_sem_t *sem, k_sem_cnt_t init_count)
{
return tos_sem_create_max(sem, init_count, (k_sem_cnt_t)-1);
}
__API__ k_err_t tos_sem_destroy(k_sem_t *sem)
{
TOS_CPU_CPSR_ALLOC();
......@@ -69,7 +75,7 @@ __STATIC__ k_err_t sem_do_post(k_sem_t *sem, opt_post_t opt)
TOS_CPU_INT_DISABLE();
if (sem->count == (k_sem_cnt_t)-1) {
if (sem->count == sem->count_max) {
TOS_CPU_INT_ENABLE();
return K_ERR_SEM_OVERFLOW;
}
......
......@@ -268,6 +268,10 @@ __STATIC__ void knl_idle_entry(void *arg)
arg = arg; // make compiler happy
while (K_TRUE) {
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
task_free_all();
#endif
#if TOS_CFG_PWR_MGR_EN > 0u
pm_power_manager();
#endif
......
......@@ -23,6 +23,10 @@ __STATIC_INLINE__ void task_reset(k_task_t *task)
knl_object_deinit(&task->knl_obj);
#endif
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
tos_list_init(&task->dead_list);
#endif
tos_list_init(&task->stat_list);
tos_list_init(&task->tick_list);
tos_list_init(&task->pend_list);
......@@ -102,6 +106,8 @@ __API__ k_err_t tos_task_create(k_task_t *task,
}
task_reset(task);
tos_list_add(&task->stat_list, &k_stat_list);
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
knl_object_init(&task->knl_obj, KNL_OBJ_TYPE_TASK);
#endif
......@@ -136,30 +142,14 @@ __API__ k_err_t tos_task_create(k_task_t *task,
return K_ERR_NONE;
}
__API__ k_err_t tos_task_destroy(k_task_t *task)
__STATIC__ k_err_t task_do_destroy(k_task_t *task)
{
TOS_CPU_CPSR_ALLOC();
TOS_IN_IRQ_CHECK();
if (unlikely(!task)) {
task = k_curr_task;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
return K_ERR_OBJ_INVALID;
}
#endif
if (knl_is_idle(task)) {
return K_ERR_TASK_DESTROY_IDLE;
}
if (knl_is_self(task) && knl_is_sched_locked()) {
return K_ERR_SCHED_LOCKED;
}
TOS_CPU_INT_DISABLE();
#if TOS_CFG_MUTEX_EN > 0u
......@@ -179,7 +169,9 @@ __API__ k_err_t tos_task_destroy(k_task_t *task)
pend_list_remove(task);
}
tos_list_del(&task->stat_list);
task_reset(task);
task_state_set_deleted(task);
TOS_CPU_INT_ENABLE();
......@@ -188,6 +180,147 @@ __API__ k_err_t tos_task_destroy(k_task_t *task)
return K_ERR_NONE;
}
__API__ k_err_t tos_task_destroy(k_task_t *task)
{
TOS_IN_IRQ_CHECK();
if (unlikely(!task)) {
task = k_curr_task;
}
if (knl_is_self(task) && knl_is_sched_locked()) {
return K_ERR_SCHED_LOCKED;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
return K_ERR_OBJ_INVALID;
}
#endif
return task_do_destroy(task);
}
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
__API__ k_err_t tos_task_create_dyn(k_task_t **task,
char *name,
k_task_entry_t entry,
void *arg,
k_prio_t prio,
size_t stk_size,
k_timeslice_t timeslice)
{
k_err_t err;
k_task_t *the_task;
k_stack_t *stk_base;
TOS_IN_IRQ_CHECK();
TOS_PTR_SANITY_CHECK(task);
TOS_PTR_SANITY_CHECK(entry);
if (unlikely(stk_size < sizeof(cpu_context_t))) {
return K_ERR_TASK_STK_SIZE_INVALID;
}
if (unlikely(prio == K_TASK_PRIO_IDLE)) {
return K_ERR_TASK_PRIO_INVALID;
}
if (unlikely(prio > K_TASK_PRIO_IDLE)) {
return K_ERR_TASK_PRIO_INVALID;
}
the_task = tos_mmheap_alloc(sizeof(k_task_t));
if (!the_task) {
return K_ERR_TASK_OUT_OF_MEMORY;
}
stk_base = tos_mmheap_aligned_alloc(stk_size, sizeof(cpu_addr_t));
if (!stk_base) {
tos_mmheap_free(the_task);
return K_ERR_TASK_OUT_OF_MEMORY;
}
err = tos_task_create(the_task, name, entry, arg, prio, stk_base, stk_size, timeslice);
if (err != K_ERR_NONE) {
tos_mmheap_free(stk_base);
tos_mmheap_free(the_task);
return err;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
knl_object_init(&the_task->knl_obj, KNL_OBJ_TYPE_TASK_DYN);
#endif
*task = the_task;
return K_ERR_NONE;
}
__API__ k_err_t tos_task_destroy_dyn(k_task_t *task)
{
k_err_t err;
TOS_IN_IRQ_CHECK();
if (unlikely(!task)) {
task = k_curr_task;
}
if (knl_is_self(task) && knl_is_sched_locked()) {
return K_ERR_SCHED_LOCKED;
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
tos_knl_sched_lock();
err = task_do_destroy(task);
if (err != K_ERR_NONE) {
tos_knl_sched_unlock();
return err;
}
if (knl_is_self(task)) { // we are destroying ourself
// in this situation, we cannot just free ourself's task stack because we are using it
// we count on the idle task to free the memory
tos_list_add(&task->dead_list, &k_dead_task_list);
} else {
tos_mmheap_free(task->stk_base);
tos_mmheap_free(task);
}
tos_knl_sched_unlock();
return K_ERR_NONE;
}
__KERNEL__ void task_free_all(void)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *task;
k_list_t *curr, *next;
TOS_CPU_INT_DISABLE();
TOS_LIST_FOR_EACH_SAFE(curr, next, &k_dead_task_list) {
task = TOS_LIST_ENTRY(curr, k_task_t, dead_list);
tos_list_del(&task->dead_list);
tos_mmheap_free(task->stk_base);
tos_mmheap_free(task);
}
TOS_CPU_INT_ENABLE();
}
#endif
__API__ void tos_task_yield(void)
{
TOS_CPU_CPSR_ALLOC();
......@@ -216,7 +349,8 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new)
TOS_IN_IRQ_CHECK();
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
......@@ -278,7 +412,8 @@ __API__ k_err_t tos_task_suspend(k_task_t *task)
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
......@@ -311,7 +446,8 @@ __API__ k_err_t tos_task_resume(k_task_t *task)
TOS_PTR_SANITY_CHECK(task);
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
......@@ -378,7 +514,8 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task)
TOS_IN_IRQ_CHECK();
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
......@@ -404,6 +541,45 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task)
return K_ERR_NONE;
}
__API__ k_task_t *tos_task_curr_task_get(void)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *curr_task = K_NULL;
TOS_CPU_INT_DISABLE();
if (likely(tos_knl_is_running())) {
curr_task = k_curr_task;
}
TOS_CPU_INT_ENABLE();
return curr_task;
}
__API__ void tos_task_walkthru(k_task_walker walker)
{
TOS_CPU_CPSR_ALLOC();
k_task_t *task;
k_list_t *curr;
if (!walker) {
return;
}
TOS_CPU_INT_DISABLE();
TOS_LIST_FOR_EACH(curr, &k_stat_list) {
task = TOS_LIST_ENTRY(curr, k_task_t, stat_list);
walker(task);
}
TOS_CPU_INT_ENABLE();
}
__DEBUG__ void tos_task_info_display(void)
{
tos_task_walkthru(task_default_walker);
}
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
__API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth)
......@@ -418,7 +594,8 @@ __API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth)
}
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK) &&
!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK_DYN)) {
return K_ERR_OBJ_INVALID;
}
#endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册