Merge remote-tracking branch 'TOS/master'
port to msp430fr
This commit is contained in:
@@ -35,11 +35,16 @@
|
||||
#include <tos_pm.h>
|
||||
#include <tos_pend.h>
|
||||
#include <tos_sys.h>
|
||||
#include <tos_fifo.h>
|
||||
#include <tos_ring_queue.h>
|
||||
#include <tos_char_fifo.h>
|
||||
#include <tos_mail_queue.h>
|
||||
#include <tos_message_queue.h>
|
||||
#include <tos_binary_heap.h>
|
||||
#include <tos_priority_queue.h>
|
||||
#include <tos_priority_mail_queue.h>
|
||||
#include <tos_priority_message_queue.h>
|
||||
#include <tos_task.h>
|
||||
#include <tos_robin.h>
|
||||
#include <tos_msg.h>
|
||||
#include <tos_queue.h>
|
||||
#include <tos_mutex.h>
|
||||
#include <tos_sem.h>
|
||||
#include <tos_event.h>
|
||||
|
180
kernel/core/include/tos_binary_heap.h
Normal file
180
kernel/core/include/tos_binary_heap.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_BINARY_HEAP_H_
|
||||
#define _TOS_BINARY_HEAP_H_
|
||||
|
||||
typedef int (*k_bin_heap_cmp)(void *first, void *second);
|
||||
|
||||
typedef struct k_binary_heap_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
size_t total;
|
||||
|
||||
k_bin_heap_cmp cmp;
|
||||
size_t item_size;
|
||||
size_t item_cnt;
|
||||
uint8_t *pool;
|
||||
} k_bin_heap_t;
|
||||
|
||||
#define BIN_HEAP_FIRST_ITEM(bin_heap) (void *)(&bin_heap->pool[0])
|
||||
#define BIN_HEAP_LAST_ITEM(bin_heap) (void *)(&bin_heap->pool[bin_heap->total * bin_heap->item_size])
|
||||
#define BIN_HEAP_THE_ITEM(bin_heap, index) (void *)(&bin_heap->pool[index * bin_heap->item_size])
|
||||
|
||||
#define BIN_HEAP_PARENT(index) ((index - 1) / 2)
|
||||
#define BIN_HEAP_RCHILD(index) (2 * (index + 1))
|
||||
#define BIN_HEAP_LSIBLING(index) (index - 1)
|
||||
|
||||
/**
|
||||
* @brief Create a binary heap.
|
||||
* create a binary heap.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
* @param[in] pool pool buffer of the binary heap.
|
||||
* @param[in] item_cnt item count of the binary heap.
|
||||
* @param[in] item_size size of each item of the binary heap.
|
||||
* @param[in] cmp compare function to determine two items which is bigger or smaller.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_create(k_bin_heap_t *bin_heap, void *pool, size_t item_cnt, size_t item_size, k_bin_heap_cmp cmp);
|
||||
|
||||
/**
|
||||
* @brief Destroy a binary heap.
|
||||
* destroy a binary heap.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_destroy(k_bin_heap_t *bin_heap);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Create a binary heap with a dynamic allocated pool.
|
||||
* create a binary heap with a dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
* @param[in] item_cnt item count of the binary heap.
|
||||
* @param[in] item_size size of each item of the binary heap.
|
||||
* @param[in] cmp compare function to determine two items which is bigger or smaller.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_create_dyn(k_bin_heap_t *bin_heap, size_t item_cnt, size_t item_size, k_bin_heap_cmp cmp);
|
||||
|
||||
/**
|
||||
* @brief Destroy a binary heap with a dynamic allocated pool.
|
||||
* destroy a binary heap with a dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_destroy_dyn(k_bin_heap_t *bin_heap);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Push an item.
|
||||
* push an item into the binary heap.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
* @param[in] item the item to be pushed.
|
||||
* @param[in] item_size size of the item(should be consistent with the item_size passed to tos_bin_heap_create).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_BIN_HEAP_ITEM_SIZE_NOT_MATCH the item_size is not consistent with the item_size passed to tos_bin_heap_create.
|
||||
* @retval #K_ERR_BIN_HEAP_FULL the binary heap is full.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_push(k_bin_heap_t *bin_heap, void *item, size_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Pop an item.
|
||||
* pop an item from the binary heap.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
* @param[out] item buffer to hold the item poped.
|
||||
* @param[out] item_size size of the item poped(should be consistent with the item_size passed to tos_bin_heap_create).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_BIN_HEAP_EMPTY the ring queue is empty.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_pop(k_bin_heap_t *bin_heap, void *item, size_t *item_size);
|
||||
|
||||
/**
|
||||
* @brief Flush the binary heap.
|
||||
* flush the binary heap.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_bin_heap_flush(k_bin_heap_t *bin_heap);
|
||||
|
||||
/**
|
||||
* @brief Whether the binary heap is empty.
|
||||
* Whether the binary heap is empty.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
*
|
||||
* @return whether the binary heap is emtpy.
|
||||
* @retval #0 the binary heap is not empty.
|
||||
* @retval #Not 0 the binary heap is empty.
|
||||
*/
|
||||
__API__ int tos_bin_heap_is_empty(k_bin_heap_t *bin_heap);
|
||||
|
||||
/**
|
||||
* @brief Whether the binary heap is full.
|
||||
* Whether the binary heap is full.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] bin_heap pointer to the handler of the binary heap.
|
||||
*
|
||||
* @return whether the binary hea is full.
|
||||
* @retval #0 the binary hea is not full.
|
||||
* @retval #Not 0 the binary hea is full.
|
||||
*/
|
||||
__API__ int tos_bin_heap_is_full(k_bin_heap_t *bin_heap);
|
||||
|
||||
#endif /* _TOS_BINARY_HEAP_H_ */
|
||||
|
191
kernel/core/include/tos_char_fifo.h
Normal file
191
kernel/core/include/tos_char_fifo.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_CHAR_FIFO_H_
|
||||
#define _TOS_CHAR_FIFO_H_
|
||||
|
||||
typedef struct k_char_fifo_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
k_ring_q_t ring_q;
|
||||
} k_chr_fifo_t;
|
||||
|
||||
/**
|
||||
* @brief Create a character fifo.
|
||||
* Create a character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[in] buffer memory buffer provided to be as the inner buffer.
|
||||
* @param[in] size size of the memory buffer.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_OBJ_PTR_NULL fifo is a NULL pointer.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_create(k_chr_fifo_t *chr_fifo, void *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a character fifo.
|
||||
* Destroy a character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_OBJ_PTR_NULL fifo is a NULL pointer.
|
||||
* @retval #K_ERR_OBJ_INVALID not a valid pointer to a fifo.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_destroy(k_chr_fifo_t *chr_fifo);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Create a character fifo with a dynamic allocated buffer.
|
||||
* Create a character fifo with a dynamic allocated buffer.
|
||||
*
|
||||
* @attention the buffer is dynamic allocated(tos_mmheap_alloc)
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[in] fifo_size size of the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_OBJ_PTR_NULL fifo is a NULL pointer.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_create_dyn(k_chr_fifo_t *chr_fifo, size_t fifo_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a character fifo with a dynamic allocated buffer.
|
||||
* Destroy a character fifo with a dynamic allocated buffer.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_OBJ_PTR_NULL fifo is a NULL pointer.
|
||||
* @retval #K_ERR_OBJ_INVALID not a valid pointer to a fifo.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_destroy_dyn(k_chr_fifo_t *chr_fifo);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Push data into character fifo.
|
||||
* Push one single data into the character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
* @param[in] data data to push into the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_RING_Q_FULL the character fifo is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_push(k_chr_fifo_t *chr_fifo, uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Push stream into character fifo.
|
||||
* Push a stream data into the character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
* @param[IN] stream stream to be pushed into the character fifo.
|
||||
* @param[OUT] size size of the stream.
|
||||
*
|
||||
* @return the actual number of the data pushed into the character fifo.
|
||||
*/
|
||||
__API__ int tos_chr_fifo_push_stream(k_chr_fifo_t *chr_fifo, uint8_t *stream, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Pop data from character fifo.
|
||||
* Pop one single data from the character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
* @param[OUT] out one signle buffer to hold the data poped from the character fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_FIFO_EMPTY the character fifo is empty.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_pop(k_chr_fifo_t *chr_fifo, uint8_t *out);
|
||||
|
||||
/**
|
||||
* @brief Pop stream from character fifo.
|
||||
* Pop a stream data from the character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
* @param[OUT] buffer pointer to the buffer to receive the stream poped.
|
||||
* @param[OUT] size size of the buffer.
|
||||
*
|
||||
* @return the actual number of the data poped from the character fifo.
|
||||
*/
|
||||
__API__ int tos_chr_fifo_pop_stream(k_chr_fifo_t *chr_fifo, uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Flush character fifo.
|
||||
* Flush/reset the character fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
__API__ k_err_t tos_chr_fifo_flush(k_chr_fifo_t *chr_fifo);
|
||||
|
||||
/**
|
||||
* @brief Whether the character fifo is empty.
|
||||
* Whether the character fifo is empty.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
*
|
||||
* @return whether the character fifo is emtpy.
|
||||
* @retval #0 the character fifo is not empty.
|
||||
* @retval #Not 0 the character fifo is empty.
|
||||
*/
|
||||
__API__ int tos_chr_fifo_is_empty(k_chr_fifo_t *chr_fifo);
|
||||
|
||||
/**
|
||||
* @brief Whether the character fifo is full.
|
||||
* Whether the character fifo is full.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the character fifo.
|
||||
*
|
||||
* @return whether the character fifo is full.
|
||||
* @retval #0 the character fifo is not full.
|
||||
* @retval #Not 0 the character fifo is full.
|
||||
*/
|
||||
__API__ int tos_chr_fifo_is_full(k_chr_fifo_t *chr_fifo);
|
||||
|
||||
#endif // _TOS_CHAR_FIFO_H_
|
||||
|
@@ -23,6 +23,10 @@
|
||||
typedef uint16_t completion_done_t;
|
||||
|
||||
typedef struct k_completion_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
completion_done_t done;
|
||||
} k_completion_t;
|
||||
@@ -82,9 +86,7 @@ __API__ k_err_t tos_completion_pend_timed(k_completion_t *completion, k_tick_t t
|
||||
* @param[in] timeout how much time(in k_tick_t) we would like to wait.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait.
|
||||
* @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked.
|
||||
* @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing.
|
||||
* @retval #K_ERR_PEND_DESTROY the completion we are pending is destroyed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
|
@@ -40,8 +40,16 @@
|
||||
#error "INVALID config, TOS_CFG_TASK_PRIO_MAX must be >= 8"
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_QUEUE_EN > 0u) && (TOS_CFG_MSG_EN == 0u)
|
||||
#error "INVALID config, must enable tos_msg to use tos_queue"
|
||||
#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_PRIORITY_MESSAGE_QUEUE_EN > 0u) && (TOS_CFG_MMHEAP_EN == 0u)
|
||||
#error "INVALID config, must enable TOS_CFG_MMHEAP_EN to support tos_prio_msg_q"
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_PRIORITY_MAIL_QUEUE_EN > 0u) && (TOS_CFG_MMHEAP_EN == 0u)
|
||||
#error "INVALID config, must enable TOS_CFG_MMHEAP_EN to support tos_prio_mail_q"
|
||||
#endif
|
||||
|
||||
#if ((TOS_CFG_TIMER_EN > 0u) && !defined(TOS_CFG_TIMER_AS_PROC))
|
||||
@@ -55,7 +63,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
|
||||
@@ -51,15 +60,6 @@
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable queue
|
||||
#ifdef TOS_CFG_QUEUE_EN
|
||||
#undef TOS_CFG_QUEUE_EN
|
||||
#endif
|
||||
#define TOS_CFG_QUEUE_EN 0u
|
||||
/////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// disable semaphore
|
||||
#ifdef TOS_CFG_SEM_EN
|
||||
@@ -167,7 +167,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
|
||||
@@ -182,8 +186,20 @@
|
||||
#define TOS_CFG_MUTEX_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_QUEUE_EN
|
||||
#define TOS_CFG_QUEUE_EN 0u
|
||||
#ifndef TOS_CFG_MESSAGE_QUEUE_EN
|
||||
#define TOS_CFG_MESSAGE_QUEUE_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_MAIL_QUEUE_EN
|
||||
#define TOS_CFG_MAIL_QUEUE_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN
|
||||
#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_PRIORITY_MAIL_QUEUE_EN
|
||||
#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_SEM_EN
|
||||
@@ -198,12 +214,6 @@
|
||||
#define TOS_CFG_COMPLETION_EN 0u
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_QUEUE_EN > 0u) && !defined(TOS_CFG_MSG_EN)
|
||||
#define TOS_CFG_MSG_EN 1u
|
||||
#elif (TOS_CFG_QUEUE_EN == 0u) && !defined(TOS_CFG_MSG_EN)
|
||||
#define TOS_CFG_MSG_EN 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_TIMER_EN
|
||||
#define TOS_CFG_TIMER_EN 0u
|
||||
#endif
|
||||
@@ -212,10 +222,6 @@
|
||||
#define TOS_CFG_TIMER_AS_PROC 0u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_MSG_POOL_SIZE
|
||||
#define TOS_CFG_MSG_POOL_SIZE 100u
|
||||
#endif
|
||||
|
||||
#ifndef TOS_CFG_IDLE_TASK_STK_SIZE
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 128u
|
||||
#endif
|
||||
@@ -275,6 +281,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
|
||||
|
@@ -21,6 +21,10 @@
|
||||
#if TOS_CFG_COUNTDOWNLATCH_EN > 0u
|
||||
|
||||
typedef struct k_countdownlatch_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
k_countdownlatch_cnt_t count;
|
||||
} k_countdownlatch_t;
|
||||
|
@@ -21,6 +21,10 @@
|
||||
typedef enum k_err_en {
|
||||
K_ERR_NONE = 0u,
|
||||
|
||||
K_ERR_BIN_HEAP_FULL = 10u,
|
||||
K_ERR_BIN_HEAP_EMPTY,
|
||||
K_ERR_BIN_HEAP_ITEM_SIZE_NOT_MATCH,
|
||||
|
||||
K_ERR_COMPLETION_OVERFLOW = 25u,
|
||||
|
||||
K_ERR_COUNTDOWNLATCH_OVERFLOW = 50u,
|
||||
@@ -30,9 +34,6 @@ typedef enum k_err_en {
|
||||
|
||||
K_ERR_EVENT_PEND_OPT_INVALID = 200u,
|
||||
|
||||
K_ERR_FIFO_FULL = 300u,
|
||||
K_ERR_FIFO_EMPTY,
|
||||
|
||||
K_ERR_IN_IRQ = 400u,
|
||||
|
||||
K_ERR_KNL_NOT_RUNNING = 500u,
|
||||
@@ -51,26 +52,17 @@ typedef enum k_err_en {
|
||||
K_ERR_MMHEAP_POOL_ALREADY_EXIST,
|
||||
K_ERR_MMHEAP_POOL_NOT_EXIST,
|
||||
|
||||
K_ERR_MSG_QUEUE_FULL = 900u,
|
||||
K_ERR_MSG_QUEUE_EMPTY,
|
||||
K_ERR_MSG_QUEUE_MSG_NOT_EXIST,
|
||||
|
||||
K_ERR_MUTEX_NOT_OWNER = 1000u,
|
||||
K_ERR_MUTEX_NESTING,
|
||||
K_ERR_MUTEX_NESTING_OVERFLOW,
|
||||
|
||||
K_ERR_OBJ_PTR_NULL = 1100u,
|
||||
K_ERR_OBJ_INVALID,
|
||||
K_ERR_OBJ_INVALID_ALLOC_TYPE,
|
||||
|
||||
K_ERR_PM_DEVICE_ALREADY_REG = 1200u,
|
||||
K_ERR_PM_DEVICE_OVERFLOW = 1300u,
|
||||
K_ERR_PM_WKUP_SOURCE_NOT_INSTALL = 1400u,
|
||||
K_ERR_OUT_OF_MEMORY = 1150u,
|
||||
|
||||
K_ERR_QUEUE_EMPTY = 1500u,
|
||||
K_ERR_QUEUE_FULL,
|
||||
K_ERR_QUEUE_MSG_NOT_EXIST,
|
||||
|
||||
K_ERR_PEND_NOWAIT = 1600u,
|
||||
K_ERR_PEND_NOWAIT = 1200u,
|
||||
K_ERR_PEND_SCHED_LOCKED,
|
||||
K_ERR_PEND_IN_IRQ,
|
||||
K_ERR_PEND_ABNORMAL,
|
||||
@@ -78,6 +70,19 @@ typedef enum k_err_en {
|
||||
K_ERR_PEND_DESTROY,
|
||||
K_ERR_PEND_OWNER_DIE,
|
||||
|
||||
K_ERR_PM_DEVICE_ALREADY_REG = 1300u,
|
||||
K_ERR_PM_DEVICE_OVERFLOW,
|
||||
K_ERR_PM_WKUP_SOURCE_NOT_INSTALL,
|
||||
|
||||
K_ERR_PRIO_Q_EMPTY = 1400u,
|
||||
K_ERR_PRIO_Q_FULL,
|
||||
K_ERR_PRIO_Q_SLOT_NOT_TAKEN,
|
||||
K_ERR_PRIO_Q_ITEM_SIZE_NOT_MATCH,
|
||||
|
||||
K_ERR_RING_Q_FULL = 1600u,
|
||||
K_ERR_RING_Q_EMPTY,
|
||||
K_ERR_RING_Q_ITEM_SIZE_NOT_MATCH,
|
||||
|
||||
K_ERR_SCHED_LOCKED = 1700u,
|
||||
K_ERR_SCHED_NOT_LOCKED,
|
||||
|
||||
@@ -91,6 +96,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,
|
||||
|
@@ -20,10 +20,10 @@
|
||||
|
||||
#if TOS_CFG_EVENT_EN > 0
|
||||
|
||||
// if we are pending an event, for any flag we expect is set is ok, this flag should be passed to tos_event_pend
|
||||
// if we are pending an event, for any flag we expect is set is ok, this flag should be passed to tos_event_pend
|
||||
#define TOS_OPT_EVENT_PEND_ANY (k_opt_t)0x0001
|
||||
|
||||
// if we are pending an event, must all the flag we expect is set is ok, this flag should be passed to tos_event_pend
|
||||
// if we are pending an event, must all the flag we expect is set is ok, this flag should be passed to tos_event_pend
|
||||
#define TOS_OPT_EVENT_PEND_ALL (k_opt_t)0x0002
|
||||
|
||||
// if we are pending an event, and we wanna clear the event's flag after we read, this flag should be passed to tos_event_pend
|
||||
@@ -41,6 +41,10 @@ typedef enum opt_event_post_en {
|
||||
} opt_event_post_t;
|
||||
|
||||
typedef struct k_event_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
k_event_flag_t flag;
|
||||
} k_event_t;
|
||||
@@ -128,6 +132,6 @@ __API__ k_err_t tos_event_post(k_event_t *event, k_event_flag_t flag);
|
||||
__API__ k_err_t tos_event_post_keep(k_event_t *event, k_event_flag_t flag);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* _TOS_EVENT_H_ */
|
||||
|
||||
|
@@ -1,163 +0,0 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_FIFO_H_
|
||||
#define _TOS_FIFO_H_
|
||||
|
||||
typedef struct k_fifo_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
int beg;
|
||||
int end;
|
||||
size_t cnt;
|
||||
uint8_t *buf;
|
||||
size_t siz;
|
||||
} k_fifo_t;
|
||||
|
||||
/**
|
||||
* @brief Create a fifo.
|
||||
* Create a fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[in] buffer memory buffer provided to be as the inner buffer.
|
||||
* @param[in] size size of the memory buffer.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_OBJ_PTR_NULL fifo is a NULL pointer.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_fifo_create(k_fifo_t *fifo, uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a fifo.
|
||||
* Destroy a fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_OBJ_PTR_NULL fifo is a NULL pointer.
|
||||
* @retval #K_ERR_OBJ_INVALID not a valid pointer to a fifo.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_fifo_destroy(k_fifo_t *fifo);
|
||||
|
||||
/**
|
||||
* @brief Push data into fifo.
|
||||
* Push one single data into the fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[in] data data to push into the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_FIFO_FULL the fifo is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_fifo_push(k_fifo_t *fifo, uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Push stream into fifo.
|
||||
* Push a stream data into the fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[IN] stream stream to be pushed into the fifo.
|
||||
* @param[OUT] size size of the stream.
|
||||
*
|
||||
* @return the actual number of the data pushed into the fifo.
|
||||
*/
|
||||
__API__ int tos_fifo_push_stream(k_fifo_t *fifo, uint8_t *stream, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Pop data from fifo.
|
||||
* Pop one single data from the fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[OUT] out one signle buffer to hold the data poped from the fifo.
|
||||
*
|
||||
* @return errno
|
||||
* @retval #K_ERR_FIFO_EMPTY the fifo is empty.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_fifo_pop(k_fifo_t *fifo, uint8_t *out);
|
||||
|
||||
/**
|
||||
* @brief Pop stream from fifo.
|
||||
* Pop a stream data from the fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
* @param[OUT] buffer pointer to the buffer to receive the stream poped.
|
||||
* @param[OUT] size size of the buffer.
|
||||
*
|
||||
* @return the actual number of the data poped from the fifo.
|
||||
*/
|
||||
__API__ int tos_fifo_pop_stream(k_fifo_t *fifo, uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Flush fifo.
|
||||
* Flush/reset the fifo.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
__API__ void tos_fifo_flush(k_fifo_t *fifo);
|
||||
|
||||
/**
|
||||
* @brief Whether the fifo is empty.
|
||||
* Whether the fifo is empty.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
*
|
||||
* @return whether the fifo is emtpy.
|
||||
* @retval #0 the fifo is not empty.
|
||||
* @retval #Not 0 the fifo is empty.
|
||||
*/
|
||||
__API__ int tos_fifo_is_empty(k_fifo_t *fifo);
|
||||
|
||||
/**
|
||||
* @brief Whether the fifo is full.
|
||||
* Whether the fifo is full.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] fifo pointer to the handler of the fifo.
|
||||
*
|
||||
* @return whether the fifo is full.
|
||||
* @retval #0 the fifo is not full.
|
||||
* @retval #Not 0 the fifo is full.
|
||||
*/
|
||||
__API__ int tos_fifo_is_full(k_fifo_t *fifo);
|
||||
|
||||
#endif // _TOS_FIFO_H_
|
||||
|
@@ -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 */
|
||||
@@ -82,11 +90,6 @@ extern size_t const k_timer_task_stk_size;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_MSG_EN > 0u)
|
||||
extern k_list_t k_msg_freelist;
|
||||
extern k_msg_t k_msg_pool[];
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
extern pm_device_ctl_t k_pm_device_ctl;
|
||||
|
||||
|
@@ -21,7 +21,6 @@
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TOS_OFFSET_OF_FIELD(type, field) \
|
||||
@@ -37,6 +36,13 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define TOS_PTR_SANITY_CHECK_RC(ptr, return_code) \
|
||||
do { \
|
||||
if (unlikely((ptr) == K_NULL)) { \
|
||||
return return_code; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define TOS_IN_IRQ_CHECK() \
|
||||
do { \
|
||||
if (unlikely(knl_is_inirq())) { \
|
||||
@@ -44,6 +50,26 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
#define TOS_OBJ_VERIFY(obj, obj_type) \
|
||||
do { \
|
||||
if (!knl_object_verify(&obj->knl_obj, obj_type)) { \
|
||||
return K_ERR_OBJ_INVALID; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TOS_OBJ_VERIFY_RC(obj, obj_type, return_code) \
|
||||
do { \
|
||||
if (!knl_object_verify(&obj->knl_obj, obj_type)) { \
|
||||
return return_code; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define TOS_OBJ_VERIFY(obj, obj_type)
|
||||
#define TOS_OBJ_VERIFY_RC(obj, obj_type, return_code)
|
||||
#endif
|
||||
|
||||
// currently we use default microlib supplied by mdk
|
||||
#define tos_kprintf(...) printf(__VA_ARGS__);
|
||||
|
||||
@@ -51,5 +77,17 @@
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n");
|
||||
|
||||
#define TOS_ASSERT_AUX(exp, function, line) \
|
||||
if (!(exp)) { \
|
||||
tos_kprintln("assert failed: %s %d\n", function, line); \
|
||||
tos_knl_sched_lock(); \
|
||||
tos_cpu_int_disable(); \
|
||||
while (K_TRUE) { \
|
||||
; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define TOS_ASSERT(exp) TOS_ASSERT_AUX(exp, __FUNCTION__, __LINE__)
|
||||
|
||||
#endif /* _TOS_KLIB_H_ */
|
||||
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#define _TOS_KTYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
typedef uint8_t k_prio_t;
|
||||
typedef uint8_t k_stack_t;
|
||||
|
159
kernel/core/include/tos_mail_queue.h
Normal file
159
kernel/core/include/tos_mail_queue.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_MAIL_QUEUE_H_
|
||||
#define _TOS_MAIL_QUEUE_H_
|
||||
|
||||
#if TOS_CFG_MAIL_QUEUE_EN > 0u
|
||||
|
||||
typedef struct k_mail_queue_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
k_ring_q_t ring_q;
|
||||
} k_mail_q_t;
|
||||
|
||||
/**
|
||||
* @brief Create a mail queue.
|
||||
* create a mail queue.
|
||||
*
|
||||
* @attention a MAIL is a buffer with a certain size.
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
* @param[in] pool pool buffer of the mail queue.
|
||||
* @param[in] mail_cnt mail count of the mail queue.
|
||||
* @param[in] mail_size size of each mail in the mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_create(k_mail_q_t *mail_q, void *pool, size_t mail_cnt, size_t mail_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a mail queue.
|
||||
* destroy a mail queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Create a mail queue with dynamic allocated pool.
|
||||
* create a mail queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention a MAIL is a buffer with a certain size.
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
* @param[in] mail_cnt mail count of the mail queue.
|
||||
* @param[in] mail_size size of each mail in the mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_create_dyn(k_mail_q_t *mail_q, size_t mail_cnt, size_t mail_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a mail queue with dynamic allocated pool.
|
||||
* destroy a mail queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_destroy_dyn(k_mail_q_t *mail_q);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Flush the mail queue.
|
||||
* flush the mail queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_flush(k_mail_q_t *mail_q);
|
||||
|
||||
/**
|
||||
* @brief Pend a mail queue.
|
||||
* pend a mail queue.
|
||||
*
|
||||
* @attention we WILL perform a memcpy when mail_buf is received(a MAIL is a buffer with a certain size).
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
* @param[OUT] mail_buf a pointer to the mail buffer we wanna receive.
|
||||
* @param[OUT] mail_size size of the mail buffer received(should be consistent with the mail_size passed to tos_mail_q_create).
|
||||
* @param[in] timeout how much time(in k_tick_t) we would like to wait.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait.
|
||||
* @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked.
|
||||
* @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing.
|
||||
* @retval #K_ERR_PEND_DESTROY the queue we are pending is destroyed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_pend(k_mail_q_t *mail_q, void *mail_buf, size_t *mail_size, k_tick_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Post a mail queue.
|
||||
* post a mail queue and wakeup one pending task.
|
||||
*
|
||||
* @attention when tos_mail_q_post return successfully, only one task who are waitting for the mail queue will be woken up.
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
* @param[in] mail_buf the mail to post(a MAIL is a buffer).
|
||||
* @param[in] mail_size the size of the mail to post(a MAIL is just a buffer).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_RING_Q_FULL the mail queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_post(k_mail_q_t *mail_q, void *mail_buf, size_t mail_size);
|
||||
|
||||
/**
|
||||
* @brief Post a mail queue.
|
||||
* post a mail queue and wakeup all the pending task.
|
||||
*
|
||||
* @attention when tos_mail_q_post_all return successfully, all of the tasks who are waitting for the message queue will be woken up.
|
||||
*
|
||||
* @param[in] mail_q pointer to the handler of the mail queue.
|
||||
* @param[in] mail_buf the mail to post(a MAIL is a buffer).
|
||||
* @param[in] mail_size the size of the mail to post(a MAIL is just a buffer).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_RING_Q_FULL the mail queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_mail_q_post_all(k_mail_q_t *mail_q, void *mail_buf, size_t mail_size);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_MAIL_QUEUE_H_ */
|
||||
|
154
kernel/core/include/tos_message_queue.h
Normal file
154
kernel/core/include/tos_message_queue.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_MESSAGE_QUEUE_H_
|
||||
#define _TOS_MESSAGE_QUEUE_H_
|
||||
|
||||
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
|
||||
|
||||
typedef struct k_message_queue_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
k_ring_q_t ring_q;
|
||||
} k_msg_q_t;
|
||||
|
||||
/**
|
||||
* @brief Create a message queue.
|
||||
* create a message queue.
|
||||
*
|
||||
* @attention a MESSAGE is a "void *" pointer.
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
* @param[in] pool pool buffer of the message queue.
|
||||
* @param[in] msg_cnt message count of the message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_create(k_msg_q_t *msg_q, void *pool, size_t msg_cnt);
|
||||
|
||||
/**
|
||||
* @brief Destroy a message queue.
|
||||
* destroy a message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Create a message queue with dynamic allocated pool.
|
||||
* create a message queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention a MESSAGE is a "void *" pointer.
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
* @param[in] msg_cnt message count of the message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_create_dyn(k_msg_q_t *msg_q, size_t msg_cnt);
|
||||
|
||||
/**
|
||||
* @brief Destroy a message queue with dynamic allocated pool.
|
||||
* destroy a message queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_destroy_dyn(k_msg_q_t *msg_q);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Flush the message queue.
|
||||
* flush the message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_flush(k_msg_q_t *msg_q);
|
||||
|
||||
/**
|
||||
* @brief Pend a message queue.
|
||||
* pend a message queue.
|
||||
*
|
||||
* @attention we DONNOT perform a memcpy when msg_ptr is received(a MESSAGE is just a pointer).
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
* @param[OUT] msg_ptr a pointer to the message we wanna receive.
|
||||
* @param[in] timeout how much time(in k_tick_t) we would like to wait.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait.
|
||||
* @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked.
|
||||
* @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing.
|
||||
* @retval #K_ERR_PEND_DESTROY the queue we are pending is destroyed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_pend(k_msg_q_t *msg_q, void **msg_ptr, k_tick_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Post a message queue.
|
||||
* post a message queue and wakeup one pending task.
|
||||
*
|
||||
* @attention when tos_msg_q_post return successfully, only one task who are waitting for the message queue will be woken up.
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
* @param[in] msg_ptr the message to post(a MESSAGE is just a pointer).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_RING_Q_FULL the message queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_post(k_msg_q_t *msg_q, void *msg_ptr);
|
||||
|
||||
/**
|
||||
* @brief Post a message queue.
|
||||
* post a message queue and wakeup all the pending task.
|
||||
*
|
||||
* @attention when tos_msg_q_post_all return successfully, all of the tasks who are waitting for the message queue will be woken up.
|
||||
*
|
||||
* @param[in] msg_q pointer to the handler of the message queue.
|
||||
* @param[in] msg_ptr the message to post(a MESSAGE is just a pointer).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_RING_Q_FULL the message queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_q_post_all(k_msg_q_t *msg_q, void *msg_ptr);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_MESSAGE_QUEUE_H_ */
|
||||
|
@@ -1,129 +0,0 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_MSG_H_
|
||||
#define _TOS_MSG_H_
|
||||
|
||||
#define TOS_OPT_MSG_PUT_LIFO (k_opt_t)0x0001
|
||||
#define TOS_OPT_MSG_PUT_FIFO (k_opt_t)0x0002
|
||||
|
||||
typedef struct k_message_st {
|
||||
k_list_t list;
|
||||
void *msg_addr;
|
||||
size_t msg_size;
|
||||
} k_msg_t;
|
||||
|
||||
typedef struct k_msg_queue_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
k_list_t queue_head;
|
||||
} k_msg_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Create a message queue.
|
||||
* Initialize a message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[IN] msg_queue the pointer to the handler of the message queue.
|
||||
*
|
||||
* @return errcode.
|
||||
* @retval #K_ERR_OBJ_PTR_NULL msg_queue is a null pointer
|
||||
* @retval #K_ERR_NONE return successfully
|
||||
*/
|
||||
__API__ k_err_t tos_msg_queue_create(k_msg_queue_t *msg_queue);
|
||||
|
||||
/**
|
||||
* @brief Destroy a message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[IN] msg_queue the pointer to the handler of the message queue.
|
||||
*
|
||||
* @return errcode.
|
||||
* @retval #K_ERR_OBJ_PTR_NULL msg_queue is a null pointer
|
||||
* @retval #K_ERR_OBJ_INVALID msg_queue is not a valid pointer to a message queue
|
||||
* @retval #K_ERR_NONE return successfully
|
||||
*/
|
||||
__API__ k_err_t tos_msg_queue_destroy(k_msg_queue_t *msg_queue);
|
||||
|
||||
/**
|
||||
* @brief Get a message.
|
||||
* Get a message from the queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[IN] msg_queue the pointer to the handler of the message queue.
|
||||
* @param[OUT] msg_body the pointer to the body of the message.
|
||||
* @param[OUT] msg_size the pointer to the size of the message.
|
||||
*
|
||||
* @return errcode.
|
||||
* @retval #K_ERR_QUEUE_EMPTY the queue is empty.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_queue_get(k_msg_queue_t *msg_queue, void **msg_addr, size_t *msg_size);
|
||||
|
||||
/**
|
||||
* @brief Put a message.
|
||||
* Put a message to the queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[IN] msg_queue the pointer to the handler of the message queue.
|
||||
* @param[IN] msg_body the pointer to the body of the message.
|
||||
* @param[IN] msg_size the pointer to the size of the message.
|
||||
* @param[IN] opt option for the function call.
|
||||
*
|
||||
* @return errcode.
|
||||
* @retval #K_ERR_QUEUE_FULL the queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_msg_queue_put(k_msg_queue_t *msg_queue, void *msg_addr, size_t msg_size, k_opt_t opt);
|
||||
|
||||
/**
|
||||
* @brief Remove one message from the message queue.
|
||||
* Remove one message with certain address from the message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[IN] msg_queue the pointer to the handler of the message queue.
|
||||
* @param[IN] msg_addr the address of the message.
|
||||
*
|
||||
* @return errcode.
|
||||
* @retval #K_ERR_MSG_QUEUE_MSG_NOT_EXIST message to remove is not existed
|
||||
* @retval #K_ERR_NONE return successfully
|
||||
*/
|
||||
__API__ k_err_t tos_msg_queue_remove(k_msg_queue_t *msg_queue, void *msg_addr);
|
||||
|
||||
/**
|
||||
* @brief Flush all of the messages.
|
||||
* Flush all of the messages in the queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[IN] msg_queue the pointer to the handler of the message queue.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
__API__ void tos_msg_queue_flush(k_msg_queue_t *msg_queue);
|
||||
|
||||
__KERNEL__ void msgpool_init(void);
|
||||
|
||||
#endif /* _TOS_MSG_H_ */
|
||||
|
@@ -21,6 +21,10 @@
|
||||
#if TOS_CFG_MUTEX_EN > 0u
|
||||
|
||||
typedef struct k_mutex_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
k_nesting_t pend_nesting;
|
||||
k_task_t *owner;
|
||||
|
@@ -32,36 +32,19 @@ typedef enum pend_state_en {
|
||||
PEND_STATE_OWNER_DIE, /**< the pend object owner task is destroyed. */
|
||||
} pend_state_t;
|
||||
|
||||
// what we are pending
|
||||
/* actually, it's some kind of magic number, mainly for identifing whether the pend
|
||||
is initialized, or whether user pass the correct parameter.
|
||||
*/
|
||||
typedef enum pend_type_en {
|
||||
PEND_TYPE_NONE = 0x0000,
|
||||
PEND_TYPE_SEM = 0x1BEE,
|
||||
PEND_TYPE_MUTEX = 0x2BEE,
|
||||
PEND_TYPE_EVENT = 0x3BEE,
|
||||
PEND_TYPE_QUEUE = 0x4BEE,
|
||||
PEND_TYPE_COUNTDOWNLATCH = 0x5BEE,
|
||||
PEND_TYPE_COMPLETION = 0x6BEE,
|
||||
} pend_type_t;
|
||||
|
||||
typedef enum opt_post_en {
|
||||
OPT_POST_ONE,
|
||||
OPT_POST_ALL,
|
||||
} opt_post_t;
|
||||
|
||||
typedef struct pend_object_st {
|
||||
pend_type_t type;
|
||||
k_list_t list;
|
||||
} pend_obj_t;
|
||||
|
||||
__KERNEL__ void pend_object_init(pend_obj_t *object, pend_type_t type);
|
||||
__KERNEL__ void pend_object_init(pend_obj_t *object);
|
||||
|
||||
__KERNEL__ void pend_object_deinit(pend_obj_t *object);
|
||||
|
||||
__KERNEL__ int pend_object_verify(pend_obj_t *object, pend_type_t type);
|
||||
|
||||
__KERNEL__ int pend_is_nopending(pend_obj_t *object);
|
||||
|
||||
__KERNEL__ k_prio_t pend_highest_pending_prio_get(pend_obj_t *object);
|
||||
|
164
kernel/core/include/tos_priority_mail_queue.h
Normal file
164
kernel/core/include/tos_priority_mail_queue.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_PRIORITY_MAIL_QUEUE_H_
|
||||
#define _TOS_PRIORITY_MAIL_QUEUE_H_
|
||||
|
||||
#if TOS_CFG_PRIORITY_MAIL_QUEUE_EN > 0u
|
||||
|
||||
typedef struct k_priority_mail_queue_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
|
||||
void *prio_q_mgr_array;
|
||||
k_prio_q_t prio_q;
|
||||
} k_prio_mail_q_t;
|
||||
|
||||
/**
|
||||
* @brief Create a priority mail queue.
|
||||
* create a priority mail queue.
|
||||
*
|
||||
* @attention a MAIL is a buffer with a certain size.
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
* @param[in] pool pool buffer of the priority mail queue.
|
||||
* @param[in] mail_cnt mail count of the priority mail queue.
|
||||
* @param[in] mail_size size of each mail in the priority mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_create(k_prio_mail_q_t *prio_mail_q, void *pool, size_t mail_cnt, size_t mail_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a priority mail queue.
|
||||
* destroy a priority mail queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_destroy(k_prio_mail_q_t *prio_mail_q);
|
||||
|
||||
/**
|
||||
* @brief Create a priority mail queue with dynamic allocated pool.
|
||||
* create a priority mail queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention a MAIL is a buffer with a certain size.
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
* @param[in] pool pool buffer of the priority mail queue.
|
||||
* @param[in] mail_cnt mail count of the priority mail queue.
|
||||
* @param[in] mail_size size of each mail in the priority mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_create_dyn(k_prio_mail_q_t *prio_mail_q, size_t mail_cnt, size_t mail_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a priority mail queue with dynamic allocated pool.
|
||||
* destroy a priority mail queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_destroy_dyn(k_prio_mail_q_t *prio_mail_q);
|
||||
|
||||
/**
|
||||
* @brief Flush the priority mail queue.
|
||||
* flush the priority mail queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_flush(k_prio_mail_q_t *prio_mail_q);
|
||||
|
||||
/**
|
||||
* @brief Pend a priority mail queue.
|
||||
* pend a priority mail queue.
|
||||
*
|
||||
* @attention
|
||||
* 1. we WILL perform a memcpy when mail_buf is received(a MAIL is a buffer with a certain size).
|
||||
* 2. With priority mail queue, if the poster has post several mail with different priority, the pender will receive
|
||||
* the mail in priority order(numerically bigger, actually smaller, means the mail with highest priority(numerically
|
||||
* smallest) will be received first, then the second highest priority mail, and so on).
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
* @param[OUT] mail_buf a pointer to the mail buffer we wanna receive.
|
||||
* @param[OUT] mail_size size of the mail buffer received(should be consistent with the mail_size passed to tos_prio_mail_q_create).
|
||||
* @param[in] timeout how much time(in k_tick_t) we would like to wait.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait.
|
||||
* @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked.
|
||||
* @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing.
|
||||
* @retval #K_ERR_PEND_DESTROY the queue we are pending is destroyed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_pend(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t *mail_size, k_tick_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Post a priority mail queue.
|
||||
* post a priority mail queue and wakeup one pending task.
|
||||
*
|
||||
* @attention when tos_prio_mail_q_post return successfully, only one task who are waitting for the mail queue will be woken up.
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
* @param[in] mail_buf the mail to post(a MAIL is a buffer).
|
||||
* @param[in] mail_size the size of the mail to post(a MAIL is just a buffer).
|
||||
* @param[in] prio the priority of the mail.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PRIO_Q_FULL the mail queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_post(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t mail_size, k_prio_t prio);
|
||||
|
||||
/**
|
||||
* @brief Post a priority mail queue.
|
||||
* post a priority mail queue and wakeup all the pending task.
|
||||
*
|
||||
* @attention when tos_prio_mail_q_post_all return successfully, all of the tasks who are waitting for the message queue will be woken up.
|
||||
*
|
||||
* @param[in] prio_mail_q pointer to the handler of the priority mail queue.
|
||||
* @param[in] mail_buf the mail to post(a MAIL is a buffer).
|
||||
* @param[in] mail_size the size of the mail to post(a MAIL is just a buffer).
|
||||
* @param[in] prio the priority of the mail.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PRIO_Q_FULL the mail queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_mail_q_post_all(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t mail_size, k_prio_t prio);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* TOS_CFG_PRIORITY_MAIL_QUEUE_EN */
|
||||
|
159
kernel/core/include/tos_priority_message_queue.h
Normal file
159
kernel/core/include/tos_priority_message_queue.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_PRIORITY_MESSAGE_QUEUE_H_
|
||||
#define _TOS_PRIORITY_MESSAGE_QUEUE_H_
|
||||
|
||||
#if TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN > 0u
|
||||
|
||||
typedef struct k_priority_message_queue_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
pend_obj_t pend_obj;
|
||||
|
||||
void *prio_q_mgr_array;
|
||||
k_prio_q_t prio_q;
|
||||
} k_prio_msg_q_t;
|
||||
|
||||
/**
|
||||
* @brief Create a priority message queue.
|
||||
* create a priority message queue.
|
||||
*
|
||||
* @attention a MESSAGE is a "void *" pointer.
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
* @param[in] pool pool buffer of the priority message queue.
|
||||
* @param[in] msg_cnt message count of the priority message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_create(k_prio_msg_q_t *prio_msg_q, void *pool, size_t msg_cnt);
|
||||
|
||||
/**
|
||||
* @brief Destroy a priority message queue.
|
||||
* destroy a priority message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_destroy(k_prio_msg_q_t *prio_msg_q);
|
||||
|
||||
/**
|
||||
* @brief Create a priority message queue with dynamic allocated pool.
|
||||
* create a priority message queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention a MESSAGE is a "void *" pointer.
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
* @param[in] pool pool buffer of the priority message queue.
|
||||
* @param[in] msg_cnt message count of the priority message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_create_dyn(k_prio_msg_q_t *prio_msg_q, size_t msg_cnt);
|
||||
|
||||
/**
|
||||
* @brief Destroy a priority message queue with dynamic allocated pool.
|
||||
* destroy a priority message queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_destroy_dyn(k_prio_msg_q_t *prio_msg_q);
|
||||
|
||||
/**
|
||||
* @brief Flush the priority message queue.
|
||||
* flush the priority message queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_flush(k_prio_msg_q_t *prio_msg_q);
|
||||
|
||||
/**
|
||||
* @brief Pend a priority message queue.
|
||||
* pend a priority message queue.
|
||||
*
|
||||
* @attentio
|
||||
* 1. we DONNOT perform a memcpy when msg_ptr is received(a MESSAGE is just a pointer).
|
||||
* 2. With priority message queue, if the poster has post several message with different priority, the pender will receive
|
||||
* the message in priority order(numerically bigger, actually smaller, means the message with highest priority(numerically
|
||||
* smallest) will be received first, then the second highest priority message, and so on).
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
* @param[OUT] msg_ptr a pointer to the message we wanna receive.
|
||||
* @param[in] timeout how much time(in k_tick_t) we would like to wait.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait.
|
||||
* @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked.
|
||||
* @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing.
|
||||
* @retval #K_ERR_PEND_DESTROY the queue we are pending is destroyed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_pend(k_prio_msg_q_t *prio_msg_q, void **msg_ptr, k_tick_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Post a priority message queue.
|
||||
* post a priority message queue and wakeup one pending task.
|
||||
*
|
||||
* @attention when tos_prio_msg_q_post return successfully, only one task who are waitting for the priority message queue will be woken up.
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
* @param[in] msg_ptr the message to post(a MESSAGE is just a pointer).
|
||||
* @param[in] prio the priority of the message.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PRIO_Q_FULL the priority message queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_post(k_prio_msg_q_t *prio_msg_q, void *msg_ptr, k_prio_t prio);
|
||||
|
||||
/**
|
||||
* @brief Post a priority message queue.
|
||||
* post a priority message queue and wakeup all the pending task.
|
||||
*
|
||||
* @attention when tos_prio_msg_q_post_all return successfully, all of the tasks who are waitting for the priority message queue will be woken up.
|
||||
*
|
||||
* @param[in] prio_msg_q pointer to the handler of the priority message queue.
|
||||
* @param[in] msg_ptr the priority message to post(a MESSAGE is just a pointer).
|
||||
* @param[in] prio the priority of the message.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PRIO_Q_FULL the priority message queue is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_msg_q_post_all(k_prio_msg_q_t *prio_msg_q, void *msg_ptr, k_prio_t prio);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_PRIORITY_MESSAGE_QUEUE_H_ */
|
||||
|
211
kernel/core/include/tos_priority_queue.h
Normal file
211
kernel/core/include/tos_priority_queue.h
Normal file
@@ -0,0 +1,211 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_PRIORITY_QUEUE_H_
|
||||
#define _TOS_PRIORITY_QUEUE_H_
|
||||
|
||||
typedef uint16_t prio_q_slot_t;
|
||||
|
||||
typedef struct prio_q_pool_manager_entry_st {
|
||||
prio_q_slot_t next;
|
||||
} prio_q_pool_mgr_ent_t;
|
||||
|
||||
typedef struct prio_q_pool_manager_st {
|
||||
prio_q_slot_t first_free;
|
||||
prio_q_pool_mgr_ent_t *pool_mgr_ent_array;
|
||||
} prio_q_pool_mgr_t;
|
||||
|
||||
typedef struct prio_q_priority_manager_entry_st {
|
||||
k_prio_t priority;
|
||||
prio_q_slot_t slot;
|
||||
} prio_q_prio_mgr_ent_t;
|
||||
|
||||
typedef struct prio_q_prio_manager_st {
|
||||
k_bin_heap_t prio_mgr_bin_heap;
|
||||
prio_q_prio_mgr_ent_t *prio_mgr_ent_pool;
|
||||
} prio_q_prio_mgr_t;
|
||||
|
||||
typedef struct k_priority_queue_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
prio_q_pool_mgr_t pool_mgr;
|
||||
prio_q_prio_mgr_t prio_mgr;
|
||||
|
||||
size_t total;
|
||||
size_t item_size;
|
||||
size_t item_cnt;
|
||||
|
||||
uint8_t *mgr_pool;
|
||||
uint8_t *data_pool;
|
||||
} k_prio_q_t;
|
||||
|
||||
#define PRIO_Q_POOL_SLOT_INVALID ((prio_q_slot_t)-1)
|
||||
|
||||
#define PRIO_Q_POOL_MGR_ENT_ARRAY_SIZE(item_cnt) \
|
||||
(item_cnt * sizeof(prio_q_pool_mgr_ent_t))
|
||||
|
||||
#define PRIO_Q_PRIO_MGR_ENT_POOL_SIZE(item_cnt) \
|
||||
(item_cnt * sizeof(prio_q_prio_mgr_ent_t))
|
||||
|
||||
#define PRIO_Q_THE_ITEM(prio_q, slot) (void *)(&prio_q->data_pool[slot * prio_q->item_size])
|
||||
|
||||
// get the size of mgr_array to create a priority queue
|
||||
#define TOS_PRIO_Q_MGR_ARRAY_SIZE(item_cnt) \
|
||||
(PRIO_Q_POOL_MGR_ENT_ARRAY_SIZE(item_cnt) + PRIO_Q_PRIO_MGR_ENT_POOL_SIZE(item_cnt))
|
||||
|
||||
/**
|
||||
* @brief Create a priority queue.
|
||||
* create a priority queue.
|
||||
*
|
||||
* @attention if we wanna create a priority queue, we should offer a manager array buffer of which the size can be calculated by TOS_PRIO_Q_MGR_ARRAY_SIZE.
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the priority queue.
|
||||
* @param[in] mgr_array manager array buffer of the priority queue.
|
||||
* @param[in] pool pool buffer of the priority queue.
|
||||
* @param[in] item_cnt item count of the priority queue.
|
||||
* @param[in] item_size size of each item of the priority queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_create(k_prio_q_t *prio_q, void *mgr_array, void *pool, size_t item_cnt, size_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a priority queue.
|
||||
* destroy a priority queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the bpriority queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_destroy(k_prio_q_t *prio_q);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Create a priority queue with dynamic allocated mgr array and data pool.
|
||||
* create a priority queue with dynamic allocated mgr array and data pool.
|
||||
*
|
||||
* @attention if we wanna create a priority queue, we should offer a manager array buffer of which the size can be calculated by TOS_PRIO_Q_MGR_ARRAY_SIZE.
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the priority queue.
|
||||
* @param[in] mgr_array manager array buffer of the priority queue.
|
||||
* @param[in] pool pool buffer of the priority queue.
|
||||
* @param[in] item_cnt item count of the priority queue.
|
||||
* @param[in] item_size size of each item of the priority queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_create_dyn(k_prio_q_t *prio_q, size_t item_cnt, size_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a priority queue with dynamic allocated mgr array and data pool.
|
||||
* destroy a priority queue with dynamic allocated mgr array and data pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the bpriority queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_destroy_dyn(k_prio_q_t *prio_q);
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enqueue an priority queue.
|
||||
* enqueue an item into the priority queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of priority queue.
|
||||
* @param[in] item the item to be enqueued.
|
||||
* @param[in] item_size size of the item(should be consistent with the item_size passed to tos_prio_q_create).
|
||||
* @param[in] prio priority of the item to be enqueued(should be consistent with the item_size passed to tos_prio_q_create).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_PRIO_Q_ITEM_SIZE_NOT_MATCH the item_size is not consistent with the item_size passed to tos_prio_q_create.
|
||||
* @retval #K_ERR_PRIO_Q_FULL the priority queue is full.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_enqueue(k_prio_q_t *prio_q, void *item, size_t item_size, k_prio_t prio);
|
||||
|
||||
/**
|
||||
* @brief Dequeue an item.
|
||||
* dequeue an item from the priority queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the priority queue.
|
||||
* @param[out] item buffer to hold the item dequeued.
|
||||
* @param[out] item_size size of the item dequeued(should be consistent with the item_size passed to tos_prio_q_create).
|
||||
* @param[out] prio priority of the item dequeued.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_PRIO_Q_EMPTY the priority queue is empty.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_dequeue(k_prio_q_t *prio_q, void *item, size_t *item_size, k_prio_t *prio);
|
||||
|
||||
/**
|
||||
* @brief Flush the priority queue.
|
||||
* flush the priority queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the priority queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_prio_q_flush(k_prio_q_t *prio_q);
|
||||
|
||||
/**
|
||||
* @brief Whether the priority queue is empty.
|
||||
* Whether the priority queue is empty.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the priority queue.
|
||||
*
|
||||
* @return whether the priority queue is emtpy.
|
||||
* @retval #0 the priority queue is not empty.
|
||||
* @retval #Not 0 the priority queue is empty.
|
||||
*/
|
||||
__API__ int tos_prio_q_is_empty(k_prio_q_t *prio_q);
|
||||
|
||||
/**
|
||||
* @brief Whether the priority queue is full.
|
||||
* Whether the priority queue is full.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] prio_q pointer to the handler of the priority queue.
|
||||
*
|
||||
* @return whether the priority queue is full.
|
||||
* @retval #0 the priority queue is not full.
|
||||
* @retval #Not 0 the priority queue is full.
|
||||
*/
|
||||
__API__ int tos_prio_q_is_full(k_prio_q_t *prio_q);
|
||||
|
||||
#endif /* _TOS_PRIORITY_QUEUE_H_ */
|
||||
|
@@ -1,134 +0,0 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_QUEUE_H_
|
||||
#define _TOS_QUEUE_H_
|
||||
|
||||
#if TOS_CFG_QUEUE_EN > 0u
|
||||
|
||||
typedef struct k_queue_st {
|
||||
pend_obj_t pend_obj;
|
||||
k_msg_queue_t msg_queue;
|
||||
} k_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Create a queue.
|
||||
* create a queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_create(k_queue_t *queue);
|
||||
|
||||
/**
|
||||
* @brief Destroy a queue.
|
||||
* destroy a queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_destroy(k_queue_t *queue);
|
||||
|
||||
/**
|
||||
* @brief Pend a queue.
|
||||
* pend a queue.
|
||||
*
|
||||
* @attention we DONNOT perform a memcpy when msg_addr returned, we just let the *msg_addr point to an inner memory block.
|
||||
* that means you DONNOT need to alloc memory for msg_addr, msg_addr can just be a pointer.
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
* @param[out] msg_addr a pointer point to the message we wanna recive.
|
||||
* @param[out] msg_size pointer to the message size returned.
|
||||
* @param[in] timeout how much time(in k_tick_t) we would like to wait.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_PEND_NOWAIT we get nothing, and we don't wanna wait.
|
||||
* @retval #K_ERR_PEND_SCHED_LOCKED we can wait, but scheduler is locked.
|
||||
* @retval #K_ERR_PEND_TIMEOUT the time we wait is up, we get nothing.
|
||||
* @retval #K_ERR_PEND_DESTROY the queue we are pending is destroyed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_pend(k_queue_t *queue, void **msg_addr, size_t *msg_size, k_tick_t timeout);
|
||||
|
||||
/**
|
||||
* @brief Post a queue.
|
||||
* post a queue and wakeup one pending task.
|
||||
*
|
||||
* @attention when tos_queue_post return successfully, only one task who are waitting for the queue will be woken up.
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_QUEUE_FULL the message pool is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_post(k_queue_t *queue, void *msg_addr, size_t msg_size);
|
||||
|
||||
/**
|
||||
* @brief Post a queue.
|
||||
* post a queue and wakeup all the pending task.
|
||||
*
|
||||
* @attention when tos_queue_post_all return successfully, all of the tasks who are waitting for the queue will be woken up.
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_QUEUE_FULL the message pool is full.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_post_all(k_queue_t *queue, void *msg_addr, size_t msg_size);
|
||||
|
||||
/**
|
||||
* @brief Flush a queue.
|
||||
* flush a queue, clear all the msg in the queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_flush(k_queue_t *queue);
|
||||
|
||||
/**
|
||||
* @brief Remove one message from the queue.
|
||||
* Remove one message with certain address from the queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] queue pointer to the handler of the queue.
|
||||
* @param[in] msg_addr the address of the message.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_QUEUE_MSG_NOT_EXIST message to remove is not existed.
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_queue_remove(k_queue_t *queue, void *msg_addr);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _TOS_QUEUE_H_ */
|
||||
|
178
kernel/core/include/tos_ring_queue.h
Normal file
178
kernel/core/include/tos_ring_queue.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef _TOS_RING_QUEUE_H_
|
||||
#define _TOS_RING_QUEUE_H_
|
||||
|
||||
typedef struct k_ring_queue_st {
|
||||
knl_obj_t knl_obj;
|
||||
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
size_t total;
|
||||
|
||||
uint8_t *pool;
|
||||
|
||||
size_t item_size;
|
||||
size_t item_cnt;
|
||||
} k_ring_q_t;
|
||||
|
||||
#define RING_HEAD_ITEM(ring_q) (uint8_t *)(&ring_q->pool[ring_q->head * ring_q->item_size])
|
||||
#define RING_TAIL_ITEM(ring_q) (uint8_t *)(&ring_q->pool[ring_q->tail * ring_q->item_size])
|
||||
#define RING_NEXT(ring_q, index) ((index + 1) % ring_q->item_cnt)
|
||||
|
||||
/**
|
||||
* @brief Create a ring queue.
|
||||
* create a ring queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
* @param[in] pool pool buffer of the ring queue.
|
||||
* @param[in] item_cnt item count of the ring queue.
|
||||
* @param[in] item_size size of each item of the ring queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_create(k_ring_q_t *ring_q, void *pool, size_t item_cnt, size_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a ring queue.
|
||||
* destroy a ring queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_OBJ_INVALID_ALLOC_TYPE invalid alloc type(is dynamic allocated not static)
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_destroy(k_ring_q_t *ring_q);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
/**
|
||||
* @brief Create a ring queue with dynamic allocated pool.
|
||||
* create a ring queue with dynamic allocated pool.
|
||||
*
|
||||
* @attention pool inside is dynamic allocated.
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
* @param[in] item_cnt item count of the ring queue.
|
||||
* @param[in] item_size size of each item of the ring queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_OUT_OF_MEMORY out of memory
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_create_dyn(k_ring_q_t *ring_q, size_t item_cnt, size_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Destroy a ring queue with a dynamic allocated pool.
|
||||
* destroy a ring queue with a dynamic allocated pool.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_OBJ_INVALID_ALLOC_TYPE invalid alloc type(is static allocated not dynamic)
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_destroy_dyn(k_ring_q_t *ring_q);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enqueue an item.
|
||||
* enqueue an item into the ring queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
* @param[in] item the item to be enqueued.
|
||||
* @param[in] item_size size of the item(should be consistent with the item_size passed to tos_ring_q_create).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_RING_Q_ITEM_SIZE_NOT_MATCH the item_size is not consistent with the item_size passed to tos_ring_q_create.
|
||||
* @retval #K_ERR_RING_Q_FULL the ring queue is full.
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_enqueue(k_ring_q_t *ring_q, void *item, size_t item_size);
|
||||
|
||||
/**
|
||||
* @brief Dequeue an item.
|
||||
* dequeue an item from the ring queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
* @param[out] item buffer to hold the item dequeued.
|
||||
* @param[out] item_size size of the item dequeued(should be consistent with the item_size passed to tos_ring_q_create).
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
* @retval #K_ERR_RING_Q_EMPTY the ring queue is empty.
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_dequeue(k_ring_q_t *ring_q, void *item, size_t *item_size);
|
||||
|
||||
/**
|
||||
* @brief Flush the ring queue.
|
||||
* flush the ring queue.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
*
|
||||
* @return errcode
|
||||
* @retval #K_ERR_NONE return successfully.
|
||||
*/
|
||||
__API__ k_err_t tos_ring_q_flush(k_ring_q_t *ring_q);
|
||||
|
||||
/**
|
||||
* @brief Whether the ring queue is empty.
|
||||
* Whether the ring queue is empty.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
*
|
||||
* @return whether the ring queue is emtpy.
|
||||
* @retval #0 the ring queue is not empty.
|
||||
* @retval #Not 0 the ring queue is empty.
|
||||
*/
|
||||
__API__ int tos_ring_q_is_empty(k_ring_q_t *ring_q);
|
||||
|
||||
/**
|
||||
* @brief Whether the ring queue is full.
|
||||
* Whether the ring queue is full.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param[in] ring_q pointer to the handler of the ring queue.
|
||||
*
|
||||
* @return whether the ring queue is full.
|
||||
* @retval #0 the ring queue is not full.
|
||||
* @retval #Not 0 the ring queue is full.
|
||||
*/
|
||||
__API__ int tos_ring_q_is_full(k_ring_q_t *ring_q);
|
||||
|
||||
#endif
|
||||
|
@@ -21,10 +21,30 @@
|
||||
#if TOS_CFG_SEM_EN > 0u
|
||||
|
||||
typedef struct k_sem_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj;
|
||||
#endif
|
||||
|
||||
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 +52,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.
|
||||
|
@@ -26,21 +26,42 @@ typedef enum knl_state_en {
|
||||
KNL_STATE_RUNNING,
|
||||
} knl_state_t;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
// some kind of magic number, mainly for identifing whether the object is initialized, or whether user pass the correct parameter.
|
||||
typedef enum knl_obj_type_en {
|
||||
KNL_OBJ_TYPE_NONE = 0x0000,
|
||||
KNL_OBJ_TYPE_TASK = 0xDAD1,
|
||||
KNL_OBJ_TYPE_TIMER = 0xDAD2,
|
||||
KNL_OBJ_TYPE_MSG_QUEUE = 0xDAD4,
|
||||
KNL_OBJ_TYPE_MMBLK_POOL = 0xDAD8,
|
||||
KNL_OBJ_TYPE_FIFO = 0xDAE1,
|
||||
KNL_OBJ_TYPE_NONE = 0x0000,
|
||||
KNL_OBJ_TYPE_TASK = 0xDAD1,
|
||||
KNL_OBJ_TYPE_TIMER = 0xDAD2,
|
||||
KNL_OBJ_TYPE_MSG_QUEUE = 0xDAD3,
|
||||
KNL_OBJ_TYPE_MMBLK_POOL = 0xDAD4,
|
||||
KNL_OBJ_TYPE_RING_QUEUE = 0xDAD5,
|
||||
KNL_OBJ_TYPE_BINARY_HEAP = 0xDAD6,
|
||||
KNL_OBJ_TYPE_PRIORITY_QUEUE = 0xDAD7,
|
||||
KNL_OBJ_TYPE_CHAR_FIFO = 0xDAD8,
|
||||
|
||||
// ipc object
|
||||
KNL_OBJ_TYPE_SEMAPHORE = 0x1BEE,
|
||||
KNL_OBJ_TYPE_MUTEX = 0x2BEE,
|
||||
KNL_OBJ_TYPE_EVENT = 0x3BEE,
|
||||
KNL_OBJ_TYPE_MAIL_QUEUE = 0x4BEE,
|
||||
KNL_OBJ_TYPE_MESSAGE_QUEUE = 0x5BEE,
|
||||
KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE = 0x6BEE,
|
||||
KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE = 0x7BEE,
|
||||
KNL_OBJ_TYPE_COUNTDOWNLATCH = 0x8BEE,
|
||||
KNL_OBJ_TYPE_COMPLETION = 0x9BEE,
|
||||
} knl_obj_type_t;
|
||||
|
||||
typedef enum knl_obj_alloc_type_en {
|
||||
KNL_OBJ_ALLOC_TYPE_NONE,
|
||||
KNL_OBJ_ALLOC_TYPE_STATIC,
|
||||
KNL_OBJ_ALLOC_TYPE_DYNAMIC,
|
||||
} knl_obj_alloc_type_t;
|
||||
|
||||
typedef struct knl_object_st {
|
||||
knl_obj_type_t type;
|
||||
} knl_obj_t;
|
||||
knl_obj_alloc_type_t alloc_type; /* is dynamic allocated(using tos_mmheap) or static memory? */
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_type_t type;
|
||||
#endif
|
||||
} knl_obj_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize the kernel.
|
||||
@@ -145,9 +166,17 @@ __KERNEL__ k_tick_t knl_next_expires_get(void);
|
||||
__KERNEL__ void knl_sched(void);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
__KERNEL__ int knl_object_verify(knl_obj_t *object, knl_obj_type_t type);
|
||||
__KERNEL__ int knl_object_init(knl_obj_t *object, knl_obj_type_t type);
|
||||
__KERNEL__ int knl_object_deinit(knl_obj_t *object);
|
||||
__KERNEL__ int knl_object_verify(knl_obj_t *knl_obj, knl_obj_type_t type);
|
||||
__KERNEL__ void knl_object_init(knl_obj_t *knl_obj, knl_obj_type_t type);
|
||||
__KERNEL__ void knl_object_deinit(knl_obj_t *knl_obj);
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
__KERNEL__ void knl_object_alloc_reset(knl_obj_t *knl_obj);
|
||||
__KERNEL__ void knl_object_alloc_set_dynamic(knl_obj_t *knl_obj);
|
||||
__KERNEL__ void knl_object_alloc_set_static(knl_obj_t *knl_obj);
|
||||
__KERNEL__ int knl_object_alloc_is_dynamic(knl_obj_t *knl_obj);
|
||||
__KERNEL__ int knl_object_alloc_is_static(knl_obj_t *knl_obj);
|
||||
#endif
|
||||
|
||||
__KERNEL__ int knl_is_sched_locked(void);
|
||||
|
@@ -61,15 +61,15 @@
|
||||
|
||||
typedef void (*k_task_entry_t)(void *arg);
|
||||
|
||||
typedef void (*k_task_walker)(k_task_t *task);
|
||||
|
||||
/**
|
||||
* task control block
|
||||
*/
|
||||
typedef struct k_task_st {
|
||||
k_stack_t *sp; /**< task stack pointer. This lady always comes first, we count on her in port_s.S for context switch. */
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj; /**< just for verification, test whether current object is really a task. */
|
||||
#endif
|
||||
|
||||
char *name; /**< task name */
|
||||
k_task_entry_t entry; /**< task entry */
|
||||
@@ -80,6 +80,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 */
|
||||
@@ -104,9 +110,13 @@ typedef struct k_task_st {
|
||||
k_timeslice_t timeslice; /**< how much time slice left for us? */
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_MSG_EN > 0u
|
||||
void *msg_addr; /**< if we pend a queue successfully, our msg_addr and msg_size will be set by the queue poster */
|
||||
size_t msg_size;
|
||||
#if (TOS_CFG_MESSAGE_QUEUE_EN > 0u) || (TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN > 0u)
|
||||
void *msg; /**< if we pend a message queue successfully, our msg will be set by the message queue poster */
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_MAIL_QUEUE_EN > 0u) || (TOS_CFG_PRIORITY_MAIL_QUEUE_EN > 0u)
|
||||
void *mail; /**< if we pend a mail queue successfully, our mail and mail_size will be set by the message queue poster */
|
||||
size_t mail_size;
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_EVENT_EN > 0u
|
||||
@@ -131,7 +141,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 +170,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 +299,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 +330,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 +414,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%p", task->stk_base);
|
||||
tos_kprintln("stk top : 0x%p", task->stk_base + task->stk_size);
|
||||
tos_kprintf("\n");
|
||||
}
|
||||
|
||||
#endif /* _TOS_TASK_H_ */
|
||||
|
||||
|
@@ -48,9 +48,7 @@ typedef void (*k_timer_callback_t)(void *arg);
|
||||
* timer control block
|
||||
*/
|
||||
typedef struct k_timer_st {
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_obj_t knl_obj; /**< just for verification, test whether current object is really a timer */
|
||||
#endif
|
||||
|
||||
k_timer_callback_t cb; /**< callback when time is up */
|
||||
void *cb_arg; /**< argument for callback */
|
||||
|
314
kernel/core/tos_binary_heap.c
Normal file
314
kernel/core/tos_binary_heap.c
Normal file
@@ -0,0 +1,314 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
__STATIC_INLINE__ void bin_heap_item_copy_to(k_bin_heap_t *bin_heap, void *item_out, size_t *item_size)
|
||||
{
|
||||
memcpy(item_out, BIN_HEAP_FIRST_ITEM(bin_heap), bin_heap->item_size);
|
||||
if (item_size) {
|
||||
*item_size = bin_heap->item_size;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void bin_heap_item_copy_from(k_bin_heap_t *bin_heap, void *item_in)
|
||||
{
|
||||
memcpy(BIN_HEAP_LAST_ITEM(bin_heap), item_in, bin_heap->item_size);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void bin_heap_item_increase(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
++bin_heap->total;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void bin_heap_item_decrease(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
--bin_heap->total;
|
||||
}
|
||||
|
||||
__STATIC__ void bin_heap_do_percolate_up(k_bin_heap_t *bin_heap, uint16_t hole, void *item_backup)
|
||||
{
|
||||
k_bin_heap_cmp cmp;
|
||||
size_t item_size;
|
||||
uint16_t parent, top;
|
||||
void *hole_item, *parent_item;
|
||||
|
||||
top = 0u;
|
||||
parent = BIN_HEAP_PARENT(hole);
|
||||
cmp = bin_heap->cmp;
|
||||
item_size = bin_heap->item_size;
|
||||
|
||||
hole_item = BIN_HEAP_THE_ITEM(bin_heap, hole);
|
||||
parent_item = BIN_HEAP_THE_ITEM(bin_heap, parent);
|
||||
|
||||
while (hole > top && cmp(item_backup, parent_item)) {
|
||||
memcpy(hole_item, parent_item, item_size);
|
||||
hole = parent;
|
||||
parent = BIN_HEAP_PARENT(hole);
|
||||
hole_item = BIN_HEAP_THE_ITEM(bin_heap, hole);
|
||||
parent_item = BIN_HEAP_THE_ITEM(bin_heap, parent);
|
||||
}
|
||||
hole_item = BIN_HEAP_THE_ITEM(bin_heap, hole);
|
||||
memcpy(hole_item, item_backup, item_size);
|
||||
}
|
||||
|
||||
__STATIC__ void bin_heap_percolate_up(k_bin_heap_t *bin_heap, void *item_backup)
|
||||
{
|
||||
bin_heap_do_percolate_up(bin_heap, bin_heap->total, item_backup);
|
||||
}
|
||||
|
||||
__STATIC__ void bin_heap_percolate_down(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
k_bin_heap_cmp cmp;
|
||||
size_t item_size;
|
||||
uint16_t lchild, rchild, the_child, hole;
|
||||
void *hole_item, *rchild_item, *lchild_item, *the_child_item;
|
||||
|
||||
hole = 0u;
|
||||
rchild = BIN_HEAP_RCHILD(hole);
|
||||
lchild = BIN_HEAP_LSIBLING(rchild);
|
||||
the_child = rchild;
|
||||
cmp = bin_heap->cmp;
|
||||
item_size = bin_heap->item_size;
|
||||
|
||||
hole_item = BIN_HEAP_THE_ITEM(bin_heap, hole);
|
||||
rchild_item = BIN_HEAP_THE_ITEM(bin_heap, rchild);
|
||||
lchild_item = BIN_HEAP_THE_ITEM(bin_heap, lchild);
|
||||
|
||||
while (the_child < bin_heap->total) {
|
||||
if (cmp(lchild_item, rchild_item)) {
|
||||
the_child = lchild;
|
||||
}
|
||||
the_child_item = BIN_HEAP_THE_ITEM(bin_heap, the_child);
|
||||
memcpy(hole_item, the_child_item, item_size);
|
||||
|
||||
hole = the_child;
|
||||
the_child = BIN_HEAP_RCHILD(the_child);
|
||||
rchild = the_child;
|
||||
lchild = BIN_HEAP_LSIBLING(rchild);
|
||||
|
||||
hole_item = BIN_HEAP_THE_ITEM(bin_heap, hole);
|
||||
rchild_item = BIN_HEAP_THE_ITEM(bin_heap, rchild);
|
||||
lchild_item = BIN_HEAP_THE_ITEM(bin_heap, lchild);
|
||||
}
|
||||
|
||||
if (the_child == bin_heap->total) {
|
||||
memcpy(hole_item, lchild_item, item_size);
|
||||
hole = lchild;
|
||||
hole_item = BIN_HEAP_THE_ITEM(bin_heap, hole);
|
||||
}
|
||||
bin_heap_do_percolate_up(bin_heap, hole, BIN_HEAP_LAST_ITEM(bin_heap));
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_bin_heap_create(k_bin_heap_t *bin_heap, void *pool, size_t item_cnt, size_t item_size, k_bin_heap_cmp cmp)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_PTR_SANITY_CHECK(pool);
|
||||
TOS_PTR_SANITY_CHECK(cmp);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&bin_heap->knl_obj, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_set_static(&bin_heap->knl_obj);
|
||||
#endif
|
||||
|
||||
bin_heap->total = 0;
|
||||
bin_heap->cmp = cmp;
|
||||
bin_heap->item_size = item_size;
|
||||
bin_heap->item_cnt = item_cnt;
|
||||
bin_heap->pool = (uint8_t *)pool;
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_bin_heap_destroy(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
if (!knl_object_alloc_is_static(&bin_heap->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
bin_heap->total = 0;
|
||||
bin_heap->cmp = K_NULL;
|
||||
bin_heap->item_size = 0;
|
||||
bin_heap->item_cnt = 0;
|
||||
bin_heap->pool = K_NULL;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&bin_heap->knl_obj);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_reset(&bin_heap->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_bin_heap_create_dyn(k_bin_heap_t *bin_heap, size_t item_cnt, size_t item_size, k_bin_heap_cmp cmp)
|
||||
{
|
||||
void *pool;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_PTR_SANITY_CHECK(cmp);
|
||||
|
||||
pool = tos_mmheap_alloc(item_cnt * item_size);
|
||||
if (!pool) {
|
||||
return K_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
bin_heap->total = 0;
|
||||
bin_heap->cmp = cmp;
|
||||
bin_heap->item_size = item_size;
|
||||
bin_heap->item_cnt = item_cnt;
|
||||
bin_heap->pool = (uint8_t *)pool;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&bin_heap->knl_obj, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&bin_heap->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_bin_heap_destroy_dyn(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&bin_heap->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
tos_mmheap_free(bin_heap->pool);
|
||||
|
||||
bin_heap->total = 0;
|
||||
bin_heap->cmp = K_NULL;
|
||||
bin_heap->item_size = 0;
|
||||
bin_heap->item_cnt = 0;
|
||||
bin_heap->pool = K_NULL;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&bin_heap->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&bin_heap->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ k_err_t tos_bin_heap_push(k_bin_heap_t *bin_heap, void *item, size_t item_size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_PTR_SANITY_CHECK(item);
|
||||
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
|
||||
if (item_size != bin_heap->item_size) {
|
||||
return K_ERR_BIN_HEAP_ITEM_SIZE_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (tos_bin_heap_is_full(bin_heap)) {
|
||||
return K_ERR_BIN_HEAP_FULL;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
bin_heap_item_copy_from(bin_heap, item);
|
||||
bin_heap_percolate_up(bin_heap, item);
|
||||
bin_heap_item_increase(bin_heap);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_bin_heap_pop(k_bin_heap_t *bin_heap, void *item, size_t *item_size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_PTR_SANITY_CHECK(item);
|
||||
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_bin_heap_is_empty(bin_heap)) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_BIN_HEAP_EMPTY;
|
||||
}
|
||||
|
||||
bin_heap_item_copy_to(bin_heap, item, item_size);
|
||||
bin_heap_item_decrease(bin_heap);
|
||||
bin_heap_percolate_down(bin_heap);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_bin_heap_flush(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(bin_heap);
|
||||
TOS_OBJ_VERIFY(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
bin_heap->total = 0;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ int tos_bin_heap_is_empty(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_empty = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(bin_heap, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_empty = (bin_heap->total == 0);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
__API__ int tos_bin_heap_is_full(k_bin_heap_t *bin_heap)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_full = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(bin_heap, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(bin_heap, KNL_OBJ_TYPE_BINARY_HEAP, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_full = (bin_heap->total == bin_heap->item_cnt);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_full;
|
||||
}
|
||||
|
203
kernel/core/tos_char_fifo.c
Normal file
203
kernel/core/tos_char_fifo.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_create(k_chr_fifo_t *chr_fifo, void *buffer, size_t size)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
TOS_PTR_SANITY_CHECK(buffer);
|
||||
|
||||
err = tos_ring_q_create(&chr_fifo->ring_q, buffer, size, sizeof(uint8_t));
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&chr_fifo->knl_obj, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_set_static(&chr_fifo->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_destroy(k_chr_fifo_t *chr_fifo)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
TOS_OBJ_VERIFY(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
if (!knl_object_alloc_is_static(&chr_fifo->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = tos_ring_q_destroy(&chr_fifo->ring_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&chr_fifo->knl_obj);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_reset(&chr_fifo->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_create_dyn(k_chr_fifo_t *chr_fifo, size_t fifo_size)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
|
||||
err = tos_ring_q_create_dyn(&chr_fifo->ring_q, fifo_size, sizeof(uint8_t));
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&chr_fifo->knl_obj, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&chr_fifo->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_destroy_dyn(k_chr_fifo_t *chr_fifo)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
TOS_OBJ_VERIFY(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&chr_fifo->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
err = tos_ring_q_destroy_dyn(&chr_fifo->ring_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&chr_fifo->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&chr_fifo->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_push(k_chr_fifo_t *chr_fifo, uint8_t data)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
TOS_OBJ_VERIFY(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
|
||||
return tos_ring_q_enqueue(&chr_fifo->ring_q, &data, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
__API__ int tos_chr_fifo_push_stream(k_chr_fifo_t *chr_fifo, uint8_t *stream, size_t size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
int i = 0;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(chr_fifo, 0);
|
||||
TOS_OBJ_VERIFY_RC(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO, 0);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
while (i < size) {
|
||||
err = tos_ring_q_enqueue(&chr_fifo->ring_q, &stream[i], sizeof(uint8_t));
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_pop(k_chr_fifo_t *chr_fifo, uint8_t *out)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
TOS_OBJ_VERIFY(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
|
||||
return tos_ring_q_dequeue(&chr_fifo->ring_q, (void *)out, K_NULL);
|
||||
}
|
||||
|
||||
__API__ int tos_chr_fifo_pop_stream(k_chr_fifo_t *chr_fifo, uint8_t *buffer, size_t size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int i = 0;
|
||||
uint8_t data;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(chr_fifo, 0);
|
||||
TOS_OBJ_VERIFY_RC(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO, 0);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
while (i < size) {
|
||||
if (tos_ring_q_dequeue(&chr_fifo->ring_q, &data, K_NULL) != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
buffer[i++] = data;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_chr_fifo_flush(k_chr_fifo_t *chr_fifo)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(chr_fifo);
|
||||
TOS_OBJ_VERIFY(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO);
|
||||
|
||||
return tos_ring_q_flush(&chr_fifo->ring_q);
|
||||
}
|
||||
|
||||
__API__ int tos_chr_fifo_is_empty(k_chr_fifo_t *chr_fifo)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK_RC(chr_fifo, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO, K_FALSE);
|
||||
|
||||
return tos_ring_q_is_empty(&chr_fifo->ring_q);
|
||||
}
|
||||
|
||||
__API__ int tos_chr_fifo_is_full(k_chr_fifo_t *chr_fifo)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK_RC(chr_fifo, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(chr_fifo, KNL_OBJ_TYPE_CHAR_FIFO, K_FALSE);
|
||||
|
||||
return tos_ring_q_is_full(&chr_fifo->ring_q);
|
||||
}
|
||||
|
@@ -23,7 +23,11 @@ __API__ k_err_t tos_completion_create(k_completion_t *completion)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(completion);
|
||||
|
||||
pend_object_init(&completion->pend_obj, PEND_TYPE_COMPLETION);
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&completion->knl_obj, KNL_OBJ_TYPE_COMPLETION);
|
||||
#endif
|
||||
|
||||
pend_object_init(&completion->pend_obj);
|
||||
completion->done = (completion_done_t)0u;
|
||||
|
||||
return K_ERR_NONE;
|
||||
@@ -34,12 +38,7 @@ __API__ k_err_t tos_completion_destroy(k_completion_t *completion)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(completion);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&completion->pend_obj, PEND_TYPE_COMPLETION)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(completion, KNL_OBJ_TYPE_COMPLETION);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -49,6 +48,10 @@ __API__ k_err_t tos_completion_destroy(k_completion_t *completion)
|
||||
|
||||
pend_object_deinit(&completion->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&completion->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
@@ -60,12 +63,7 @@ __API__ k_err_t tos_completion_pend_timed(k_completion_t *completion, k_tick_t t
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(completion);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&completion->pend_obj, PEND_TYPE_COMPLETION)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(completion, KNL_OBJ_TYPE_COMPLETION);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -107,12 +105,7 @@ __STATIC__ k_err_t completion_do_post(k_completion_t *completion, opt_post_t opt
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(completion);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&completion->pend_obj, PEND_TYPE_COMPLETION)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(completion, KNL_OBJ_TYPE_COMPLETION);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -151,12 +144,7 @@ __API__ k_err_t tos_completion_reset(k_completion_t *completion)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(completion);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&completion->pend_obj, PEND_TYPE_COMPLETION)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(completion, KNL_OBJ_TYPE_COMPLETION);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
completion->done = (completion_done_t)0u;
|
||||
@@ -170,13 +158,8 @@ __API__ int tos_completion_is_done(k_completion_t *completion)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_done = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(completion);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&completion->pend_obj, PEND_TYPE_COMPLETION)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_PTR_SANITY_CHECK_RC(completion, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(completion, KNL_OBJ_TYPE_COMPLETION, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_done = (completion->done > (completion_done_t)0u ? K_TRUE : K_FALSE);
|
||||
|
@@ -23,7 +23,11 @@ __API__ k_err_t tos_countdownlatch_create(k_countdownlatch_t *countdownlatch, k_
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(countdownlatch);
|
||||
|
||||
pend_object_init(&countdownlatch->pend_obj, PEND_TYPE_COUNTDOWNLATCH);
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&countdownlatch->knl_obj, KNL_OBJ_TYPE_COUNTDOWNLATCH);
|
||||
#endif
|
||||
|
||||
pend_object_init(&countdownlatch->pend_obj);
|
||||
countdownlatch->count = count;
|
||||
|
||||
return K_ERR_NONE;
|
||||
@@ -34,12 +38,7 @@ __API__ k_err_t tos_countdownlatch_destroy(k_countdownlatch_t *countdownlatch)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(countdownlatch);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&countdownlatch->pend_obj, PEND_TYPE_COUNTDOWNLATCH)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(countdownlatch, KNL_OBJ_TYPE_COUNTDOWNLATCH);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -49,6 +48,10 @@ __API__ k_err_t tos_countdownlatch_destroy(k_countdownlatch_t *countdownlatch)
|
||||
|
||||
pend_object_deinit(&countdownlatch->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&countdownlatch->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
@@ -60,12 +63,7 @@ __API__ k_err_t tos_countdownlatch_pend_timed(k_countdownlatch_t *countdownlatch
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(countdownlatch);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&countdownlatch->pend_obj, PEND_TYPE_COUNTDOWNLATCH)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(countdownlatch, KNL_OBJ_TYPE_COUNTDOWNLATCH);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -107,12 +105,7 @@ __API__ k_err_t tos_countdownlatch_post(k_countdownlatch_t *countdownlatch)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(countdownlatch);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&countdownlatch->pend_obj, PEND_TYPE_COUNTDOWNLATCH)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(countdownlatch, KNL_OBJ_TYPE_COUNTDOWNLATCH);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -141,12 +134,7 @@ __API__ k_err_t tos_countdownlatch_reset(k_countdownlatch_t *countdownlatch, k_c
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(countdownlatch);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&countdownlatch->pend_obj, PEND_TYPE_COUNTDOWNLATCH)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(countdownlatch, KNL_OBJ_TYPE_COUNTDOWNLATCH);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
countdownlatch->count = count;
|
||||
|
@@ -23,7 +23,11 @@ __API__ k_err_t tos_event_create(k_event_t *event, k_event_flag_t init_flag)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(event);
|
||||
|
||||
pend_object_init(&event->pend_obj, PEND_TYPE_EVENT);
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&event->knl_obj, KNL_OBJ_TYPE_EVENT);
|
||||
#endif
|
||||
|
||||
pend_object_init(&event->pend_obj);
|
||||
event->flag = init_flag;
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
@@ -33,12 +37,7 @@ __API__ k_err_t tos_event_destroy(k_event_t *event)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(event);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&event->pend_obj, PEND_TYPE_EVENT)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(event, KNL_OBJ_TYPE_EVENT);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -49,6 +48,10 @@ __API__ k_err_t tos_event_destroy(k_event_t *event)
|
||||
pend_object_deinit(&event->pend_obj);
|
||||
event->flag = (k_event_flag_t)0u;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&event->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
@@ -77,12 +80,7 @@ __API__ k_err_t tos_event_pend(k_event_t *event, k_event_flag_t flag_expect, k_e
|
||||
|
||||
TOS_PTR_SANITY_CHECK(event);
|
||||
TOS_PTR_SANITY_CHECK(flag_match);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&event->pend_obj, PEND_TYPE_EVENT)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(event, KNL_OBJ_TYPE_EVENT);
|
||||
|
||||
if (!(opt_pend & TOS_OPT_EVENT_PEND_ALL) && !(opt_pend & TOS_OPT_EVENT_PEND_ANY)) {
|
||||
return K_ERR_EVENT_PEND_OPT_INVALID;
|
||||
@@ -140,12 +138,7 @@ __STATIC__ k_err_t event_do_post(k_event_t *event, k_event_flag_t flag, opt_even
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(event);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&event->pend_obj, PEND_TYPE_EVENT)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(event, KNL_OBJ_TYPE_EVENT);
|
||||
|
||||
if (opt_post == OPT_EVENT_POST_KEP) {
|
||||
event->flag |= flag;
|
||||
|
@@ -1,213 +0,0 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
__STATIC_INLINE__ int fifo_next(k_fifo_t *fifo, int index)
|
||||
{
|
||||
return (index + 1) % fifo->siz;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_fifo_create(k_fifo_t *fifo, uint8_t *buffer, size_t size)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(fifo);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO);
|
||||
#endif
|
||||
|
||||
fifo->beg = 0;
|
||||
fifo->end = 0;
|
||||
fifo->cnt = 0;
|
||||
fifo->buf = buffer;
|
||||
fifo->siz = size;
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_fifo_destroy(k_fifo_t *fifo)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(fifo);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
fifo->beg = 0;
|
||||
fifo->end = 0;
|
||||
fifo->cnt = 0;
|
||||
fifo->buf = K_NULL;
|
||||
fifo->siz = 0;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&fifo->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_fifo_push(k_fifo_t *fifo, uint8_t data)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_fifo_is_full(fifo)) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_FIFO_FULL;
|
||||
}
|
||||
|
||||
fifo->buf[fifo->end] = data;
|
||||
fifo->end = fifo_next(fifo, fifo->end);
|
||||
++fifo->cnt;
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ int tos_fifo_push_stream(k_fifo_t *fifo, uint8_t *stream, size_t size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int i = 0;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
while (!tos_fifo_is_full(fifo) && i < size) {
|
||||
if (tos_fifo_push(fifo, stream[i]) != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_fifo_pop(k_fifo_t *fifo, uint8_t *out)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
uint8_t data;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_fifo_is_empty(fifo)) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_FIFO_EMPTY;
|
||||
}
|
||||
|
||||
data = fifo->buf[fifo->beg];
|
||||
fifo->beg = fifo_next(fifo, fifo->beg);
|
||||
--fifo->cnt;
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
*out = data;
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ int tos_fifo_pop_stream(k_fifo_t *fifo, uint8_t *buffer, size_t size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int i = 0;
|
||||
uint8_t data;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
while (!tos_fifo_is_empty(fifo) && i < size) {
|
||||
if (tos_fifo_pop(fifo, &data) != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
buffer[i++] = data;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return i;
|
||||
}
|
||||
|
||||
__API__ void tos_fifo_flush(k_fifo_t *fifo)
|
||||
{
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
fifo->beg = 0;
|
||||
fifo->end = 0;
|
||||
fifo->cnt = 0;
|
||||
}
|
||||
|
||||
__API__ int tos_fifo_is_empty(k_fifo_t *fifo)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_empty = 0;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_empty = (fifo->cnt == 0);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
__API__ int tos_fifo_is_full(k_fifo_t *fifo)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_full = 0;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&fifo->knl_obj, KNL_OBJ_TYPE_FIFO)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_full = (fifo->cnt == fifo->siz);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_full;
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -66,11 +72,6 @@ size_t const k_timer_task_stk_size = TOS_CFG_TIMER_TASK_STK_SIZ
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_MSG_EN > 0u
|
||||
TOS_LIST_DEFINE(k_msg_freelist);
|
||||
k_msg_t k_msg_pool[TOS_CFG_MSG_POOL_SIZE];
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_PWR_MGR_EN > 0u
|
||||
pm_device_ctl_t k_pm_device_ctl = { 0u };
|
||||
|
||||
|
254
kernel/core/tos_mail_queue.c
Normal file
254
kernel/core/tos_mail_queue.c
Normal file
@@ -0,0 +1,254 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
#if TOS_CFG_MAIL_QUEUE_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_mail_q_create(k_mail_q_t *mail_q, void *pool, size_t mail_cnt, size_t mail_size)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
k_err_t err;
|
||||
|
||||
err = tos_ring_q_create(&mail_q->ring_q, pool, mail_cnt, mail_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pend_object_init(&mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&mail_q->knl_obj, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_set_static(&mail_q->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_mail_q_destroy(k_mail_q_t *mail_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
if (!knl_object_alloc_is_static(&mail_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_ring_q_destroy(&mail_q->ring_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&mail_q->pend_obj)) {
|
||||
pend_wakeup_all(&mail_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&mail_q->knl_obj);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_reset(&mail_q->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_mail_q_create_dyn(k_mail_q_t *mail_q, size_t mail_cnt, size_t mail_size)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
k_err_t err;
|
||||
|
||||
err = tos_ring_q_create_dyn(&mail_q->ring_q, mail_cnt, mail_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pend_object_init(&mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&mail_q->knl_obj, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&mail_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_mail_q_destroy_dyn(k_mail_q_t *mail_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&mail_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_ring_q_destroy_dyn(&mail_q->ring_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&mail_q->pend_obj)) {
|
||||
pend_wakeup_all(&mail_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&mail_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&mail_q->knl_obj);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ k_err_t tos_mail_q_flush(k_mail_q_t *mail_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
|
||||
return tos_ring_q_flush(&mail_q->ring_q);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_mail_q_pend(k_mail_q_t *mail_q, void *mail_buf, size_t *mail_size, k_tick_t timeout)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
TOS_PTR_SANITY_CHECK(mail_buf);
|
||||
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_ring_q_dequeue(&mail_q->ring_q, mail_buf, mail_size) == K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (timeout == TOS_TIME_NOWAIT) {
|
||||
*mail_size = 0;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_NOWAIT;
|
||||
}
|
||||
|
||||
if (knl_is_sched_locked()) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
pend_task_block(k_curr_task, &mail_q->pend_obj, timeout);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
err = pend_state2errno(k_curr_task->pend_state);
|
||||
|
||||
if (err == K_ERR_NONE) {
|
||||
memcpy(mail_buf, k_curr_task->mail, k_curr_task->mail_size);
|
||||
*mail_size = k_curr_task->mail_size;
|
||||
k_curr_task->mail = K_NULL;
|
||||
k_curr_task->mail_size = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
__STATIC__ void mail_task_recv(k_task_t *task, void *mail_buf, size_t mail_size)
|
||||
{
|
||||
task->mail = mail_buf;
|
||||
task->mail_size = mail_size;
|
||||
pend_task_wakeup(task, PEND_STATE_POST);
|
||||
}
|
||||
|
||||
__STATIC__ k_err_t mail_q_do_post(k_mail_q_t *mail_q, void *mail_buf, size_t mail_size, opt_post_t opt)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mail_q);
|
||||
TOS_PTR_SANITY_CHECK(mail_buf);
|
||||
TOS_OBJ_VERIFY(mail_q, KNL_OBJ_TYPE_MAIL_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (pend_is_nopending(&mail_q->pend_obj)) {
|
||||
err = tos_ring_q_enqueue(&mail_q->ring_q, mail_buf, mail_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (opt == OPT_POST_ONE) {
|
||||
mail_task_recv(TOS_LIST_FIRST_ENTRY(&mail_q->pend_obj.list, k_task_t, pend_list),
|
||||
mail_buf, mail_size);
|
||||
} else { // OPT_POST_ALL
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &mail_q->pend_obj.list) {
|
||||
mail_task_recv(TOS_LIST_ENTRY(curr, k_task_t, pend_list),
|
||||
mail_buf, mail_size);
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_mail_q_post(k_mail_q_t *mail_q, void *mail_buf, size_t mail_size)
|
||||
{
|
||||
return mail_q_do_post(mail_q, mail_buf, mail_size, OPT_POST_ONE);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_mail_q_post_all(k_mail_q_t *mail_q, void *mail_buf, size_t mail_size)
|
||||
{
|
||||
return mail_q_do_post(mail_q, mail_buf, mail_size, OPT_POST_ALL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
251
kernel/core/tos_message_queue.c
Normal file
251
kernel/core/tos_message_queue.c
Normal file
@@ -0,0 +1,251 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_msg_q_create(k_msg_q_t *msg_q, void *pool, size_t msg_cnt)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
TOS_PTR_SANITY_CHECK(pool);
|
||||
|
||||
err = tos_ring_q_create(&msg_q->ring_q, pool, msg_cnt, sizeof(void *));
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pend_object_init(&msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&msg_q->knl_obj, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_set_static(&msg_q->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_q_destroy(k_msg_q_t *msg_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
if (!knl_object_alloc_is_static(&msg_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_ring_q_destroy(&msg_q->ring_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&msg_q->pend_obj)) {
|
||||
pend_wakeup_all(&msg_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&msg_q->knl_obj);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_reset(&msg_q->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_msg_q_create_dyn(k_msg_q_t *msg_q, size_t msg_cnt)
|
||||
{
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
|
||||
err = tos_ring_q_create_dyn(&msg_q->ring_q, msg_cnt, sizeof(void *));
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pend_object_init(&msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&msg_q->knl_obj, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&msg_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_q_destroy_dyn(k_msg_q_t *msg_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&msg_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_ring_q_destroy_dyn(&msg_q->ring_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&msg_q->pend_obj)) {
|
||||
pend_wakeup_all(&msg_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&msg_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&msg_q->knl_obj);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ k_err_t tos_msg_q_flush(k_msg_q_t *msg_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
|
||||
return tos_ring_q_flush(&msg_q->ring_q);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_q_pend(k_msg_q_t *msg_q, void **msg_ptr, k_tick_t timeout)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
TOS_PTR_SANITY_CHECK(msg_ptr);
|
||||
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_ring_q_dequeue(&msg_q->ring_q, msg_ptr, K_NULL) == K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (timeout == TOS_TIME_NOWAIT) {
|
||||
*msg_ptr = K_NULL;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_NOWAIT;
|
||||
}
|
||||
|
||||
if (knl_is_sched_locked()) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
pend_task_block(k_curr_task, &msg_q->pend_obj, timeout);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
err = pend_state2errno(k_curr_task->pend_state);
|
||||
|
||||
if (err == K_ERR_NONE) {
|
||||
*msg_ptr = k_curr_task->msg;
|
||||
k_curr_task->msg = K_NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
__STATIC__ void msg_q_task_recv(k_task_t *task, void *msg_ptr)
|
||||
{
|
||||
task->msg = msg_ptr;
|
||||
pend_task_wakeup(task, PEND_STATE_POST);
|
||||
}
|
||||
|
||||
__STATIC__ k_err_t msg_q_do_post(k_msg_q_t *msg_q, void *msg_ptr, opt_post_t opt)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_q);
|
||||
TOS_OBJ_VERIFY(msg_q, KNL_OBJ_TYPE_MESSAGE_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (pend_is_nopending(&msg_q->pend_obj)) {
|
||||
err = tos_ring_q_enqueue(&msg_q->ring_q, &msg_ptr, sizeof(void*));
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (opt == OPT_POST_ONE) {
|
||||
msg_q_task_recv(TOS_LIST_FIRST_ENTRY(&msg_q->pend_obj.list, k_task_t, pend_list), msg_ptr);
|
||||
} else { // OPT_POST_ALL
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &msg_q->pend_obj.list) {
|
||||
msg_q_task_recv(TOS_LIST_ENTRY(curr, k_task_t, pend_list), msg_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_q_post(k_msg_q_t *msg_q, void *msg_ptr)
|
||||
{
|
||||
return msg_q_do_post(msg_q, msg_ptr, OPT_POST_ONE);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_q_post_all(k_msg_q_t *msg_q, void *msg_ptr)
|
||||
{
|
||||
return msg_q_do_post(msg_q, msg_ptr, OPT_POST_ALL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -61,12 +61,7 @@ __API__ k_err_t tos_mmblk_pool_create(k_mmblk_pool_t *mbp, void *pool_start, siz
|
||||
__API__ k_err_t tos_mmblk_pool_destroy(k_mmblk_pool_t *mbp)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(mbp);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&mbp->knl_obj, KNL_OBJ_TYPE_MMBLK_POOL)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(mbp, KNL_OBJ_TYPE_MMBLK_POOL);
|
||||
|
||||
mbp->pool_start = K_NULL;
|
||||
mbp->free_list = K_NULL;
|
||||
@@ -86,12 +81,7 @@ __API__ k_err_t tos_mmblk_alloc(k_mmblk_pool_t *mbp, void **blk)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mbp);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&mbp->knl_obj, KNL_OBJ_TYPE_MMBLK_POOL)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(mbp, KNL_OBJ_TYPE_MMBLK_POOL);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
if (mbp->blk_free == 0) {
|
||||
@@ -112,12 +102,7 @@ __API__ k_err_t tos_mmblk_free(k_mmblk_pool_t *mbp, void *blk)
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mbp);
|
||||
TOS_PTR_SANITY_CHECK(blk);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&mbp->knl_obj, KNL_OBJ_TYPE_MMBLK_POOL)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(mbp, KNL_OBJ_TYPE_MMBLK_POOL);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
if (mbp->blk_free >= mbp->blk_max) {
|
||||
|
@@ -1,209 +0,0 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <tos.h>
|
||||
|
||||
#if TOS_CFG_MSG_EN > 0u
|
||||
|
||||
__KERNEL__ void msgpool_init(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < TOS_CFG_MSG_POOL_SIZE; ++i) {
|
||||
tos_list_init(&k_msg_pool[i].list);
|
||||
tos_list_add(&k_msg_pool[i].list, &k_msg_freelist);
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC__ k_msg_t *msgpool_alloc(void)
|
||||
{
|
||||
k_msg_t *msg = K_NULL;
|
||||
|
||||
if (tos_list_empty(&k_msg_freelist)) {
|
||||
return K_NULL;
|
||||
}
|
||||
|
||||
msg = TOS_LIST_FIRST_ENTRY(&k_msg_freelist, k_msg_t, list);
|
||||
tos_list_del(&msg->list);
|
||||
return msg;
|
||||
}
|
||||
|
||||
__STATIC__ void msgpool_free(k_msg_t *msg)
|
||||
{
|
||||
tos_list_del(&msg->list);
|
||||
tos_list_add(&msg->list, &k_msg_freelist);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_queue_create(k_msg_queue_t *msg_queue)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(msg_queue);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE);
|
||||
#endif
|
||||
|
||||
tos_list_init(&msg_queue->queue_head);
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_queue_destroy(k_msg_queue_t *msg_queue)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(msg_queue);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
tos_msg_queue_flush(msg_queue);
|
||||
tos_list_init(&msg_queue->queue_head);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&msg_queue->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_queue_get(k_msg_queue_t *msg_queue, void **msg_addr, size_t *msg_size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_msg_t *msg;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_queue);
|
||||
TOS_PTR_SANITY_CHECK(msg_addr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
msg = TOS_LIST_FIRST_ENTRY_OR_NULL(&msg_queue->queue_head, k_msg_t, list);
|
||||
if (!msg) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_MSG_QUEUE_EMPTY;
|
||||
}
|
||||
|
||||
*msg_addr = msg->msg_addr;
|
||||
*msg_size = msg->msg_size;
|
||||
msgpool_free(msg);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_queue_put(k_msg_queue_t *msg_queue, void *msg_addr, size_t msg_size, k_opt_t opt)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_msg_t *msg;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_queue);
|
||||
TOS_PTR_SANITY_CHECK(msg_addr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
msg = msgpool_alloc();
|
||||
if (!msg) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_MSG_QUEUE_FULL;
|
||||
}
|
||||
|
||||
msg->msg_addr = msg_addr;
|
||||
msg->msg_size = msg_size;
|
||||
|
||||
if (opt & TOS_OPT_MSG_PUT_LIFO) {
|
||||
tos_list_add(&msg->list, &msg_queue->queue_head);
|
||||
} else {
|
||||
tos_list_add_tail(&msg->list, &msg_queue->queue_head);
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_msg_queue_remove(k_msg_queue_t *msg_queue, void *msg_addr)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_msg_t *msg;
|
||||
k_list_t *curr, *next;
|
||||
int is_msg_exist = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(msg_queue);
|
||||
TOS_PTR_SANITY_CHECK(msg_addr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &msg_queue->queue_head) {
|
||||
msg = TOS_LIST_ENTRY(curr, k_msg_t, list);
|
||||
|
||||
if (msg->msg_addr != msg_addr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
is_msg_exist = K_TRUE;
|
||||
msgpool_free(msg);
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_msg_exist ? K_ERR_NONE : K_ERR_MSG_QUEUE_MSG_NOT_EXIST;
|
||||
}
|
||||
|
||||
__API__ void tos_msg_queue_flush(k_msg_queue_t *msg_queue)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_list_t *curr, *next;
|
||||
|
||||
if(!msg_queue) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&msg_queue->knl_obj, KNL_OBJ_TYPE_MSG_QUEUE)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &msg_queue->queue_head) {
|
||||
msgpool_free(TOS_LIST_ENTRY(curr, k_msg_t, list));
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -73,7 +73,11 @@ __API__ k_err_t tos_mutex_create(k_mutex_t *mutex)
|
||||
|
||||
TOS_IN_IRQ_CHECK();
|
||||
|
||||
pend_object_init(&mutex->pend_obj, PEND_TYPE_MUTEX);
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&mutex->knl_obj, KNL_OBJ_TYPE_MUTEX);
|
||||
#endif
|
||||
|
||||
pend_object_init(&mutex->pend_obj);
|
||||
mutex->pend_nesting = (k_nesting_t)0u;
|
||||
mutex->owner = K_NULL;
|
||||
mutex->owner_orig_prio = K_TASK_PRIO_INVALID;
|
||||
@@ -88,12 +92,7 @@ __API__ k_err_t tos_mutex_destroy(k_mutex_t *mutex)
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mutex);
|
||||
TOS_IN_IRQ_CHECK();
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&mutex->pend_obj, PEND_TYPE_MUTEX)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(mutex, KNL_OBJ_TYPE_MUTEX);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -101,12 +100,16 @@ __API__ k_err_t tos_mutex_destroy(k_mutex_t *mutex)
|
||||
pend_wakeup_all(&mutex->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&mutex->pend_obj);
|
||||
|
||||
if (mutex->owner) {
|
||||
mutex_old_owner_release(mutex);
|
||||
}
|
||||
|
||||
pend_object_deinit(&mutex->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&mutex->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
@@ -119,12 +122,7 @@ __API__ k_err_t tos_mutex_pend_timed(k_mutex_t *mutex, k_tick_t timeout)
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mutex);
|
||||
TOS_IN_IRQ_CHECK();
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&mutex->pend_obj, PEND_TYPE_MUTEX)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(mutex, KNL_OBJ_TYPE_MUTEX);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
if (mutex->pend_nesting == (k_nesting_t)0u) { // first come
|
||||
@@ -180,12 +178,7 @@ __API__ k_err_t tos_mutex_post(k_mutex_t *mutex)
|
||||
|
||||
TOS_PTR_SANITY_CHECK(mutex);
|
||||
TOS_IN_IRQ_CHECK();
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&mutex->pend_obj, PEND_TYPE_MUTEX)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(mutex, KNL_OBJ_TYPE_MUTEX);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
if (!knl_is_self(mutex->owner)) {
|
||||
|
@@ -61,15 +61,13 @@ __KERNEL__ void pend_list_remove(k_task_t *task)
|
||||
task_state_reset_pending(task);
|
||||
}
|
||||
|
||||
__KERNEL__ void pend_object_init(pend_obj_t *object, pend_type_t type)
|
||||
__KERNEL__ void pend_object_init(pend_obj_t *object)
|
||||
{
|
||||
object->type = type;
|
||||
tos_list_init(&object->list);
|
||||
}
|
||||
|
||||
__KERNEL__ void pend_object_deinit(pend_obj_t *object)
|
||||
{
|
||||
object->type = PEND_TYPE_NONE;
|
||||
tos_list_init(&object->list);
|
||||
}
|
||||
|
||||
@@ -86,11 +84,6 @@ __KERNEL__ void pend_list_adjust(k_task_t *task)
|
||||
pend_list_add(task, task->pending_obj);
|
||||
}
|
||||
|
||||
__KERNEL__ int pend_object_verify(pend_obj_t *object, pend_type_t type)
|
||||
{
|
||||
return object->type == type;
|
||||
}
|
||||
|
||||
__KERNEL__ k_err_t pend_state2errno(pend_state_t state)
|
||||
{
|
||||
if (state == PEND_STATE_POST) {
|
||||
|
255
kernel/core/tos_priority_mail_queue.c
Normal file
255
kernel/core/tos_priority_mail_queue.c
Normal file
@@ -0,0 +1,255 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
#if TOS_CFG_PRIORITY_MAIL_QUEUE_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_create(k_prio_mail_q_t *prio_mail_q, void *pool, size_t mail_cnt, size_t mail_size)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
k_err_t err;
|
||||
void *prio_q_mgr_array = K_NULL;
|
||||
|
||||
prio_q_mgr_array = tos_mmheap_alloc(TOS_PRIO_Q_MGR_ARRAY_SIZE(mail_cnt));
|
||||
if (!prio_q_mgr_array) {
|
||||
return K_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
err = tos_prio_q_create(&prio_mail_q->prio_q, prio_q_mgr_array, pool, mail_cnt, mail_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
tos_mmheap_free(prio_q_mgr_array);
|
||||
return err;
|
||||
}
|
||||
|
||||
prio_mail_q->prio_q_mgr_array = prio_q_mgr_array;
|
||||
pend_object_init(&prio_mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&prio_mail_q->knl_obj, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_static(&prio_mail_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_destroy(k_prio_mail_q_t *prio_mail_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_static(&prio_mail_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_prio_q_destroy(&prio_mail_q->prio_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&prio_mail_q->pend_obj)) {
|
||||
pend_wakeup_all(&prio_mail_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
tos_mmheap_free(prio_mail_q->prio_q_mgr_array);
|
||||
prio_mail_q->prio_q_mgr_array = K_NULL;
|
||||
|
||||
pend_object_deinit(&prio_mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&prio_mail_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&prio_mail_q->knl_obj);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_create_dyn(k_prio_mail_q_t *prio_mail_q, size_t mail_cnt, size_t mail_size)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
k_err_t err;
|
||||
|
||||
err = tos_prio_q_create_dyn(&prio_mail_q->prio_q, mail_cnt, mail_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pend_object_init(&prio_mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&prio_mail_q->knl_obj, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&prio_mail_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_destroy_dyn(k_prio_mail_q_t *prio_mail_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&prio_mail_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_prio_q_destroy_dyn(&prio_mail_q->prio_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&prio_mail_q->pend_obj)) {
|
||||
pend_wakeup_all(&prio_mail_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&prio_mail_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&prio_mail_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&prio_mail_q->knl_obj);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_flush(k_prio_mail_q_t *prio_mail_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
|
||||
return tos_prio_q_flush(&prio_mail_q->prio_q);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_pend(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t *mail_size, k_tick_t timeout)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
TOS_PTR_SANITY_CHECK(mail_buf);
|
||||
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_prio_q_dequeue(&prio_mail_q->prio_q, mail_buf, mail_size, K_NULL) == K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (timeout == TOS_TIME_NOWAIT) {
|
||||
*mail_size = 0;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_NOWAIT;
|
||||
}
|
||||
|
||||
if (knl_is_sched_locked()) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
pend_task_block(k_curr_task, &prio_mail_q->pend_obj, timeout);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
err = pend_state2errno(k_curr_task->pend_state);
|
||||
|
||||
if (err == K_ERR_NONE) {
|
||||
memcpy(mail_buf, k_curr_task->mail, k_curr_task->mail_size);
|
||||
*mail_size = k_curr_task->mail_size;
|
||||
k_curr_task->mail = K_NULL;
|
||||
k_curr_task->mail_size = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_mail_task_recv(k_task_t *task, void *mail_buf, size_t mail_size)
|
||||
{
|
||||
task->mail = mail_buf;
|
||||
task->mail_size = mail_size;
|
||||
pend_task_wakeup(task, PEND_STATE_POST);
|
||||
}
|
||||
|
||||
__STATIC__ k_err_t prio_mail_q_do_post(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t mail_size, k_prio_t prio, opt_post_t opt)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_mail_q);
|
||||
TOS_PTR_SANITY_CHECK(mail_buf);
|
||||
TOS_OBJ_VERIFY(prio_mail_q, KNL_OBJ_TYPE_PRIORITY_MAIL_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (pend_is_nopending(&prio_mail_q->pend_obj)) {
|
||||
err = tos_prio_q_enqueue(&prio_mail_q->prio_q, mail_buf, mail_size, prio);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (opt == OPT_POST_ONE) {
|
||||
prio_mail_task_recv(TOS_LIST_FIRST_ENTRY(&prio_mail_q->pend_obj.list, k_task_t, pend_list),
|
||||
mail_buf, mail_size);
|
||||
} else { // OPT_POST_ALL
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &prio_mail_q->pend_obj.list) {
|
||||
prio_mail_task_recv(TOS_LIST_ENTRY(curr, k_task_t, pend_list),
|
||||
mail_buf, mail_size);
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_post(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t mail_size, k_prio_t prio)
|
||||
{
|
||||
return prio_mail_q_do_post(prio_mail_q, mail_buf, mail_size, prio, OPT_POST_ONE);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_mail_q_post_all(k_prio_mail_q_t *prio_mail_q, void *mail_buf, size_t mail_size, k_prio_t prio)
|
||||
{
|
||||
return prio_mail_q_do_post(prio_mail_q, mail_buf, mail_size, prio, OPT_POST_ALL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
252
kernel/core/tos_priority_message_queue.c
Normal file
252
kernel/core/tos_priority_message_queue.c
Normal file
@@ -0,0 +1,252 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
#if TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_create(k_prio_msg_q_t *prio_msg_q, void *pool, size_t msg_cnt)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
k_err_t err;
|
||||
void *prio_q_mgr_array = K_NULL;
|
||||
|
||||
prio_q_mgr_array = tos_mmheap_alloc(TOS_PRIO_Q_MGR_ARRAY_SIZE(msg_cnt));
|
||||
if (!prio_q_mgr_array) {
|
||||
return K_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
err = tos_prio_q_create(&prio_msg_q->prio_q, prio_q_mgr_array, pool, msg_cnt, sizeof(void *));
|
||||
if (err != K_ERR_NONE) {
|
||||
tos_mmheap_free(prio_q_mgr_array);
|
||||
return err;
|
||||
}
|
||||
|
||||
prio_msg_q->prio_q_mgr_array = prio_q_mgr_array;
|
||||
pend_object_init(&prio_msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&prio_msg_q->knl_obj, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_static(&prio_msg_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_destroy(k_prio_msg_q_t *prio_msg_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_static(&prio_msg_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_prio_q_destroy(&prio_msg_q->prio_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&prio_msg_q->pend_obj)) {
|
||||
pend_wakeup_all(&prio_msg_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
tos_mmheap_free(prio_msg_q->prio_q_mgr_array);
|
||||
prio_msg_q->prio_q_mgr_array = K_NULL;
|
||||
|
||||
pend_object_deinit(&prio_msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&prio_msg_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&prio_msg_q->knl_obj);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_create_dyn(k_prio_msg_q_t *prio_msg_q, size_t msg_cnt)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
k_err_t err;
|
||||
|
||||
err = tos_prio_q_create_dyn(&prio_msg_q->prio_q, msg_cnt, sizeof(void *));
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pend_object_init(&prio_msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&prio_msg_q->knl_obj, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&prio_msg_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_destroy_dyn(k_prio_msg_q_t *prio_msg_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&prio_msg_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
err = tos_prio_q_destroy_dyn(&prio_msg_q->prio_q);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pend_is_nopending(&prio_msg_q->pend_obj)) {
|
||||
pend_wakeup_all(&prio_msg_q->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
tos_mmheap_free(prio_msg_q->prio_q_mgr_array);
|
||||
prio_msg_q->prio_q_mgr_array = K_NULL;
|
||||
|
||||
pend_object_deinit(&prio_msg_q->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&prio_msg_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&prio_msg_q->knl_obj);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_flush(k_prio_msg_q_t *prio_msg_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
|
||||
return tos_prio_q_flush(&prio_msg_q->prio_q);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_pend(k_prio_msg_q_t *prio_msg_q, void **msg_ptr, k_tick_t timeout)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
TOS_PTR_SANITY_CHECK(msg_ptr);
|
||||
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_prio_q_dequeue(&prio_msg_q->prio_q, msg_ptr, K_NULL, K_NULL) == K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (timeout == TOS_TIME_NOWAIT) {
|
||||
*msg_ptr = K_NULL;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_NOWAIT;
|
||||
}
|
||||
|
||||
if (knl_is_sched_locked()) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
pend_task_block(k_curr_task, &prio_msg_q->pend_obj, timeout);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
err = pend_state2errno(k_curr_task->pend_state);
|
||||
|
||||
if (err == K_ERR_NONE) {
|
||||
*msg_ptr = k_curr_task->msg;
|
||||
k_curr_task->msg = K_NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_msg_q_task_recv(k_task_t *task, void *msg_ptr)
|
||||
{
|
||||
task->msg = msg_ptr;
|
||||
pend_task_wakeup(task, PEND_STATE_POST);
|
||||
}
|
||||
|
||||
__STATIC__ k_err_t prio_msg_q_do_post(k_prio_msg_q_t *prio_msg_q, void *msg_ptr, k_prio_t prio, opt_post_t opt)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_msg_q);
|
||||
TOS_OBJ_VERIFY(prio_msg_q, KNL_OBJ_TYPE_PRIORITY_MESSAGE_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (pend_is_nopending(&prio_msg_q->pend_obj)) {
|
||||
err = tos_prio_q_enqueue(&prio_msg_q->prio_q, &msg_ptr, sizeof(void *), prio);
|
||||
if (err != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return err;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (opt == OPT_POST_ONE) {
|
||||
prio_msg_q_task_recv(TOS_LIST_FIRST_ENTRY(&prio_msg_q->pend_obj.list, k_task_t, pend_list), msg_ptr);
|
||||
} else { // OPT_POST_ALL
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &prio_msg_q->pend_obj.list) {
|
||||
prio_msg_q_task_recv(TOS_LIST_ENTRY(curr, k_task_t, pend_list), msg_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_post(k_prio_msg_q_t *prio_msg_q, void *msg_ptr, k_prio_t prio)
|
||||
{
|
||||
return prio_msg_q_do_post(prio_msg_q, msg_ptr, prio, OPT_POST_ONE);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_msg_q_post_all(k_prio_msg_q_t *prio_msg_q, void *msg_ptr, k_prio_t prio)
|
||||
{
|
||||
return prio_msg_q_do_post(prio_msg_q, msg_ptr, prio, OPT_POST_ALL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
393
kernel/core/tos_priority_queue.c
Normal file
393
kernel/core/tos_priority_queue.c
Normal file
@@ -0,0 +1,393 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
__STATIC_INLINE__ void prio_q_item_copy_to(k_prio_q_t *prio_q, void *item_out, size_t *item_size, prio_q_slot_t slot)
|
||||
{
|
||||
memcpy(item_out, PRIO_Q_THE_ITEM(prio_q, slot), prio_q->item_size);
|
||||
if (item_size) {
|
||||
*item_size = prio_q->item_size;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void prio_q_item_copy_from(k_prio_q_t *prio_q, void *item_in, prio_q_slot_t slot)
|
||||
{
|
||||
memcpy(PRIO_Q_THE_ITEM(prio_q, slot), item_in, prio_q->item_size);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void prio_q_item_increase(k_prio_q_t *prio_q)
|
||||
{
|
||||
++prio_q->total;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void prio_q_item_decrease(k_prio_q_t *prio_q)
|
||||
{
|
||||
--prio_q->total;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_pool_mgr_init(prio_q_pool_mgr_t *pool_mgr, prio_q_pool_mgr_ent_t *pool_mgr_ent_array, size_t item_cnt)
|
||||
{
|
||||
prio_q_slot_t i;
|
||||
|
||||
pool_mgr->first_free = (prio_q_slot_t)0u;
|
||||
pool_mgr->pool_mgr_ent_array = pool_mgr_ent_array;
|
||||
|
||||
for (i = 0; i < item_cnt; ++i) {
|
||||
pool_mgr_ent_array[i].next = i + 1;
|
||||
}
|
||||
pool_mgr_ent_array[item_cnt - 1].next = PRIO_Q_POOL_SLOT_INVALID;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_pool_mgr_reset(prio_q_pool_mgr_t *pool_mgr, size_t item_cnt)
|
||||
{
|
||||
prio_q_slot_t i;
|
||||
prio_q_pool_mgr_ent_t *pool_mgr_ent_array;
|
||||
|
||||
pool_mgr->first_free = (prio_q_slot_t)0u;
|
||||
pool_mgr_ent_array = pool_mgr->pool_mgr_ent_array;
|
||||
|
||||
for (i = 0; i < item_cnt; ++i) {
|
||||
pool_mgr_ent_array[i].next = i + 1;
|
||||
}
|
||||
pool_mgr_ent_array[item_cnt - 1].next = PRIO_Q_POOL_SLOT_INVALID;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_pool_mgr_deinit(prio_q_pool_mgr_t *pool_mgr)
|
||||
{
|
||||
pool_mgr->first_free = (prio_q_slot_t)0u;
|
||||
pool_mgr->pool_mgr_ent_array = K_NULL;
|
||||
}
|
||||
|
||||
__STATIC__ int prio_q_mgr_entry_cmp(void *first, void *second)
|
||||
{
|
||||
prio_q_prio_mgr_ent_t *first_entry, *second_entry;
|
||||
|
||||
first_entry = (prio_q_prio_mgr_ent_t *)first;
|
||||
second_entry = (prio_q_prio_mgr_ent_t *)second;
|
||||
|
||||
// numerically bigger, actually smaller, we build a minimal binary heap here
|
||||
if (first_entry->priority < second_entry->priority) {
|
||||
return K_TRUE;
|
||||
}
|
||||
return K_FALSE;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_prio_mgr_init(prio_q_prio_mgr_t *prio_mgr, prio_q_prio_mgr_ent_t *prio_mgr_ent_pool, size_t item_cnt)
|
||||
{
|
||||
prio_mgr->prio_mgr_ent_pool = prio_mgr_ent_pool;
|
||||
tos_bin_heap_create(&prio_mgr->prio_mgr_bin_heap, prio_mgr_ent_pool, item_cnt, sizeof(prio_q_prio_mgr_ent_t), prio_q_mgr_entry_cmp);
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_prio_mgr_reset(prio_q_prio_mgr_t *prio_mgr)
|
||||
{
|
||||
tos_bin_heap_flush(&prio_mgr->prio_mgr_bin_heap);
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_prio_mgr_deinit(prio_q_prio_mgr_t *prio_mgr)
|
||||
{
|
||||
prio_mgr->prio_mgr_ent_pool = K_NULL;
|
||||
tos_bin_heap_destroy(&prio_mgr->prio_mgr_bin_heap);
|
||||
}
|
||||
|
||||
__STATIC__ prio_q_slot_t prio_q_pool_mgr_slot_alloc(prio_q_pool_mgr_t *pool_mgr)
|
||||
{
|
||||
prio_q_slot_t fresh;
|
||||
prio_q_pool_mgr_ent_t *first_free;
|
||||
|
||||
if (pool_mgr->first_free == PRIO_Q_POOL_SLOT_INVALID) {
|
||||
return PRIO_Q_POOL_SLOT_INVALID;
|
||||
}
|
||||
|
||||
fresh = pool_mgr->first_free;
|
||||
first_free = &pool_mgr->pool_mgr_ent_array[pool_mgr->first_free];
|
||||
pool_mgr->first_free = first_free->next;
|
||||
|
||||
return fresh;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_pool_mgr_slot_free(prio_q_pool_mgr_t *pool_mgr, prio_q_slot_t slot)
|
||||
{
|
||||
prio_q_pool_mgr_ent_t *slot_entry;
|
||||
|
||||
slot_entry = &pool_mgr->pool_mgr_ent_array[slot];
|
||||
slot_entry->next = pool_mgr->first_free;
|
||||
pool_mgr->first_free = slot;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_prio_mgr_slot_enqueue(prio_q_prio_mgr_t *prio_mgr, prio_q_slot_t slot, k_prio_t prio)
|
||||
{
|
||||
k_err_t err;
|
||||
prio_q_prio_mgr_ent_t prio_mgr_entry;
|
||||
|
||||
prio_mgr_entry.priority = prio;
|
||||
prio_mgr_entry.slot = slot;
|
||||
|
||||
err = tos_bin_heap_push(&prio_mgr->prio_mgr_bin_heap, &prio_mgr_entry, sizeof(prio_q_prio_mgr_ent_t));
|
||||
TOS_ASSERT(err == K_ERR_NONE);
|
||||
}
|
||||
|
||||
__STATIC__ prio_q_slot_t prio_q_prio_mgr_slot_dequeue(prio_q_prio_mgr_t *prio_mgr, k_prio_t *prio)
|
||||
{
|
||||
k_err_t err;
|
||||
size_t dummy;
|
||||
prio_q_prio_mgr_ent_t prio_mgr_entry;
|
||||
|
||||
err = tos_bin_heap_pop(&prio_mgr->prio_mgr_bin_heap, &prio_mgr_entry, &dummy);
|
||||
TOS_ASSERT(err == K_ERR_NONE);
|
||||
TOS_ASSERT(dummy == sizeof(prio_q_prio_mgr_ent_t));
|
||||
|
||||
if (prio) {
|
||||
*prio = prio_mgr_entry.priority;
|
||||
}
|
||||
|
||||
return prio_mgr_entry.slot;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_q_create(k_prio_q_t *prio_q, void *mgr_array, void *pool, size_t item_cnt, size_t item_size)
|
||||
{
|
||||
prio_q_pool_mgr_ent_t *pool_mgr_ent_array;
|
||||
prio_q_prio_mgr_ent_t *prio_mgr_ent_pool;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
TOS_PTR_SANITY_CHECK(mgr_array);
|
||||
TOS_PTR_SANITY_CHECK(pool);
|
||||
|
||||
pool_mgr_ent_array = (prio_q_pool_mgr_ent_t *)mgr_array;
|
||||
prio_mgr_ent_pool = (prio_q_prio_mgr_ent_t *)((uint8_t *)mgr_array + PRIO_Q_POOL_MGR_ENT_ARRAY_SIZE(item_cnt));
|
||||
|
||||
prio_q_pool_mgr_init(&prio_q->pool_mgr, pool_mgr_ent_array, item_cnt);
|
||||
prio_q_prio_mgr_init(&prio_q->prio_mgr, prio_mgr_ent_pool, item_cnt);
|
||||
|
||||
prio_q->total = 0;
|
||||
prio_q->item_size = item_size;
|
||||
prio_q->item_cnt = item_cnt;
|
||||
prio_q->mgr_pool = (uint8_t *)mgr_array;
|
||||
prio_q->data_pool = (uint8_t *)pool;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&prio_q->knl_obj, KNL_OBJ_TYPE_PRIORITY_QUEUE);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_set_static(&prio_q->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_q_destroy(k_prio_q_t *prio_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
if (!knl_object_alloc_is_static(&prio_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
prio_q_pool_mgr_deinit(&prio_q->pool_mgr);
|
||||
prio_q_prio_mgr_deinit(&prio_q->prio_mgr);
|
||||
|
||||
prio_q->total = 0;
|
||||
prio_q->item_size = 0;
|
||||
prio_q->item_cnt = 0;
|
||||
prio_q->mgr_pool = K_NULL;
|
||||
prio_q->data_pool = K_NULL;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&prio_q->knl_obj);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_reset(&prio_q->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_prio_q_create_dyn(k_prio_q_t *prio_q, size_t item_cnt, size_t item_size)
|
||||
{
|
||||
k_err_t err;
|
||||
void *mgr_pool, *data_pool;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
|
||||
mgr_pool = tos_mmheap_alloc(TOS_PRIO_Q_MGR_ARRAY_SIZE(item_cnt));
|
||||
if (!mgr_pool) {
|
||||
return K_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
data_pool = tos_mmheap_alloc(item_cnt * item_size);
|
||||
if (!data_pool) {
|
||||
tos_mmheap_free(mgr_pool);
|
||||
return K_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
err = tos_prio_q_create(prio_q, mgr_pool, data_pool, item_cnt, item_size);
|
||||
if (err != K_ERR_NONE) {
|
||||
tos_mmheap_free(data_pool);
|
||||
tos_mmheap_free(mgr_pool);
|
||||
}
|
||||
|
||||
knl_object_alloc_set_dynamic(&prio_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_q_destroy_dyn(k_prio_q_t *prio_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&prio_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
prio_q_pool_mgr_deinit(&prio_q->pool_mgr);
|
||||
prio_q_prio_mgr_deinit(&prio_q->prio_mgr);
|
||||
|
||||
tos_mmheap_free(prio_q->mgr_pool);
|
||||
tos_mmheap_free(prio_q->data_pool);
|
||||
|
||||
prio_q->total = 0;
|
||||
prio_q->item_size = 0;
|
||||
prio_q->item_cnt = 0;
|
||||
prio_q->mgr_pool = K_NULL;
|
||||
prio_q->data_pool = K_NULL;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&prio_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&prio_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__STATIC__ void prio_q_do_enqueue(k_prio_q_t *prio_q, void *item, prio_q_slot_t slot, k_prio_t prio)
|
||||
{
|
||||
prio_q_item_copy_from(prio_q, item, slot);
|
||||
prio_q_prio_mgr_slot_enqueue(&prio_q->prio_mgr, slot, prio);
|
||||
prio_q_item_increase(prio_q);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_q_enqueue(k_prio_q_t *prio_q, void *item, size_t item_size, k_prio_t prio)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
prio_q_slot_t the_slot;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
TOS_PTR_SANITY_CHECK(item);
|
||||
TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE);
|
||||
|
||||
if (item_size != prio_q->item_size) {
|
||||
return K_ERR_PRIO_Q_ITEM_SIZE_NOT_MATCH;
|
||||
}
|
||||
|
||||
if (tos_prio_q_is_full(prio_q)) {
|
||||
return K_ERR_PRIO_Q_FULL;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
the_slot = prio_q_pool_mgr_slot_alloc(&prio_q->pool_mgr);
|
||||
TOS_ASSERT(the_slot != PRIO_Q_POOL_SLOT_INVALID);
|
||||
prio_q_do_enqueue(prio_q, item, the_slot, prio);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__STATIC__ void prio_q_do_dequeue(k_prio_q_t *prio_q, void *item, size_t *item_size, prio_q_slot_t slot)
|
||||
{
|
||||
prio_q_pool_mgr_slot_free(&prio_q->pool_mgr, slot);
|
||||
prio_q_item_copy_to(prio_q, item, item_size, slot);
|
||||
prio_q_item_decrease(prio_q);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_q_dequeue(k_prio_q_t *prio_q, void *item, size_t *item_size, k_prio_t *prio)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
prio_q_slot_t the_slot;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
TOS_PTR_SANITY_CHECK(item);
|
||||
TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE);
|
||||
|
||||
if (tos_prio_q_is_empty(prio_q)) {
|
||||
return K_ERR_PRIO_Q_EMPTY;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
the_slot = prio_q_prio_mgr_slot_dequeue(&prio_q->prio_mgr, prio);
|
||||
prio_q_do_dequeue(prio_q, item, item_size, the_slot);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_prio_q_flush(k_prio_q_t *prio_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(prio_q);
|
||||
TOS_OBJ_VERIFY(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
prio_q_pool_mgr_reset(&prio_q->pool_mgr, prio_q->item_cnt);
|
||||
prio_q_prio_mgr_reset(&prio_q->prio_mgr);
|
||||
prio_q->total = 0;
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ int tos_prio_q_is_empty(k_prio_q_t *prio_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_empty = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(prio_q, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_empty = (prio_q->total == 0);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
__API__ int tos_prio_q_is_full(k_prio_q_t *prio_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_full = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(prio_q, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(prio_q, KNL_OBJ_TYPE_PRIORITY_QUEUE, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_full = (prio_q->total == prio_q->item_cnt);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_full;
|
||||
}
|
||||
|
@@ -1,213 +0,0 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
#if TOS_CFG_QUEUE_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_queue_create(k_queue_t *queue)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(queue);
|
||||
|
||||
pend_object_init(&queue->pend_obj, PEND_TYPE_QUEUE);
|
||||
tos_msg_queue_create(&queue->msg_queue);
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_queue_destroy(k_queue_t *queue)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(queue);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&queue->pend_obj, PEND_TYPE_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (!pend_is_nopending(&queue->pend_obj)) {
|
||||
pend_wakeup_all(&queue->pend_obj, PEND_STATE_DESTROY);
|
||||
}
|
||||
|
||||
pend_object_deinit(&queue->pend_obj);
|
||||
tos_msg_queue_flush(&queue->msg_queue);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_queue_pend(k_queue_t *queue, void **msg_addr, size_t *msg_size, k_tick_t timeout)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(queue);
|
||||
TOS_PTR_SANITY_CHECK(msg_addr);
|
||||
TOS_PTR_SANITY_CHECK(msg_size);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&queue->pend_obj, PEND_TYPE_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_msg_queue_get(&queue->msg_queue, msg_addr, msg_size) == K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (timeout == TOS_TIME_NOWAIT) {
|
||||
*msg_addr = K_NULL;
|
||||
*msg_size = 0;
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_NOWAIT;
|
||||
}
|
||||
|
||||
if (knl_is_inirq()) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_IN_IRQ;
|
||||
}
|
||||
|
||||
if (knl_is_sched_locked()) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_PEND_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
pend_task_block(k_curr_task, &queue->pend_obj, timeout);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
err = pend_state2errno(k_curr_task->pend_state);
|
||||
|
||||
if (err == K_ERR_NONE) {
|
||||
*msg_addr = k_curr_task->msg_addr;
|
||||
*msg_size = k_curr_task->msg_size;
|
||||
k_curr_task->msg_addr = K_NULL;
|
||||
k_curr_task->msg_size = 0;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
__STATIC__ void queue_task_msg_recv(k_task_t *task, void *msg_addr, size_t msg_size)
|
||||
{
|
||||
task->msg_addr = msg_addr;
|
||||
task->msg_size = msg_size;
|
||||
pend_task_wakeup(task, PEND_STATE_POST);
|
||||
}
|
||||
|
||||
__STATIC__ k_err_t queue_do_post(k_queue_t *queue, void *msg_addr, size_t msg_size, opt_post_t opt)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_list_t *curr, *next;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(queue);
|
||||
TOS_PTR_SANITY_CHECK(msg_addr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&queue->pend_obj, PEND_TYPE_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (pend_is_nopending(&queue->pend_obj)) {
|
||||
if (tos_msg_queue_put(&queue->msg_queue, msg_addr, msg_size, TOS_OPT_MSG_PUT_FIFO) != K_ERR_NONE) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_QUEUE_FULL;
|
||||
}
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
if (opt == OPT_POST_ONE) {
|
||||
queue_task_msg_recv(TOS_LIST_FIRST_ENTRY(&queue->pend_obj.list, k_task_t, pend_list),
|
||||
msg_addr, msg_size);
|
||||
} else { // OPT_QUEUE_POST_ALL
|
||||
TOS_LIST_FOR_EACH_SAFE(curr, next, &queue->pend_obj.list) {
|
||||
queue_task_msg_recv(TOS_LIST_ENTRY(curr, k_task_t, pend_list),
|
||||
msg_addr, msg_size);
|
||||
}
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_queue_post(k_queue_t *queue, void *msg_addr, size_t msg_size)
|
||||
{
|
||||
return queue_do_post(queue, msg_addr, msg_size, OPT_POST_ONE);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_queue_post_all(k_queue_t *queue, void *msg_addr, size_t msg_size)
|
||||
{
|
||||
return queue_do_post(queue, msg_addr, msg_size, OPT_POST_ALL);
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_queue_remove(k_queue_t *queue, void *msg_addr)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
k_err_t err;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(queue);
|
||||
TOS_PTR_SANITY_CHECK(msg_addr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&queue->pend_obj, PEND_TYPE_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
err = tos_msg_queue_remove(&queue->msg_queue, msg_addr);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return err == K_ERR_MSG_QUEUE_MSG_NOT_EXIST ? K_ERR_QUEUE_MSG_NOT_EXIST : K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_queue_flush(k_queue_t *queue)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(queue);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&queue->pend_obj, PEND_TYPE_QUEUE)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
tos_msg_queue_flush(&queue->msg_queue);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
251
kernel/core/tos_ring_queue.c
Normal file
251
kernel/core/tos_ring_queue.c
Normal file
@@ -0,0 +1,251 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* Tencent is pleased to support the open source community by making TencentOS
|
||||
* available.
|
||||
*
|
||||
* Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
|
||||
* If you have downloaded a copy of the TencentOS binary from Tencent, please
|
||||
* note that the TencentOS binary is licensed under the BSD 3-Clause License.
|
||||
*
|
||||
* If you have downloaded a copy of the TencentOS source code from Tencent,
|
||||
* please note that TencentOS source code is licensed under the BSD 3-Clause
|
||||
* License, except for the third-party components listed below which are
|
||||
* subject to different license terms. Your integration of TencentOS into your
|
||||
* own projects may require compliance with the BSD 3-Clause License, as well
|
||||
* as the other licenses applicable to the third-party components included
|
||||
* within TencentOS.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "tos.h"
|
||||
|
||||
__STATIC_INLINE__ void ring_q_item_copy_to(k_ring_q_t *ring_q, void *item_out, size_t *item_size)
|
||||
{
|
||||
memcpy(item_out, RING_HEAD_ITEM(ring_q), ring_q->item_size);
|
||||
if (item_size) {
|
||||
*item_size = ring_q->item_size;
|
||||
}
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void ring_q_item_copy_from(k_ring_q_t *ring_q, void *item_in)
|
||||
{
|
||||
memcpy(RING_TAIL_ITEM(ring_q), item_in, ring_q->item_size);
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void ring_q_item_increase(k_ring_q_t *ring_q)
|
||||
{
|
||||
ring_q->tail = RING_NEXT(ring_q, ring_q->tail);
|
||||
++ring_q->total;
|
||||
}
|
||||
|
||||
__STATIC_INLINE__ void ring_q_item_decrease(k_ring_q_t *ring_q)
|
||||
{
|
||||
ring_q->head = RING_NEXT(ring_q, ring_q->head);
|
||||
--ring_q->total;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_ring_q_create(k_ring_q_t *ring_q, void *pool, size_t item_cnt, size_t item_size)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
TOS_PTR_SANITY_CHECK(pool);
|
||||
|
||||
ring_q->head = 0u;
|
||||
ring_q->tail = 0u;
|
||||
ring_q->total = 0;
|
||||
|
||||
ring_q->pool = (uint8_t *)pool;
|
||||
ring_q->item_size = item_size;
|
||||
ring_q->item_cnt = item_cnt;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&ring_q->knl_obj, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_set_static(&ring_q->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_ring_q_destroy(k_ring_q_t *ring_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
if (!knl_object_alloc_is_static(&ring_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ring_q->head = 0u;
|
||||
ring_q->tail = 0u;
|
||||
ring_q->total = 0;
|
||||
|
||||
ring_q->pool = K_NULL;
|
||||
ring_q->item_size = 0u;
|
||||
ring_q->item_cnt = 0u;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&ring_q->knl_obj);
|
||||
#endif
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
knl_object_alloc_reset(&ring_q->knl_obj);
|
||||
#endif
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__API__ k_err_t tos_ring_q_create_dyn(k_ring_q_t *ring_q, size_t item_cnt, size_t item_size)
|
||||
{
|
||||
void *pool;
|
||||
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
|
||||
pool = tos_mmheap_alloc(item_cnt * item_size);
|
||||
if (!pool) {
|
||||
return K_ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
ring_q->head = 0u;
|
||||
ring_q->tail = 0u;
|
||||
ring_q->total = 0;
|
||||
|
||||
ring_q->pool = (uint8_t *)pool;
|
||||
ring_q->item_size = item_size;
|
||||
ring_q->item_cnt = item_cnt;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&ring_q->knl_obj, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
#endif
|
||||
knl_object_alloc_set_dynamic(&ring_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_ring_q_destroy_dyn(k_ring_q_t *ring_q)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&ring_q->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
tos_mmheap_free(ring_q->pool);
|
||||
|
||||
ring_q->head = 0u;
|
||||
ring_q->tail = 0u;
|
||||
ring_q->total = 0;
|
||||
|
||||
ring_q->pool = K_NULL;
|
||||
ring_q->item_size = 0u;
|
||||
ring_q->item_cnt = 0u;
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&ring_q->knl_obj);
|
||||
#endif
|
||||
knl_object_alloc_reset(&ring_q->knl_obj);
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ k_err_t tos_ring_q_enqueue(k_ring_q_t *ring_q, void *item, size_t item_size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
TOS_PTR_SANITY_CHECK(item);
|
||||
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
|
||||
if (item_size != ring_q->item_size) {
|
||||
return K_ERR_RING_Q_ITEM_SIZE_NOT_MATCH;
|
||||
}
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_ring_q_is_full(ring_q)) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_RING_Q_FULL;
|
||||
}
|
||||
|
||||
ring_q_item_copy_from(ring_q, item);
|
||||
ring_q_item_increase(ring_q);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_ring_q_dequeue(k_ring_q_t *ring_q, void *item, size_t *item_size)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
TOS_PTR_SANITY_CHECK(item);
|
||||
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (tos_ring_q_is_empty(ring_q)) {
|
||||
TOS_CPU_INT_ENABLE();
|
||||
return K_ERR_RING_Q_EMPTY;
|
||||
}
|
||||
|
||||
ring_q_item_copy_to(ring_q, item, item_size);
|
||||
ring_q_item_decrease(ring_q);
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ k_err_t tos_ring_q_flush(k_ring_q_t *ring_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(ring_q);
|
||||
TOS_OBJ_VERIFY(ring_q, KNL_OBJ_TYPE_RING_QUEUE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
ring_q->head = 0u;
|
||||
ring_q->tail = 0u;
|
||||
ring_q->total = 0;
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
__API__ int tos_ring_q_is_empty(k_ring_q_t *ring_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_empty = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(ring_q, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(ring_q, KNL_OBJ_TYPE_RING_QUEUE, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_empty = (ring_q->total == 0);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_empty;
|
||||
}
|
||||
|
||||
__API__ int tos_ring_q_is_full(k_ring_q_t *ring_q)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
int is_full = K_FALSE;
|
||||
|
||||
TOS_PTR_SANITY_CHECK_RC(ring_q, K_FALSE);
|
||||
TOS_OBJ_VERIFY_RC(ring_q, KNL_OBJ_TYPE_RING_QUEUE, K_FALSE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
is_full = (ring_q->total == ring_q->item_cnt);
|
||||
TOS_CPU_INT_ENABLE();
|
||||
|
||||
return is_full;
|
||||
}
|
||||
|
@@ -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,27 +19,32 @@
|
||||
|
||||
#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;
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_init(&sem->knl_obj, KNL_OBJ_TYPE_SEMAPHORE);
|
||||
#endif
|
||||
|
||||
pend_object_init(&sem->pend_obj);
|
||||
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();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(sem);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&sem->pend_obj, PEND_TYPE_SEM)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(sem, KNL_OBJ_TYPE_SEMAPHORE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
@@ -49,6 +54,10 @@ __API__ k_err_t tos_sem_destroy(k_sem_t *sem)
|
||||
|
||||
pend_object_deinit(&sem->pend_obj);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
knl_object_deinit(&sem->knl_obj);
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
knl_sched();
|
||||
|
||||
@@ -60,16 +69,11 @@ __STATIC__ k_err_t sem_do_post(k_sem_t *sem, opt_post_t opt)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(sem);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&sem->pend_obj, PEND_TYPE_SEM)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(sem, KNL_OBJ_TYPE_SEMAPHORE);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -103,12 +107,7 @@ __API__ k_err_t tos_sem_pend(k_sem_t *sem, k_tick_t timeout)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(sem);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!pend_object_verify(&sem->pend_obj, PEND_TYPE_SEM)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(sem, KNL_OBJ_TYPE_SEMAPHORE);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
|
@@ -36,10 +36,6 @@ __API__ k_err_t tos_knl_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (TOS_CFG_MSG_EN) > 0
|
||||
msgpool_init();
|
||||
#endif
|
||||
|
||||
err = knl_idle_init();
|
||||
if (err != K_ERR_NONE) {
|
||||
return err;
|
||||
@@ -202,22 +198,52 @@ __KERNEL__ k_tick_t knl_next_expires_get(void)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
__KERNEL__ int knl_object_verify(knl_obj_t *object, knl_obj_type_t type)
|
||||
|
||||
__KERNEL__ int knl_object_verify(knl_obj_t *knl_obj, knl_obj_type_t type)
|
||||
{
|
||||
return object->type == type;
|
||||
return knl_obj->type == type;
|
||||
}
|
||||
|
||||
__KERNEL__ int knl_object_init(knl_obj_t *object, knl_obj_type_t type)
|
||||
__KERNEL__ void knl_object_init(knl_obj_t *knl_obj, knl_obj_type_t type)
|
||||
{
|
||||
return object->type = type;
|
||||
knl_obj->type = type;
|
||||
}
|
||||
|
||||
__KERNEL__ int knl_object_deinit(knl_obj_t *object)
|
||||
__KERNEL__ void knl_object_deinit(knl_obj_t *knl_obj)
|
||||
{
|
||||
return object->type = KNL_OBJ_TYPE_NONE;
|
||||
knl_obj->type = KNL_OBJ_TYPE_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_MMHEAP_EN > 0u
|
||||
|
||||
__KERNEL__ void knl_object_alloc_reset(knl_obj_t *knl_obj)
|
||||
{
|
||||
knl_obj->alloc_type = KNL_OBJ_ALLOC_TYPE_NONE;
|
||||
}
|
||||
|
||||
__KERNEL__ void knl_object_alloc_set_dynamic(knl_obj_t *knl_obj)
|
||||
{
|
||||
knl_obj->alloc_type = KNL_OBJ_ALLOC_TYPE_DYNAMIC;
|
||||
}
|
||||
|
||||
__KERNEL__ void knl_object_alloc_set_static(knl_obj_t *knl_obj)
|
||||
{
|
||||
knl_obj->alloc_type = KNL_OBJ_ALLOC_TYPE_STATIC;
|
||||
}
|
||||
|
||||
__KERNEL__ int knl_object_alloc_is_dynamic(knl_obj_t *knl_obj)
|
||||
{
|
||||
return knl_obj->alloc_type == KNL_OBJ_ALLOC_TYPE_DYNAMIC;
|
||||
}
|
||||
|
||||
__KERNEL__ int knl_object_alloc_is_static(knl_obj_t *knl_obj)
|
||||
{
|
||||
return knl_obj->alloc_type == KNL_OBJ_ALLOC_TYPE_STATIC;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__KERNEL__ void knl_sched(void)
|
||||
@@ -268,6 +294,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,12 @@ __STATIC_INLINE__ void task_reset(k_task_t *task)
|
||||
knl_object_deinit(&task->knl_obj);
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
|
||||
knl_object_alloc_reset(&task->knl_obj);
|
||||
|
||||
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);
|
||||
|
||||
@@ -34,10 +40,15 @@ __STATIC_INLINE__ void task_reset(k_task_t *task)
|
||||
task->pend_state = PEND_STATE_NONE;
|
||||
task->pending_obj = (pend_obj_t *)K_NULL;
|
||||
|
||||
#if TOS_CFG_MSG_EN > 0u
|
||||
task->msg_addr = K_NULL;
|
||||
task->msg_size = 0;
|
||||
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
|
||||
task->msg = K_NULL;
|
||||
#endif
|
||||
|
||||
#if TOS_CFG_MAIL_QUEUE_EN > 0u
|
||||
task->mail = K_NULL;
|
||||
task->mail_size = 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
__STATIC__ void task_exit(void)
|
||||
@@ -102,10 +113,16 @@ __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
|
||||
|
||||
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
|
||||
knl_object_alloc_set_static(&task->knl_obj);
|
||||
#endif
|
||||
|
||||
task->sp = cpu_task_stk_init((void *)entry, arg, (void *)task_exit, stk_base, stk_size);
|
||||
task->entry = entry;
|
||||
task->arg = arg;
|
||||
@@ -136,30 +153,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 +180,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 +191,151 @@ __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;
|
||||
}
|
||||
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
|
||||
if (knl_is_self(task) && knl_is_sched_locked()) {
|
||||
return K_ERR_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN
|
||||
if (!knl_object_alloc_is_static(&task->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return task_do_destroy(task);
|
||||
}
|
||||
|
||||
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
|
||||
|
||||
__STATIC__ void task_free(k_task_t *task)
|
||||
{
|
||||
tos_mmheap_free(task->stk_base);
|
||||
tos_mmheap_free(task);
|
||||
}
|
||||
|
||||
__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);
|
||||
task_free(task);
|
||||
}
|
||||
|
||||
TOS_CPU_INT_ENABLE();
|
||||
}
|
||||
|
||||
__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;
|
||||
}
|
||||
|
||||
the_task->stk_base = stk_base;
|
||||
err = tos_task_create(the_task, name, entry, arg, prio, stk_base, stk_size, timeslice);
|
||||
if (err != K_ERR_NONE) {
|
||||
task_free(the_task);
|
||||
return err;
|
||||
}
|
||||
|
||||
knl_object_alloc_set_dynamic(&the_task->knl_obj);
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
|
||||
if (knl_is_self(task) && knl_is_sched_locked()) {
|
||||
return K_ERR_SCHED_LOCKED;
|
||||
}
|
||||
|
||||
if (!knl_object_alloc_is_dynamic(&task->knl_obj)) {
|
||||
return K_ERR_OBJ_INVALID_ALLOC_TYPE;
|
||||
}
|
||||
|
||||
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 {
|
||||
task_free(task);
|
||||
}
|
||||
|
||||
tos_knl_sched_unlock();
|
||||
|
||||
return K_ERR_NONE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
__API__ void tos_task_yield(void)
|
||||
{
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
@@ -213,14 +361,9 @@ __API__ k_err_t tos_task_prio_change(k_task_t *task, k_prio_t prio_new)
|
||||
#endif
|
||||
|
||||
TOS_PTR_SANITY_CHECK(task);
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
TOS_IN_IRQ_CHECK();
|
||||
|
||||
#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 (unlikely(prio_new >= K_TASK_PRIO_IDLE)) {
|
||||
return K_ERR_TASK_PRIO_INVALID;
|
||||
}
|
||||
@@ -277,11 +420,7 @@ __API__ k_err_t tos_task_suspend(k_task_t *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
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
|
||||
if (knl_is_idle(task)) {
|
||||
return K_ERR_TASK_SUSPEND_IDLE;
|
||||
@@ -309,12 +448,7 @@ __API__ k_err_t tos_task_resume(k_task_t *task)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(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
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
|
||||
if (unlikely(knl_is_self(task))) {
|
||||
return K_ERR_TASK_RESUME_SELF;
|
||||
@@ -375,14 +509,9 @@ __API__ k_err_t tos_task_delay_abort(k_task_t *task)
|
||||
TOS_CPU_CPSR_ALLOC();
|
||||
|
||||
TOS_PTR_SANITY_CHECK(task);
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
TOS_IN_IRQ_CHECK();
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&task->knl_obj, KNL_OBJ_TYPE_TASK)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
|
||||
if (knl_is_self(task) || !task_state_is_sleeping(task)) {
|
||||
@@ -404,6 +533,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)
|
||||
@@ -417,11 +585,7 @@ __API__ k_err_t tos_task_stack_draught_depth(k_task_t *task, int *depth)
|
||||
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
|
||||
TOS_OBJ_VERIFY(task, KNL_OBJ_TYPE_TASK);
|
||||
|
||||
TOS_CPU_INT_DISABLE();
|
||||
rc = cpu_task_stack_draught_depth(task->stk_base, task->stk_size, depth);
|
||||
|
@@ -147,12 +147,7 @@ __API__ k_err_t tos_timer_create(k_timer_t *tmr,
|
||||
__API__ k_err_t tos_timer_destroy(k_timer_t *tmr)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(tmr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&tmr->knl_obj, KNL_OBJ_TYPE_TIMER)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(tmr, KNL_OBJ_TYPE_TIMER);
|
||||
|
||||
if (tmr->state == TIMER_STATE_UNUSED) {
|
||||
return K_ERR_TIMER_INACTIVE;
|
||||
@@ -169,12 +164,7 @@ __API__ k_err_t tos_timer_destroy(k_timer_t *tmr)
|
||||
__API__ k_err_t tos_timer_start(k_timer_t *tmr)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(tmr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&tmr->knl_obj, KNL_OBJ_TYPE_TIMER)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(tmr, KNL_OBJ_TYPE_TIMER);
|
||||
|
||||
if (tmr->state == TIMER_STATE_UNUSED) {
|
||||
return K_ERR_TIMER_INACTIVE;
|
||||
@@ -205,12 +195,7 @@ __API__ k_err_t tos_timer_start(k_timer_t *tmr)
|
||||
__API__ k_err_t tos_timer_stop(k_timer_t *tmr)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(tmr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&tmr->knl_obj, KNL_OBJ_TYPE_TIMER)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(tmr, KNL_OBJ_TYPE_TIMER);
|
||||
|
||||
if (tmr->state == TIMER_STATE_UNUSED) {
|
||||
return K_ERR_TIMER_INACTIVE;
|
||||
@@ -232,12 +217,7 @@ __API__ k_err_t tos_timer_stop(k_timer_t *tmr)
|
||||
__STATIC__ k_err_t timer_change(k_timer_t *tmr, k_tick_t new_val, timer_change_type_t change_type)
|
||||
{
|
||||
TOS_PTR_SANITY_CHECK(tmr);
|
||||
|
||||
#if TOS_CFG_OBJECT_VERIFY_EN > 0u
|
||||
if (!knl_object_verify(&tmr->knl_obj, KNL_OBJ_TYPE_TIMER)) {
|
||||
return K_ERR_OBJ_INVALID;
|
||||
}
|
||||
#endif
|
||||
TOS_OBJ_VERIFY(tmr, KNL_OBJ_TYPE_TIMER);
|
||||
|
||||
if (tmr->state == TIMER_STATE_UNUSED) {
|
||||
return K_ERR_TIMER_INACTIVE;
|
||||
|
Reference in New Issue
Block a user