/** * @file wm_osal.h * * @brief WM OS adapter layer * * @author winnermicro * * Copyright (c) 2015 Winner Microelectronics Co., Ltd. */ #ifndef WM_OSAL_H #define WM_OSAL_H #include #include #include "wm_config.h" #include #include "wm_type_def.h" /** OS TICK Frequency ,this value needs to keep the same as OS self-defined tick value*/ extern const unsigned int HZ; /** Type definition of os_time_t */ typedef long os_time_t; /** Structure definition of os_time */ struct os_time { os_time_t sec; os_time_t usec; }; /** ENUMERATION of OS */ enum TLS_OS_TYPE{ OS_UCOSII = 0, OS_FREERTOS = 1, OS_MAX_NUM }; /** TYPE definition of OS_STK */ #ifdef OS_STK #undef OS_STK #endif typedef unsigned int OS_STK; /** TYPE definition of OS_CPU_SR */ #ifdef OS_CPU_SR #undef OS_CPU_SR #endif typedef unsigned int OS_CPU_SR; /** TYPE definition of tls_os_task_t */ typedef void * tls_os_task_t; /** TYPE definition of tls_os_timer_t */ typedef void tls_os_timer_t; /** TYPE definition of tls_os_sem_t */ typedef void tls_os_sem_t; /** TYPE definition of tls_os_queue_t */ typedef void tls_os_queue_t; /** TYPE definition of tls_os_mailbox_t */ typedef void tls_os_mailbox_t; /** TYPE definition of tls_os_mutex_t */ typedef void tls_os_mutex_t; /** TYPE definition of TLS_OS_TIMER_CALLBACK */ typedef void (*TLS_OS_TIMER_CALLBACK)(void *ptmr, void *parg); /** MACRO definition of TIMER ONE times */ #define TLS_OS_TIMER_OPT_ONE_SHORT 1u /** MACRO definition of TIMER PERIOD */ #define TLS_OS_TIMER_OPT_PERIOD 2u /** ENUMERATION definition of OS STATUS */ typedef enum tls_os_status { TLS_OS_SUCCESS = 0, TLS_OS_ERROR, TLS_OS_ERR_TIMEOUT, } tls_os_status_t; /** * @defgroup System_APIs System APIs * @brief System APIs */ /** * @addtogroup System_APIs * @{ */ /** * @defgroup OS_APIs OS APIs * @brief Operate system APIs */ /** * @addtogroup OS_APIs * @{ */ /** * @brief This function is used to register OS tick timer irq * * @param[in] None * * @return None * * @note None */ void tls_os_timer_init(void); /** * @brief This function is used to tick handler * * @param[in] *p argument * * @return None * * @note None */ void tls_os_time_tick(void *p); /** * @brief This function is used to initialize OS common resource * * @param[in] *arg * * @return None * * @note None */ void tls_os_init(void *arg); /** * @brief This function is used to start task scheduler * * @param[in] None * * @return None * * @note None */ void tls_os_start_scheduler(void); /** * @brief This function is used to get OS type * * @param[in] None * * @retval 0 OS_UCOSII * @retval 1 OS_FREERTOS * * @note May not be used by now. */ int tls_os_get_type(void); /** * @brief This function is used to create a task. Tasks can either be created prior to the start of multitasking or by a running task. A task cannot be created in an ISR. * * @param[in] *task pointer to the task * @param[in] name the task's name * @param[in] entry the task's entry function * @param[in] param pointer to an optional data area which can be used to pass parameters to the task when the task first executes. Where the task is concerned it thinks it was invoked and passed the argument 'param' as follows: void Task (void *param) { for (;;) { Task code; } } * @param[in] *stk_start pointer to the task's bottom of stack. Address must be between 0x20000000 and 0x20028000 * @param[in] stk_size the size of the stack in number of elements. If OS_STK is set to INT8U, 'stk_size' corresponds to the number of bytes available. If OS_STK is set to INT16U, 'stk_size' contains the number of 16-bit entries available. Finally, if OS_STK is set to INT32U, 'stk_size' contains the number of 32-bit entries available on the stack. * @param[in] prio the task's priority. A unique priority MUST be assigned to each task and the lower the number, the higher the priority. * @param[in] flag contains additional information about the behavior of the task * * @retval TLS_OS_SUCCESS the call was successful. * @retval TLS_OS_ERROR failed * * @note 1) Stack Range: [stk_start, stk_start + stk_size) must be between 0x20000000 and 0x20028000 * 2) task stack: Using static memory like array, not using dynamic memory. * 3) And if you use static memory like array (large size) as data storage in your application, * we suggest you change it to dynamic memory by tls_mem_alloc. */ tls_os_status_t tls_os_task_create(tls_os_task_t *task, const char* name, void (*entry)(void* param), void* param, u8 *stk_start, u32 stk_size, u32 prio, u32 flag); /** * @brief This function allows you to delete a task. The calling task can delete itself by its own priority number. The deleted task is returned to the dormant state and can be re-activated by creating the deleted task again. * * @param[in] prio task priority to delete * @param[in] (*freefun)(void) function to free resource * * @retval TLS_OS_SUCCESS the call is successful * @retval TLS_OS_ERROR failed * * @note Generally, you do not need to call this function in your application. */ tls_os_status_t tls_os_task_del(u8 prio, void (*freefun)(void)); /** * @brief This function allows you to delete a task. The calling task can delete itself by taks's handler. The deleted task is returned to the dormant state and can be re-activated by creating the deleted task again. * * @param[in] prio task handler to delete * @param[in] (*freefun)(void) function to free resource * * @retval TLS_OS_SUCCESS the call is successful * @retval TLS_OS_ERROR failed * */ tls_os_status_t tls_os_task_del_by_task_handle(void *handle, void (*freefun)(void)); tls_os_task_t tls_os_task_id(); u8 tls_os_task_schedule_state(); tls_os_status_t tls_os_task_suspend(tls_os_task_t task); tls_os_status_t tls_os_task_resume(tls_os_task_t task); tls_os_status_t tls_os_task_resume_from_isr(tls_os_task_t task); /** * @brief This function creates a mutual exclusion semaphore * * @param[in] prio the priority to use when accessing the mutual exclusion semaphore. In other words, when the semaphore is acquired and a higher priority task attempts to obtain the semaphore then the priority of the task owning the semaphore is raised to this priority. It is assumed that you will specify a priority that is LOWER in value than ANY of the tasks competing for the mutex. * @param[in] **mutex pointer to the event control clock (OS_EVENT) associated with the created mutex. * * @retval TLS_OS_SUCCESS the call was successful * @retval TLS_OS_ERROR failed * * @note 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number of the task owning the mutex or 0xFF if no task owns the mutex. 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number to use to reduce priority inversion. */ tls_os_status_t tls_os_mutex_create(u8 prio, tls_os_mutex_t **mutex); /** * @brief This function deletes a mutual exclusion semaphore and readies all tasks pending on the it * * @param[in] *mutex pointer to the event control block associated with the desired mutex * * @retval TLS_OS_SUCCESS The call was successful and the mutex was deleted * @retval TLS_OS_ERROR failed * * @note 1) This function must be used with care. Tasks that would normally expect the presence of the mutex MUST check the return code of OSMutexPend(). 2) This call can potentially disable interrupts for a long time. The interrupt disable time is directly proportional to the number of tasks waiting on the mutex. 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the resource(s) will no longer be guarded by the mutex. 4) IMPORTANT: In the 'OS_DEL_ALWAYS' case, we assume that the owner of the Mutex (if there is one) is ready-to-run and is thus NOT pending on another kernel object or has delayed itself.In other words, if a task owns the mutex being deleted,that task will be made ready-to-run at its original priority. */ tls_os_status_t tls_os_mutex_delete(tls_os_mutex_t *mutex); /** * @brief This function waits for a mutual exclusion semaphore * * @param[in] *mutex pointer to the event control block associated with the desired mutex * @param[in] wait_time an optional timeout period (in clock ticks). If non-zero, your task will wait for the resource up to the amount of time specified by this argument. If you specify 0, however, your task will wait forever at the specified mutex or, until the resource becomes available. * * @retval TLS_OS_SUCCESS The call was successful and your task owns the mutex * @retval TLS_OS_ERROR failed * * @note 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex. 2) You MUST NOT change the priority of the task that owns the mutex */ tls_os_status_t tls_os_mutex_acquire(tls_os_mutex_t *mutex, u32 wait_time); /** * @brief This function releases a mutual exclusion semaphore * * @param[in] *mutex pointer to the event control block associated with the desired mutex * * @retval TLS_OS_SUCCESS The call was successful and the mutex was signaled. * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_mutex_release(tls_os_mutex_t *mutex); /** * @brief This function creates a semaphore * * @param[in] **sem pointer to the event control block (OS_EVENT) associated with the created semaphore * @param[in] cnt the initial value for the semaphore. If the value is 0, no resource is available (or no event has occurred). You initialize the semaphore to a non-zero value to specify how many resources are available (e.g. if you have 10 resources, you would initialize the semaphore to 10). * * @retval TLS_OS_SUCCESS success,The call was successful * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_sem_create(tls_os_sem_t **sem, u32 cnt); /** * @brief This function deletes a semaphore and readies all tasks pending on this semaphore. * * @param[in] *sem pointer to the event control block associated with the desired semaphore * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_sem_delete(tls_os_sem_t *sem); /** * @brief This function waits for a semaphore * * @param[in] *sem pointer to the event control block associated with the desired semaphore * @param[in] wait_time an optional timeout period (in clock ticks). If non-zero, your task will wait for the resource up to the amount of time specified by this argument.If you specify 0, however, your task will wait forever at the specified semaphore or, until the resource becomes available (or the event occurs). * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_sem_acquire(tls_os_sem_t *sem, u32 wait_time); /** * @brief This function signals a semaphore * * @param[in] *sem pointer to the event control block associated with the desired semaphore * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_sem_release(tls_os_sem_t *sem); /** * @brief This function sets the semaphore count to the value specified as an argument.Typically,this value would be 0.You would typically use this function when a semaphore is used as a signaling mechanism and, you want to reset the count value. * * @param[in] *sem pointer to the event control block * @param[in] cnt the new value for the semaphore count. You would pass 0 to reset the semaphore count. * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_sem_set(tls_os_sem_t *sem, u16 cnt); u16 tls_os_sem_get_count(tls_os_sem_t *sem); /** * @brief This function creates a message queue if free event cont rol blocks are available * * @param[in] **queue pointer to the event control clock (OS_EVENT) associated with the created queue * @param[in] queue_size the number of elements in the storage area * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_queue_create(tls_os_queue_t **queue, u32 queue_size); /** * @brief This function deletes a message queue and readies all tasks pending on the queue * * @param[in] *queue pointer to the event control block associated with the desired queue * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_queue_delete(tls_os_queue_t *queue); /** * @brief This function sends a message to a queue * * @param[in] *queue pointer to the event control block associated with the desired queue * @param[in] *msg pointer to the message to send. * @param[in] msg_size message size * * @retval 0 success * @retval other failed * * @note None */ tls_os_status_t tls_os_queue_send(tls_os_queue_t *queue, void *msg, u32 msg_size); /** * @brief This function sends a message to a head of the queue * * @param[in] *queue pointer to the event control block associated with the desired queue * @param[in] *msg pointer to the message to send. * @param[in] msg_size message size * * @retval 0 success * @retval other failed * * @note None */ tls_os_status_t tls_os_queue_send_to_front(tls_os_queue_t *queue, void *msg, u32 msg_size); /** * @brief This function sends a message to a tail of the queue * * @param[in] *queue pointer to the event control block associated with the desired queue * @param[in] *msg pointer to the message to send. * @param[in] msg_size message size * * @retval 0 success * @retval other failed * * @note None */ tls_os_status_t tls_os_queue_send_to_back(tls_os_queue_t *queue, void *msg, u32 msg_size); /** * @brief This function is used to flush the contents of the message queue. * * @param[in] *queue * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_queue_flush(tls_os_queue_t *queue); /** * @brief This function waits for a message to be sent to a queue * * @param[in] *queue pointer to the event control block associated with the desired queue * @param[in] **msg pointer to the message received * @param[in] msg_size message size * @param[in] wait_time an optional timeout period (in clock ticks). If non-zero, your task will wait for a message to arrive at the queue up to the amount of time specified by this argument. If you specify 0, however, your task will wait forever at the specified queue or, until a message arrives. * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_queue_receive(tls_os_queue_t *queue,void **msg, u32 msg_size, u32 wait_time); u8 tls_os_queue_is_empty(tls_os_queue_t *queue); /** * @brief Return the number of free spaces available in a queue. This is equal to the * number of items that can be sent to the queue before the queue becomes full * if no items are removed. * * @param *queue pointer to the event control block associated with the desired queue * @return The number of spaces available in the queue. * @note None */ u32 tls_os_queue_space_available(tls_os_queue_t *queue); tls_os_status_t tls_os_queue_remove(tls_os_queue_t *queue, void* msg, u32 msg_size); /** * @brief This function creates a message mailbox if free event control blocks are available. * * @param[in] **mailbox pointer to the event control clock (OS_EVENT) associated with the created mailbox * @param[in] mailbox_size size * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_mailbox_create(tls_os_mailbox_t **mailbox, u32 mailbox_size); /** * @brief This function deletes a mailbox and readies all of the tasks pending on the this mailbox. * * @param[in] *mailbox pointer to the event control block associated with the desired mailbox. * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_mailbox_delete(tls_os_mailbox_t *mailbox); /** * @brief This function sends a message to a mailbox * * @param[in] *mailbox pointer to the event control block associated with the desired mailbox * @param[in] *msg pointer to the message to send. You MUST NOT send a NULL pointer * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_mailbox_send(tls_os_mailbox_t *mailbox,void *msg); /** * @brief This function waits for a message to be sent to a mailbox * * @param[in] *mailbox pointer to the event control block associated with the desired mailbox * @param[in] **msg pointer to the message received * @param[in] wait_time an optional timeout period (in clock ticks). If non-zero, your task will wait for a message to arrive at the mailbox up to the amount of time specified by this argument. If you specify 0, however, your task will wait forever at the specified mailbox or, until a message arrives. * * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_mailbox_receive(tls_os_mailbox_t *mailbox, void **msg, u32 wait_time); /** * @brief This function is used by your application to obtain the current value of the 32-bit counter which keeps track of the number of clock ticks since the system starts. * * @param[in] None * * @retval current value of OSTime * * @note None */ u32 tls_os_get_time(void); /** * @brief This function is used to disable interrupts by preserving the state of interrupts * * @param[in] None * * @retval cpu_sr * * @note None */ u32 tls_os_set_critical(void); /** * @brief This function is used to enable interrupts by preserving the state of interrupts * * @param[in] cpu_sr * * @return None * * @note None */ void tls_os_release_critical(u32 cpu_sr); /** * @brief This function is called by your application code to create a timer * * @param[in] **timer pointer to an OS_TMR data structure. This is the 'handle' that your application will use to reference the timer created * @param[in] callback pointer to a callback function that will be called when the timer expires. The callback function must be declared as follows void MyCallback (OS_TMR *ptmr, void *p_arg); * @param[in] *callback_arg argument (a pointer) that is passed to the callback function when it is called * @param[in] period The 'period' being repeated for the timer. If you specified 'OS_TMR_OPT_PERIODIC' as an option, when the timer expires, it will automatically restart with the same period. * @param[in] repeat if repeat * @param[in] *name pointer to an ASCII string that is used to name the timer. Names are useful for debugging. * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_timer_create(tls_os_timer_t **timer, TLS_OS_TIMER_CALLBACK callback, void *callback_arg, u32 period, bool repeat, u8 *name); /** * @brief This function is called by your application code to start a timer. * * @param[in] *timer pointer to an OS_TMR * * @return None * * @note None */ void tls_os_timer_start(tls_os_timer_t *timer); /* ************************************************************************************************************************ * CHANGE A TIMER WAIT TIME * * Description: This function is called by your application code to change a timer wait time. * * Arguments : timer Is a pointer to an OS_TMR * * ticks is the wait time ************************************************************************************************************************ */ void tls_os_timer_change(tls_os_timer_t *timer, u32 ticks); /** * @brief This function is called by your application code to stop a timer * * @param[in] *timer pointer to the timer to stop. * * @return None * * @note None */ void tls_os_timer_stop(tls_os_timer_t *timer); /** * @brief This function is called by your application code to delete a timer * * @param[in] *timer pointer to the timer to delete * * @retval TLS_OS_SUCCESS success * @retval TLS_OS_ERROR failed * * @note None */ tls_os_status_t tls_os_timer_delete(tls_os_timer_t *timer); /** * @brief This function is called to delay execution of the currently running task until the specified number of system ticks expires. This, of course, directly equates to delaying the current task for some time to expire. There will be no delay if the specified delay is 0. If the specified delay is greater than 0 then, a context switch will executed. * * @param[in] ticks the time delay that the task will be suspended in number of clock 'ticks'.Note that by specifying 0, the task will not be delayed. * * @return None * * @note None */ void tls_os_time_delay(u32 ticks); void tls_os_time_delay_until(u32 * const previous_wake_time, const u32 duration_in_ticks); u8 tls_os_timer_active(tls_os_timer_t *timer); u32 tls_os_timer_expirytime(tls_os_timer_t *timer); /** * @brief This function is used to display all the tasks' detail status. * * @param[in] None * * @return None * * @note None */ void tls_os_disp_task_stat_info(void); u8 tls_get_isr_count(void); /** * @} */ /** * @} */ #endif /* end of WM_OSAL_H */