2025-05-08 18:01:52 +08:00

1360 lines
51 KiB
C

// Copyright 2020-2021 Beken
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <common/bk_include.h>
#include <common/bk_typedef.h>
#include <common/bk_kernel_err.h>
#pragma once
/**
* @brief os enums defines
* @defgroup os_defines os defines
* @ingroup os
* @{
*/
#define RTOS_TAG "os" /**< OS log tag*/
#define RTOS_LOGI(...) BK_LOGI(RTOS_TAG, ##__VA_ARGS__) /**< Output OS Info log */
#define RTOS_LOGW(...) BK_LOGW(RTOS_TAG, ##__VA_ARGS__) /**< Output OS Warning log */
#define RTOS_LOGE(...) BK_LOGE(RTOS_TAG, ##__VA_ARGS__) /**< Output OS Error log */
#define RTOS_LOGD(...) BK_LOGD(RTOS_TAG, ##__VA_ARGS__) /**< Output OS Debug log */
/// os stop interrupt
#define GLOBAL_INT_STOP (void)rtos_disable_int
/// os declaration interrupt status
#define GLOBAL_INT_DECLARATION() uint32_t irq_level
/// os read interrupt status and disable interrupt
#define GLOBAL_INT_DISABLE() irq_level = rtos_disable_int()
/// os restore interrupt status
#define GLOBAL_INT_RESTORE() rtos_enable_int(irq_level)
#define RTOS_SUCCESS (1) /**< Return Success */
#define RTOS_FAILURE (0) /**< Return Failure */
#define BEKEN_DEFAULT_WORKER_PRIORITY (6) /**< Default Worker Priority */
#define BEKEN_APPLICATION_PRIORITY (7) /**< Application Task Priority */
#define NanosecondsPerSecond 1000000000UUL /**< Nanoseconds Per Second */
#define MicrosecondsPerSecond 1000000UL /**< Microseconds Per Second */
#define MillisecondsPerSecond 1000 /**< Milliseconds Per Second */
#define BEKEN_NEVER_TIMEOUT (0xFFFFFFFF) /**< Never Timeout */
#define BEKEN_WAIT_FOREVER (0xFFFFFFFF) /**< Wait Forever */
#define BEKEN_NO_WAIT (0) /**< No Wait */
#define NANOSECONDS 1000000UL /**< Nanoseconds Per Milliseconds */
#define MICROSECONDS 1000 /**< Microseconds Per Milliseconds */
#define MILLISECONDS (1) /**< One Milliseconds */
#define SECONDS (1000) /**< Milliseconds Per Second */
#define MINUTES (60 * SECONDS) /**< Milliseconds Per MINUTES */
#define HOURS (60 * MINUTES) /**< Milliseconds Per HOURS */
#define DAYS (24 * HOURS) /**< Milliseconds Per DAYS */
#define BEKEN_MAGIC_WORD (0xBABA7231) /**< Beken Magic word */
typedef int bk_err_t; /**< Return error code */
typedef void *beken_thread_arg_t; /**< Thread argument pointer type */
typedef uint8_t beken_bool_t; /**< Bool type */
typedef uint32_t beken_time_t; /**< Time value in milliseconds */
typedef uint32_t beken_utc_time_t; /**< UTC Time in seconds */
typedef uint64_t beken_utc_time_ms_t; /**< UTC Time in milliseconds */
typedef uint32_t beken_event_flags_t; /**< Event flag type */
typedef void *beken_semaphore_t; /**< OS Semaphore handle pointer */
typedef void *beken_mutex_t; /**< OS Mutex handle pointer */
typedef void *beken_thread_t; /**< OS Thread handle pointer */
typedef void *beken_queue_t; /**< OS Queue handle pointer */
typedef void *beken_event_t; /**< OS Event handle pointer */
/// timer callback function type with one parameter
typedef void (*timer_handler_t)(void *);
/// timer callback function type with two parameters
typedef void (*timer_2handler_t)(void *Larg, void *Rarg);
/// event callback function type with one parameter
typedef bk_err_t(*event_handler_t)(void *arg);
/// OS Thread entry function type
typedef void (*beken_thread_function_t)(beken_thread_arg_t arg);
/// OS Event wait options
typedef enum {
WAIT_FOR_ANY_EVENT, /**< Wait for any event */
WAIT_FOR_ALL_EVENTS, /**< Wait for all event */
} beken_event_flags_wait_option_t;
/**
* @}
*/
#define os_printf bk_printf /**< OS printf, will be replace with RTOS_LOGI later */
#define os_null_printf bk_null_printf /**< OS drop print string */
#define rtos_init_semaphore_adv rtos_init_semaphore_ex /**< To be replace with rtos_init_semaphore_ex */
#define rtos_get_sema_count rtos_get_semaphore_count /**< To be replace with rtos_get_semaphore_count */
/**
* @brief os struct defines
* @defgroup os_structs structs in os
* @ingroup os
* @{
*/
/// OS timer handle struct type
typedef struct {
void *handle; /**< OS timer handle pointer */
timer_handler_t function; /**< OS timer handle callback function */
void *arg; /**< OS timer handle callback argument */
} beken_timer_t;
/// OS worker thread handle struct type
typedef struct {
beken_thread_t thread; /**< OS thread handle */
beken_queue_t event_queue; /**< OS event queue */
} beken_worker_thread_t;
/// OS timer event struct type
typedef struct {
event_handler_t function; /**< OS event callback function */
void *arg; /**< OS event callback argument */
beken_timer_t timer; /**< OS timer handle */
beken_worker_thread_t *thread; /**< OS work thread handle */
} beken_timed_event_t;
/// OS timer handle struct type
typedef struct {
void *handle; /**< OS timer handle pointer */
timer_2handler_t function; /**< OS timer handle callback function */
void *left_arg; /**< OS timer handle callback first argument */
void *right_arg; /**< OS timer handle callback second argument */
uint32_t beken_magic; /**< OS timer magic word */
} beken2_timer_t;
/**
* @}
*/
/**
* @brief os API
* @defgroup os_apis os API group
* @ingroup os
* @{
*/
/** @brief Enter a critical session, all interrupts are disabled
*
* @return irq flags
*/
uint32_t rtos_enter_critical(void);
/** @brief Exit a critical session, all interrupts are enabled
* @param flags : irq flags
*
* @return none
*/
void rtos_exit_critical(uint32_t flags);
/** @brief Get system time value in milliseconds
*
* @param time_ptr : the pointer of time value in milliseconds
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t beken_time_get_time(beken_time_t *time_ptr);
/** @defgroup BEKEN_RTOS_Thread _BK_ RTOS Thread Management Functions
* @brief Provide thread creation, delete, suspend, resume, and other RTOS management API
* @verbatim
* _BK_ thread priority table
*
* +----------+-----------------+
* | Priority | Thread |
* |----------|-----------------|
* | 0 | _BK_ | Highest priority
* | 1 | Network |
* | 2 | |
* | 3 | Network worker |
* | 4 | |
* | 5 | Default Library |
* | | Default worker |
* | 6 | |
* | 7 | Application |
* | 8 | |
* | 9 | Idle | Lowest priority
* +----------+-----------------+
* @endverbatim
* @{
*/
/** @brief Creates and starts a new thread,the task will be dynamically created in sram
*
* @note Do not call this API when interrupts are disabled (may cause the system
* to enter a deadlock or abnormal status)
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number. The adaptation layer uniformly managers priorities.
* For the application layer,the lower the configured number,the higher
* the task priority.Currently supports ten priority levels from 0 to 9.
* recommended that the application layer use priorities from 6 to 8.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread,size is in bytes,for example if the stack_size
* is defined as 2048,then 2048bytes will be allocated for stack storage.
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_create_sram_thread(beken_thread_t *thread, uint8_t priority, const char *name, beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg);
/** @brief Creates and starts a new thread on psram
*
* @note Do not call this API when interrupts are disabled (may cause the system
* to enter a deadlock or abnormal status)
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number.he adaptation layer uniformly managers priorities.
* For the application layer,the lower the configured number,the higher
* the task priority.Currently supports ten priority levels from 0 to 9.
* recommended that the application layer use priorities from 6 to 8.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread,size is in bytes,for example if the stack_size
* is defined as 2048,then 2048bytes will be allocated for stack storage.
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_create_psram_thread(beken_thread_t *thread, uint8_t priority, const char *name, beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg);
/** @brief Creates and starts a new thread,the task will be dynamically created in sram(default)
*
* @note Do not call this API when interrupts are disabled (may cause the system
* to enter a deadlock or abnormal status)
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number. The adaptation layer uniformly managers priorities.
* For the application layer,the lower the configured number,the higher
* the task priority.Currently supports ten priority levels from 0 to 9.
* recommended that the application layer use priorities from 6 to 8.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread,size is in bytes,for example if the stack_size
* is defined as 2048,then 2048bytes will be allocated for stack storage.
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_create_thread(beken_thread_t *thread, uint8_t priority, const char *name, beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg);
/** @brief Deletes a terminated thread
*
* @note If you want to delete the task itself,do not call this API when the interrupts
* is disables(may cause the system to enter a deadlock or abnormal status))
*
* @param thread : the handle of the thread to delete, , NULL is the current thread
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_delete_thread(beken_thread_t *thread);
/** @brief Suspend a thread
*
* @note If you want to suspend the task itself,do not call this API when interrupts
* are disabled (may cause the system to enter a deadlock or abnormal status)
*
* @param thread : the handle of the thread to suspend, NULL is the current thread
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
void rtos_suspend_thread(beken_thread_t *thread);
/** @brief Suspend all other thread
*
* @param none
*
* @return none
*/
void rtos_suspend_all_thread(void);
/** @brief resume a thread
*
* @note If you want to resume the task not itself,do not call this API when interrupts
* are disabled (may cause the system to enter a deadlock or abnormal status)
*
* @param thread : the handle of the thread to resume, NULL is the current thread
*
* @return none
*/
void rtos_resume_thread(beken_thread_t* thread);
/** @brief Rresume all other thread
*
* @param none
*
* @return none
*/
void rtos_resume_all_thread(void);
/** @brief Sleeps until another thread has terminated
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @Details Causes the current thread to sleep until the specified other thread
* has terminated. If the processor is heavily loaded with higher priority
* tasks, this thread may not wake until significantly after the thread termination.
*
* @param thread : the handle of the other thread which will terminate
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_thread_join(beken_thread_t *thread);
/** @brief Forcibly wakes another thread
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @Details Causes the specified thread to wake from suspension. This will usually
* cause an error or timeout in that thread, since the task it was waiting on
* is not complete.
*
* @param thread : the handle of the other thread which will be removed from the
* block state.
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_thread_force_awake(beken_thread_t *thread);
/** @brief Checks if a thread is the current thread
*
* @Details Checks if a specified thread is the currently running thread
*
* @param thread : the handle of the other thread against which the current thread
* will be compared
*
* @return true : specified thread is the current thread
* @return false : specified thread is not currently running
*/
bool rtos_is_current_thread(beken_thread_t *thread);
/** @brief Get current thread handler
*
* @return Current RTOS thread handler
*/
beken_thread_t *rtos_get_current_thread(void);
/** @brief Suspend current thread for a specific time
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param seconds : A time interval (Unit: seconds)
*
* @return None.
*/
void rtos_thread_sleep(uint32_t seconds);
/** @brief Suspend current thread for a specific time
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param milliseconds : A time interval (Unit: millisecond)
*
* @return None.
*/
void rtos_thread_msleep(uint32_t milliseconds);
/** @brief Suspend current thread for a specific time
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param num_ms : A time interval (Unit: millisecond)
*
* @return kNoErr.
*/
bk_err_t rtos_delay_milliseconds(uint32_t num_ms);
/**
* @}
*/
/** @defgroup BEKEN_RTOS_SEM _BK_ RTOS Semaphore Functions
* @brief Provide management APIs for semaphore such as init,set,get and dinit.
* @{
*/
/** @brief Initialises a counting semaphore and set count to 0
*
* @param semaphore : a pointer to the semaphore handle to be initialised
* @param max_count : the max count number of this semaphore
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_semaphore(beken_semaphore_t *semaphore, int max_count);
/** @brief Initialises a counting semaphore and set count to init count
*
* @param semaphore : a pointer to the semaphore handle to be initialised
* @param max_count : the max count number of this semaphore
* @param init_count : the init count number of this semaphore
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_semaphore_ex(beken_semaphore_t *semaphore, int max_count, int init_count);
/** @brief Set (post/put/increment) a semaphore
*
* @note This API can be called in task context and interrupt context.
*
* @param semaphore : a pointer to the semaphore handle to be set
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_set_semaphore(beken_semaphore_t *semaphore);
/** @brief Get (wait/decrement) a semaphore
*
* @note Do not call this API when interrupts are disabled (may cause the system
* to enter a deadlock or abnormal status)
*
* @Details Attempts to get (wait/decrement) a semaphore. If semaphore is at zero already,
* then the calling thread will be suspended until another thread sets the
* semaphore with @ref rtos_set_semaphore
*
* @param semaphore : a pointer to the semaphore handle
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_get_semaphore(beken_semaphore_t *semaphore, uint32_t timeout_ms);
/** @brief get current semaphore count
*
* @param semaphore : a pointer to the semaphore handle to be set
*
* @return kNoErr : current semaphore count
*/
int rtos_get_semaphore_count(beken_semaphore_t *semaphore);
/** @brief De-initialise a semaphore
*
* @Details Deletes a semaphore created with @ref rtos_init_semaphore
*
* @param semaphore : a pointer to the semaphore handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_deinit_semaphore(beken_semaphore_t *semaphore);
/**
* @}
*/
/** @defgroup BEKEN_RTOS_MUTEX _BK_ RTOS Mutex Functions
* @brief Provide management APIs for Mutex such as init,lock,unlock and dinit.
* @{
*/
/** @brief Initialises a mutex
*
* @Details A mutex is different to a semaphore in that a thread that already holds
* the lock on the mutex can request the lock again (nested) without causing
* it to be suspended.
*
* @param mutex : a pointer to the mutex handle to be initialised
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_mutex(beken_mutex_t *mutex);
/** @brief Obtains the lock on a mutex
*
* @Details Attempts to obtain the lock on a mutex. If the lock is already held
* by another thead, the calling thread will not be suspended until the mutex
* lock is released by the other thread.
*
* @param mutex : a pointer to the mutex handle to be locked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_trylock_mutex(beken_mutex_t *mutex);
/** @brief Obtains the lock on a mutex
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @Details Attempts to obtain the lock on a mutex. If the lock is already held
* by another thead, the calling thread will be suspended until the mutex
* lock is released by the other thread.
*
* @param mutex : a pointer to the mutex handle to be locked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_lock_mutex(beken_mutex_t *mutex);
/** @brief Releases the lock on a mutex
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @Details Releases a currently held lock on a mutex. If another thread
* is waiting on the mutex lock, then it will be resumed.
*
* @param mutex : a pointer to the mutex handle to be unlocked
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_unlock_mutex(beken_mutex_t *mutex);
/** @brief De-initialise a mutex
*
* @Details Deletes a mutex created with @ref rtos_init_mutex
*
* @param mutex : a pointer to the mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_deinit_mutex(beken_mutex_t *mutex);
/** @brief Obtains the lock on a mutex
*
* @Details Attempts to obtain the lock on a mutex. If the lock is already held
* by another thead, the calling thread will be suspended until the mutex
* lock is released by the other thread or timeout.
*
* @param mutex : a pointer to the mutex handle to be locked
* @param timeout_ms : timeout for get lock
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_lock_mutex_timeout( beken_mutex_t* mutex, uint32_t timeout_ms);
/** @brief Creates a new recursive mutex type semaphore instance
*
* @param mutex : a pointer to the new recursive mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_recursive_mutex( beken_mutex_t* mutex );
/** @brief Obtains the lock on a recursive mutex (A mutex
* used recursively can be 'taken' repeatedly by the owner)
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param mutex : a pointer to the new recursive mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_lock_recursive_mutex( beken_mutex_t* mutex );
/** @brief Releases the lock on a recursive mutex (A mutex
* used recursively can be 'taken' repeatedly by the owner)
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param mutex : a pointer to the new recursive mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_unlock_recursive_mutex( beken_mutex_t* mutex );
/** @brief De-initialise a recursive mutex
*
* @Details Deletes a mutex created with @ref rtos_init_recursive_mutex
*
* @param mutex : a pointer to the recursive mutex handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_deinit_recursive_mutex( beken_mutex_t* mutex );
/**
* @}
*/
/** @defgroup BEKEN_RTOS_QUEUE _BK_ RTOS FIFO Queue Functions
* @brief Provide management APIs for FIFO such as init,push,pop and dinit.
* @{
*/
/** @brief Initialises a FIFO queue
*
* @param queue : a pointer to the queue handle to be initialised
* @param name : a text string name for the queue (NULL is allowed)
* @param message_size : size in bytes of objects that will be held in the queue
* @param number_of_messages : depth of the queue - i.e. max number of objects in the queue
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_queue(beken_queue_t *queue, const char *name, uint32_t message_size, uint32_t number_of_messages);
/** @brief Post an item to the back of a queue. The item is queued by copy, not by
* reference
*
* @note This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param queue : a pointer to the queue handle
* @param message : the object to be added to the queue. Size is assumed to be
* the size specified in @ref rtos_init_queue
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
bk_err_t rtos_push_to_queue(beken_queue_t *queue, void *message, uint32_t timeout_ms);
/** @brief Post an item to the front of a queue. The item is queued by copy, not by
* reference.
*
* @note This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param queue : a pointer to the queue handle
* @param message : the object to be added to the queue. Size is assumed to be
* the size specified in @ref rtos_init_queue
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
bk_err_t rtos_push_to_queue_front(beken_queue_t *queue, void *message, uint32_t timeout_ms);
/** @brief Pops an object off a queue
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param queue : a pointer to the queue handle
* @param message : pointer to a buffer that will receive the object being
* popped off the queue. Size is assumed to be
* the size specified in @ref rtos_init_queue , hence
* you must ensure the buffer is long enough or memory
* corruption will result
* @param timeout_ms: the number of milliseconds to wait before returning
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error or timeout occurred
*/
bk_err_t rtos_pop_from_queue(beken_queue_t *queue, void *message, uint32_t timeout_ms);
/** @brief De-initialise a queue created with @ref rtos_init_queue
*
* @param queue : a pointer to the queue handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_deinit_queue(beken_queue_t *queue);
/** @brief Check if a queue is empty
*
* @param queue : a pointer to the queue handle
*
* @return true : queue is empty.
* @return false : queue is not empty.
*/
bool rtos_is_queue_empty(beken_queue_t *queue);
/** @brief Check if a queue is full
*
* @param queue : a pointer to the queue handle
*
* @return true : queue is empty.
* @return false : queue is not empty.
*/
bool rtos_is_queue_full(beken_queue_t *queue);
/** @brief Reset queue
*
* @param queue : a pointer to the queue handle
*
* @return true : reset ok.
* @return false : reset fail.
*/
bool rtos_reset_queue(beken_queue_t *queue);
/** @defgroup BEKEN_RTOS_EVENT _BK_ RTOS Event Functions
* @{
*/
/** Create a new event group
*
* @param event_flags : pointer to a event handle which will be initialised
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_event_flags( beken_event_t* event_flags );
/** block to wait for one or more bits to be set within a
* previously created event group.
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param event_flags : pointer to a event handle which will be initialised
* @param flags_to_wait_for : A bitwise value that indicates the bit or bits to test
* inside the event group. For example, to wait for bit 0
* and/or bit 2 set flags_to_wait_for to 0x05. To wait for
* bits 0 and/or bit 1 and/or bit 2 set flags_to_wait_for to 0x07. Etc.
* @param clear_set_flags : If clear_set_flags is set to pdTRUE then any bits within
* flags_to_wait_for that are set within the event group will
* be cleared before returns
* @param wait_option : If it is set to WAIT_FOR_ALL_EVENTS then will return when
* either all the bits in flags_to_wait_for are set or the
* specified block time expires. If it is set to WAIT_FOR_ANY_EVENT
* then will return when any one of the bits set in flags_to_wait_for
* is set or the specified block time expires. The block time is specified
* by the timeout_ms parameter.
* @param timeout_ms : the time period between function calls in milliseconds
*
* @return The value of the event group at the time either the bits being waited
* for became set, or the block time expired.
*/
beken_event_flags_t rtos_wait_for_event_flags( beken_event_t* event_flags,
uint32_t flags_to_wait_for,
beken_bool_t clear_set_flags,
beken_event_flags_wait_option_t wait_option,
uint32_t timeout_ms );
/** Set bits within an event group.
*
* @note This API can be called in task context and interrupt context.
*
* @param event_flags : pointer to a event handle which will be initialised
* @param flags_to_set : A bitwise value that indicates the bit or bits to set.
* For example, to set bit 3 only, set flags_to_set to 0x08.
* To set bit 3 and bit 0 set flags_to_set to 0x09.
*
*/
void rtos_set_event_flags( beken_event_t* event_flags, uint32_t flags_to_set );
/** Clear bits within an event group.
*
* @note This API can be called in task context and interrupt context.
*
* @param event_flags : pointer to a event handle which will be initialised
* @param flags_to_clear :A bitwise value that indicates the bit or bits to clear
* in the event group. For example, to clear bit 3 only,
* set flags_to_clear to 0x08. To clear bit 3 and bit 0 set
* flags_to_clear to 0x09.
*
* @return The value of the event group before the specified bits were cleared
*
*/
beken_event_flags_t rtos_clear_event_flags( beken_event_t* event_flags, uint32_t flags_to_clear );
/** Atomically set bits within an event group, then wait for a combination of
* bits to be set within the same event group. This functionality is typically
* used to synchronise multiple tasks, where each task has to wait for the other
* tasks to reach a synchronisation point before proceeding.
*
* @note do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param event_flags : pointer to a event handle which will be initialised
* @param flags_to_set : The bits to set in the event group before determining
* if, and possibly waiting for, all the bits specified by
* the timeout_ms parameter are set.
* @param flags_to_wait_for : A bitwise value that indicates the bit or bits to test
* inside the event group. For example, to wait for bit 0 and bit 2
* flags_to_wait_for to 0x05. To wait for bits 0 and bit 1 and bit 2 set
* flags_to_wait_for to 0x07. Etc.
* @param timeout_ms : the time period between function calls in milliseconds
*
* @return The value of the event group at the time either the bits being waited
* for became set, or the block time expired.
*/
beken_event_flags_t rtos_sync_event_flags( beken_event_t* event_flags,
uint32_t flags_to_set,
uint32_t flags_to_wait_for,
uint32_t timeout_ms);
/** Delete an event group that was previously created by a call to
* rtos_init_event_flags(). Tasks that are blocked on the event group will be
* unblocked and obtain 0 as the event group's value.
*
* @param event_flags : pointer to a event handle which will be initialised
*
* @return kNoErr : on success.
* @return kParamErr : if an error occurred
*/
bk_err_t rtos_deinit_event_flags( beken_event_t* event_flags );
/** @defgroup BEKEN_RTOS_TIMER _BK_ RTOS Timer Functions
* @brief Provide management APIs for timer such as init,start,stop,reload and dinit.
* @{
*/
/**
* @brief Gets time in miiliseconds since RTOS start
*
* @note: Since this is only 32 bits, it will roll over every 49 days, 17 hours.
*
* @returns Time in milliseconds since RTOS started.
*/
uint32_t rtos_get_time(void);
/** @defgroup BEKEN_RTOS_TIMER _BK_ RTOS Timer Functions
* @brief Provide management APIs for timer such as init,start,stop,reload and dinit.
* @{
*/
/**
* @brief Gets time in miiliseconds since RTOS start
*
* @note: Since this is only 32 bits, it will roll over every 49 days, 17 hours.
*
* @returns Time in milliseconds since RTOS started.
*/
uint32_t beken_ms_per_tick(void);
/**
* @brief Initialize a RTOS periodic timer
*
* @note Timer does not start running until @ref beken_start_timer is called
* and the timer will execute periodically
*
* @param timer : a pointer to the timer handle to be initialised
* @param time_ms : Timer period in milliseconds
* @param function : the callback handler function that is called each time the
* timer expires
* @param arg : an argument that will be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_timer(beken_timer_t *timer, uint32_t time_ms, timer_handler_t function, void *arg);
/** @brief Starts a RTOS periodic timer
*
* @note Timer must have been previously initialised with @ref rtos_init_timer
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the timer handle to start
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_start_timer(beken_timer_t *timer);
/** @brief Stops a running RTOS periodic timer
*
* @note Timer must have been previously started with @ref rtos_init_timer.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the timer handle to stop
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_stop_timer(beken_timer_t *timer);
/** @brief Reloads a RTOS periodic timer that has expired
*
* @note This is usually called in the timer callback handler, to
* reschedule the timer for the next period.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the timer handle to reload
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_reload_timer(beken_timer_t *timer);
/** @brief De-initialise a RTOS periodic timer
*
* @note Deletes a RTOS timer created with @ref rtos_init_timer.
* do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_deinit_timer(beken_timer_t *timer);
/** @brief Check if an RTOS periodic timer is init
*
* @param timer : a pointer to the RTOS timer handle
*
* @return true : if init.
* @return false : if not init
*/
bool rtos_is_timer_init(beken_timer_t *timer);
/** @brief Check if an RTOS periodic timer is running
*
* @param timer : a pointer to the RTOS timer handle
*
* @return true : if running.
* @return false : if not running
*/
bool rtos_is_timer_running(beken_timer_t *timer);
/**
* @brief Initialize a RTOS oneshot timer
*
* @note Timer does not start running until @ref rtos_start_oneshot_timer is called
* and the timer will only execute once
*
* @param timer : a pointer to the timer handle to be initialised
* @param time_ms : Timer period in milliseconds
* @param function : the callback handler function that is called each time the
* timer expires
* @param larg : an argument that will be passed to the callback function
* @param rarg : an argument that will be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_init_oneshot_timer(beken2_timer_t *timer,
uint32_t time_ms,
timer_2handler_t function,
void *larg,
void *rarg);
/** @brief De-initialise a RTOS rtos_init_oneshot_timer timer
*
* @note Deletes a RTOS timer created with @ref rtos_init_oneshot_timer.
* do not call this API when interrupts are disabled (may cause the
* system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_deinit_oneshot_timer(beken2_timer_t *timer);
/** @brief start a RTOS oneshot timer
*
* @note Timer must have been previously started with @ref rtos_init_oneshot_timer.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_start_oneshot_timer(beken2_timer_t *timer);
/** @brief stop a RTOS oneshot timer
*
* @note Timer must have been previously started with @ref rtos_init_oneshot_timer.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_stop_oneshot_timer(beken2_timer_t *timer);
/** @brief Check if an RTOS oneshot timer is running
*
* @param timer : a pointer to the RTOS timer handle
*
* @return true : if running.
* @return false : if not running
*/
bool rtos_is_oneshot_timer_running(beken2_timer_t *timer);
/** @brief Check if an RTOS oneshot timer is initialised
*
* @param timer : a pointer to the RTOS timer handle
*
* @return true : if initialised
* @return false : if not initialised
*/
bool rtos_is_oneshot_timer_init(beken2_timer_t *timer);
/** @brief re-starts a oneshot timer
*
* @note Timer must have been previously started with @ref rtos_init_oneshot_timer.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_oneshot_reload_timer(beken2_timer_t *timer);
/** @brief changes the period of a oneshot timer
*
* @note Timer must have been previously started with @ref rtos_init_oneshot_timer.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_change_period(beken_timer_t *timer, uint32_t time_ms);
/** @brief changes the period of a oneshot timer then re-start it
*
* @note Timer must have been previously started with @ref rtos_init_oneshot_timer.
* This API can be called in task context and interrupt context. However when
* calling this API in task context,the interrupt cannot be turned off(may cause
* the system to enter a deadlock or abnormal status)
*
* @param timer : a pointer to the RTOS timer handle
* @param time_ms : Timer period in milliseconds
* @param function : the callback handler function that is called each time the
* timer expires
* @param larg : an argument that will be passed to the callback function
* @param rarg : an argument that will be passed to the callback function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_oneshot_reload_timer_ex(beken2_timer_t *timer,
uint32_t time_ms,
timer_2handler_t function,
void *larg,
void *rarg);
/** @brief Returns the time in ticks at which the timer will expire
*
* @param timer : a pointer to the RTOS timer handle
*
* @return If the timer is running then the time in ticks at which the timer
* will next expire is returned. If the timer is not running then the return
* value is undefined.
*/
uint32_t rtos_get_timer_expiry_time(beken_timer_t *timer);
/** @defgroup BEKEN_RTOS_SYSTEM _BK_ RTOS system Functions
* @brief Provide management APIs for system such as memory interrupt etc.
* @{
*/
/** @brief Starts the real time kernel tick processing. After calling the kernel
* has control over which tasks are executed and when.
*/
void rtos_start_scheduler(void);
/** @brief check if the rtos scheduler is running or not
*
*/
bool rtos_is_scheduler_started(void);
/** @brief get the name of the currently used OS
*
*/
char *rtos_get_name(void);
/** @brief get the version of the currently used OS
*
*/
char *rtos_get_version(void);
/** @brief get the total heap size
*
* @return the amount of total heap space available on the system
*/
size_t rtos_get_total_heap_size(void);
/** @brief get the free heap size
*
* @return the amount of left heap space available on the system
*/
size_t rtos_get_free_heap_size(void);
/** @brief get the minimum heap size
*
* @return the minimum value remaining during the system heap
* space usage
*/
size_t rtos_get_minimum_free_heap_size(void);
/** @brief get the total heap size in psram
*
* @return the amount of total heap space in psram
*/
size_t rtos_get_psram_total_heap_size(void);
/** @brief get the free heap size
*
* @return the amount of left heap space in psram
*/
size_t rtos_get_psram_free_heap_size(void);
/** @brief get the minimum heap size in psram
*
* @return the minimum value remaining in psram during
* the system heap space usage
*/
size_t rtos_get_psram_minimum_free_heap_size(void);
/** @brief get the os tick count
*
* @return The count of ticks since vTaskStartScheduler was called.
*/
uint32_t rtos_get_tick_count(void);
/** @brief disable interrupts and return the current interrupt status
*
* @note disable interrupt support nesting
*
* @return the current interrupt status
*/
uint32_t rtos_disable_int(void);
/** @brief enable previously disabled interrupts
*
* @note this API needs to be used with @ref rtos_disable_int
*
* @param int_level : saved interrupt status
*
* @return the current interrupt status
*/
void rtos_enable_int(uint32_t int_level);
/** @brief disable interrupts and return the current interrupt status
*
* @note disable interrupt support nesting.
* This API has the same functionality as @ref rtos_disable_int
*
* @return the current interrupt status
*/
uint32_t rtos_before_sleep(void);
/** @brief enable previously disabled interrupts
*
* @note This API has the same functionality as @ref rtos_enable_int
*
* @param int_level : saved interrupt status
*
* @return the current interrupt status
*/
void rtos_after_sleep(uint32_t int_level);
/** @brief Check if system in interrupt context
*
* @return true : if in interrupt context
* @return false : if not in interrupt context
*/
bool rtos_is_in_interrupt_context(void);
/** @brief Check if local irq is disabled
*
* @return true : if irq is disabled
* @return false : if irq is not disabled
*/
bool rtos_local_irq_disabled(void);
/** @brief Check if the current scheduler is in suspended state
*
* @return true : the scheduler is in suspended state
* @return false : the scheduler is not in suspended state
*/
bool rtos_is_scheduler_suspended(void);
/** @brief disable interrupts and the run in an infinite loop
*
*/
void rtos_shutdown(void);
#if (CONFIG_FREERTOS_SMP_TEMP)
/*TODO: Enhanced implementation of cohesion*/
#ifndef portGET_CORE_ID
#define portGET_CORE_ID() (*((volatile uint32_t *)(0x20000000))) /*CPU_ID_ADDR = 0x20000000*/
#endif
static inline int rtos_get_core_id(void)
{
return portGET_CORE_ID();
}
/** @brief Creates and starts a new thread with affinity
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param affinity : Core affinity, bitmap of cores, -1 stands for all cores.
* @param priority : A priority number.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_create_thread_with_affinity( beken_thread_t *thread, uint32_t affinity,
uint8_t priority, const char* name,
beken_thread_function_t function, uint32_t stack_size,
beken_thread_arg_t arg );
/** @brief Creates and starts a new smp thread
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_smp_create_thread( beken_thread_t* thread, uint8_t priority, const char* name,
beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg );
/** @brief Creates and starts a new thread specify to run on cpu0
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_core0_create_thread( beken_thread_t* thread, uint8_t priority, const char* name,
beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg );
#if (CONFIG_CPU_CNT > 1)
/** @brief Creates and starts a new thread specify to run on cpu1
*
* @param thread : Pointer to variable that will receive the thread handle (can be null)
* @param priority : A priority number.
* @param name : a text name for the thread (can be null)
* @param function : the main thread function
* @param stack_size : stack size for this thread
* @param arg : argument which will be passed to thread function
*
* @return kNoErr : on success.
* @return kGeneralErr : if an error occurred
*/
bk_err_t rtos_core1_create_thread( beken_thread_t* thread, uint8_t priority, const char* name,
beken_thread_function_t function, uint32_t stack_size, beken_thread_arg_t arg );
#endif
/*
* Lots of our codes use `GLOBAL_INT_DISABLE` to make the code excuted in critical section.
* But in SMP, disable local CPU irq is insufficient. So here `GLOBAL_INT_DISABLE'
* is redefined to `rtos_enter_critical'.
*
* In further, codes may explicitly use `rtos_enter_critical' instead of `GLOBAL_INT_DISABLE',
* and `GLOBAL_INT_DISABLE' still represents disable local cpu irq.
*
* And a global spin lock may be defined, for example, global_spin_lock. and redefine
* GLOBAL_INT_DISABLE and GLOBAL_INT_RESTORE as the following:
* volatile spinlock_t global_spin_lock = SPIN_LOCK_FREE;
* #define GLOBAL_INT_DISABLE() spin_lock_irqsave(&global_spin_lock, irq_level)
* #define GLOBAL_INT_RESTORE() spin_unlock_irqrestore(&global_spin_lock, irq_level)
* refer: portSET_INTERRUPT_MASK_FROM_ISR and portCLEAR_INTERRUPT_MASK_FROM_ISR
*/
#undef GLOBAL_INT_DISABLE
#define GLOBAL_INT_DISABLE() do { irq_level = rtos_enter_critical(); } while (0)
#undef GLOBAL_INT_RESTORE
#define GLOBAL_INT_RESTORE() do { rtos_exit_critical(irq_level); } while (0)
#endif