first init

This commit is contained in:
supowang
2024-01-03 11:19:04 +08:00
parent 837003ea32
commit 40be5eb96d
341 changed files with 93068 additions and 32 deletions

31
osal/Makefile Normal file
View File

@@ -0,0 +1,31 @@
###################################################################
#automatic detection QTOP and LOCALDIR
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
echo $$QTOP;\
else\
cd $(CUR_DIR); while /usr/bin/test ! -e qmk ; do \
dir=`cd ../;pwd`; \
if [ "$$dir" = "/" ] ; then \
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
exit 1; \
fi ; \
cd $$dir; \
done ; \
pwd; \
fi)
QTOP ?= $(realpath ${TRYQTOP})
ifeq ($(QTOP),)
$(error Please run this in a tree)
endif
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
####################################################################
TREE_LIB_ENABLE=0
lib=
subdirs = cmsis_os
include ${QTOP}/qmk/generic/Make.tpl

34
osal/cmsis_os/Makefile Normal file
View File

@@ -0,0 +1,34 @@
###################################################################
#automatic detection QTOP and LOCALDIR
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
echo $$QTOP;\
else\
cd $(CUR_DIR); while /usr/bin/test ! -d qmk ; do \
dir=`cd ../;pwd`; \
if [ "$$dir" = "/" ] ; then \
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
exit 1; \
fi ; \
cd $$dir; \
done ; \
pwd; \
fi)
QTOP ?= $(realpath ${TRYQTOP})
ifeq ($(QTOP),)
$(error Please run this in a tree)
endif
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
####################################################################
TREE_LIB_ENABLE=0
lib=
subdirs=
include ${QTOP}/qmk/generic/Make.tpl

509
osal/cmsis_os/cmsis_os.c Normal file
View File

@@ -0,0 +1,509 @@
#include <string.h>
#include "cmsis_os.h"
static k_prio_t priority_cmsis2knl(osPriority prio)
{
if (prio == osPriorityError) {
return K_TASK_PRIO_INVALID;
}
return (k_prio_t)(3 - prio);
}
static osPriority priority_knl2cmsis(k_prio_t prio)
{
return (osPriority)(3 - prio);
}
static osStatus errno_knl2cmsis(k_err_t err)
{
return err == K_ERR_NONE ? osOK : osErrorOS;
}
// ==== Kernel Control Functions ====
osStatus osKernelStart(void)
{
return errno_knl2cmsis(tos_knl_start());
}
/**
* @brief Initialize the RTOS Kernel for creating objects.
* @return status code that indicates the execution status of the function.
*/
osStatus osKernelInitialize(void)
{
return errno_knl2cmsis(tos_knl_init());
}
/**
* @brief Check if the RTOS kernel is already started.
* @retval #0 RTOS is not started
* @retval #1 RTOS is started.
*/
int32_t osKernelRunning(void)
{
return tos_knl_is_running();
}
#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
/**
* @brief Get the RTOS kernel system timer counter
* @return RTOS kernel system timer as 32-bit value
*/
uint32_t osKernelSysTick(void)
{
return tos_systick_get();
}
#endif
// ==== Thread Management ====
/**
* @brief Create a thread and add it to Active Threads and set it to state READY.
* @param[in] thread_def thread definition referenced with \ref osThread.
* @param[in] argument pointer that is passed to the thread function as start argument.
* @return thread ID for reference by other functions or NULL in case of error.
*/
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument)
{
k_err_t err;
if (!thread_def) {
return NULL;
}
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
if (!thread_def->stackbase && !thread_def->task) {
k_task_t *task;
err = tos_task_create_dyn(&task, thread_def->name, (k_task_entry_t)thread_def->pthread,
argument, priority_cmsis2knl(thread_def->tpriority),
thread_def->stacksize, thread_def->timeslice);
return err == K_ERR_NONE ? task : NULL;
}
#endif
err = tos_task_create((k_task_t *)thread_def->task, thread_def->name, (k_task_entry_t)thread_def->pthread,
argument, priority_cmsis2knl(thread_def->tpriority), thread_def->stackbase,
thread_def->stacksize, thread_def->timeslice);
return err == K_ERR_NONE ? thread_def->task : NULL;
}
/**
* @brief Return the thread ID of the current running thread.
* @return thread ID for reference by other functions or NULL in case of error.
*/
osThreadId osThreadGetId(void)
{
return k_curr_task;
}
/**
* @brief Terminate execution of a thread and remove it from Active Threads.
* @param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
* @return status code that indicates the execution status of the function.
*/
osStatus osThreadTerminate(osThreadId thread_id)
{
return errno_knl2cmsis(tos_task_destroy((k_task_t *)thread_id));
}
/**
* @brief Change priority of an active thread.
* @param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
* @param[in] priority new priority value for the thread function.
* @return status code that indicates the execution status of the function.
*/
osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority)
{
return errno_knl2cmsis(tos_task_prio_change((k_task_t *)thread_id, priority_cmsis2knl(priority)));
}
/**
* @brief Pass control to next thread that is in state READY.
* @return status code that indicates the execution status of the function.
*/
osStatus osThreadYield(void)
{
tos_task_yield();
return osOK;
}
/**
* @brief Get current priority of an active thread.
* @param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
* @return current priority value of the thread function.
*/
osPriority osThreadGetPriority(osThreadId thread_id)
{
if (!thread_id) {
return osPriorityError;
}
return priority_knl2cmsis(((k_task_t *)thread_id)->prio);
}
// ==== Generic Wait Functions ====
/**
* @brief Wait for Timeout (Time Delay)
* @param[in] millisec time delay value
* @return status code that indicates the execution status of the function.
*/
osStatus osDelay(uint32_t millisec)
{
k_tick_t delay;
if (millisec == osWaitForever) {
delay = TOS_TIME_FOREVER;
} else {
delay = tos_millisec2tick(millisec);
}
return errno_knl2cmsis(tos_task_delay(delay));
}
#if TOS_CFG_TIMER_EN > 0
/**
* @brief Create a timer.
* @param[in] timer_def timer object referenced with \ref osTimer.
* @param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
* @param[in] argument argument to the timer call back function.
* @return timer ID for reference by other functions or NULL in case of error.
*/
osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type, void *argument)
{
k_err_t err;
k_opt_t opt = TOS_OPT_TIMER_ONESHOT;
if (!timer_def) {
return NULL;
}
if (type == osTimerPeriodic) {
opt = TOS_OPT_TIMER_PERIODIC;
}
err = tos_timer_create((k_timer_t *)timer_def->timer, (k_tick_t)1u,
(k_tick_t)3000u, (k_timer_callback_t)timer_def->cb, argument, opt);
return err == K_ERR_NONE ? timer_def->timer : NULL;
}
/**
* @brief Start or restart a timer.
* @param[in] timer_id timer ID obtained by \ref osTimerCreate.
* @param[in] millisec time delay value of the timer.
* @return status code that indicates the execution status of the function.
*/
osStatus osTimerStart(osTimerId timer_id, uint32_t millisec)
{
k_timer_t *timer;
k_tick_t delay;
if (!timer_id) {
return osErrorResource;
}
if (millisec == 0) {
delay = (k_tick_t)1u;
} else if (millisec == osWaitForever) {
delay = TOS_TIME_FOREVER;
} else {
delay = tos_millisec2tick(millisec);
}
timer = (k_timer_t *)timer_id;
timer->delay = delay;
timer->period = delay;
return errno_knl2cmsis(tos_timer_start(timer));
}
/**
* @brief Stop the timer.
* @param[in] timer_id timer ID obtained by \ref osTimerCreate.
* @return status code that indicates the execution status of the function.
*/
osStatus osTimerStop(osTimerId timer_id)
{
return errno_knl2cmsis(tos_timer_stop((k_timer_t *)timer_id));
}
/**
* @brief Delete a timer that was created by \ref osTimerCreate.
* @param[in] timer_id timer ID obtained by \ref osTimerCreate.
* @return status code that indicates the execution status of the function.
*/
osStatus osTimerDelete(osTimerId timer_id)
{
return errno_knl2cmsis(tos_timer_destroy((k_timer_t *)timer_id));
}
#endif // TOS_CFG_TIMER_EN
#if TOS_CFG_MUTEX_EN > 0
/**
* @brief Create and Initialize a Mutex object
* @param[in] mutex_def mutex definition referenced with \ref osMutex.
* @return mutex ID for reference by other functions or NULL in case of error.
*/
osMutexId osMutexCreate(const osMutexDef_t *mutex_def)
{
k_err_t err;
if (!mutex_def) {
return NULL;
}
err = tos_mutex_create((k_mutex_t *)mutex_def->mutex);
return err == K_ERR_NONE ? mutex_def->mutex : NULL;
}
/**
* @brief Wait until a Mutex becomes available
* @param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
* @param[in] millisec timeout value or 0 in case of no time-out.
* @return status code that indicates the execution status of the function.
*/
osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec)
{
k_tick_t timeout;
if (millisec == osWaitForever) {
timeout = TOS_TIME_FOREVER;
} else {
timeout = tos_millisec2tick(millisec);
}
return errno_knl2cmsis(tos_mutex_pend_timed((k_mutex_t *)mutex_id, timeout));
}
/**
* @brief Release a Mutex that was obtained by \ref osMutexWait
* @param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
* @return status code that indicates the execution status of the function.
*/
osStatus osMutexRelease(osMutexId mutex_id)
{
return errno_knl2cmsis(tos_mutex_post((k_mutex_t *)mutex_id));
}
/**
* @brief Delete a Mutex that was created by \ref osMutexCreate.
* @param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
* @return status code that indicates the execution status of the function.
*/
osStatus osMutexDelete(osMutexId mutex_id)
{
return errno_knl2cmsis(tos_mutex_destroy((k_mutex_t *)mutex_id));
}
#endif // TOS_CFG_MUTEX_EN
#if TOS_CFG_SEM_EN > 0
/**
* @brief Create and Initialize a Semaphore object used for managing resources
* @param[in] semaphore_def semaphore definition referenced with \ref osSemaphore.
* @param[in] count number of available resources.
* @return semaphore ID for reference by other functions or NULL in case of error.
*/
osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, int32_t count)
{
k_err_t err;
if (!semaphore_def) {
return NULL;
}
err = tos_sem_create((k_sem_t *)semaphore_def->sem, count);
return err == K_ERR_NONE ? (k_sem_t *)semaphore_def->sem : NULL;
}
/**
* @brief Wait until a Semaphore token becomes available
* @param[in] semaphore_id semaphore object referenced with \ref osSemaphore.
* @param[in] millisec timeout value or 0 in case of no time-out.
* @return number of available tokens, or -1 in case of incorrect parameters.
*/
int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec)
{
k_err_t err;
k_tick_t timeout;
if (millisec == osWaitForever) {
timeout = TOS_TIME_FOREVER;
} else {
timeout = tos_millisec2tick(millisec);
}
err = tos_sem_pend((k_sem_t *)semaphore_id, timeout);
return err == K_ERR_NONE ? ((k_sem_t *)semaphore_id)->count : -1;
}
/**
* @brief Release a Semaphore token
* @param[in] semaphore_id semaphore object referenced with \ref osSemaphore.
* @return status code that indicates the execution status of the function.
*/
osStatus osSemaphoreRelease(osSemaphoreId semaphore_id)
{
return errno_knl2cmsis(tos_sem_post((k_sem_t *)semaphore_id));
}
/**
* @brief Delete a Semaphore that was created by \ref osSemaphoreCreate.
* @param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
* @return status code that indicates the execution status of the function.
*/
osStatus osSemaphoreDelete(osSemaphoreId semaphore_id)
{
return errno_knl2cmsis(tos_sem_destroy((k_sem_t *)semaphore_id));
}
#endif // TOS_CFG_SEM_EN
// ==== Memory Pool Management Functions ====
#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available
/**
* @brief Create and Initialize a memory pool
* @param[in] pool_def memory pool definition referenced with \ref osPool.
* @return memory pool ID for reference by other functions or NULL in case of error.
*/
osPoolId osPoolCreate(const osPoolDef_t *pool_def)
{
k_err_t err;
if (!pool_def) {
return NULL;
}
err = tos_mmblk_pool_create((k_mmblk_pool_t *)pool_def->mmblk_pool,
pool_def->pool, pool_def->pool_sz, pool_def->item_sz);
return err == K_ERR_NONE ? pool_def->mmblk_pool : NULL;
}
/**
* @brief Allocate a memory block from a memory pool
* @param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
* @return address of the allocated memory block or NULL in case of no memory available.
*/
void *osPoolAlloc(osPoolId pool_id)
{
k_err_t err;
void *ptr = NULL;
err = tos_mmblk_alloc((k_mmblk_pool_t *)pool_id, &ptr);
return err == K_ERR_NONE ? ptr : NULL;
}
/**
* @brief Allocate a memory block from a memory pool and set memory block to zero
* @param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
* @return address of the allocated memory block or NULL in case of no memory available.
*/
void *osPoolCAlloc(osPoolId pool_id)
{
k_err_t err;
void *ptr = NULL;
err = tos_mmblk_alloc((k_mmblk_pool_t *)pool_id, &ptr);
if (err == K_ERR_NONE) {
memset(ptr, 0, ((k_mmblk_pool_t *)pool_id)->blk_size);
return ptr;
}
return NULL;
}
/**
* @brief Return an allocated memory block back to a specific memory pool
* @param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
* @param[in] block address of the allocated memory block that is returned to the memory pool.
* @return status code that indicates the execution status of the function.
*/
osStatus osPoolFree(osPoolId pool_id, void *block)
{
return errno_knl2cmsis(tos_mmblk_free((k_mmblk_pool_t *)pool_id, block));
}
#endif // Memory Pool Management available
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
// ==== Message Queue Management Functions ====
#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available
/**
* @brief Create and Initialize a Message Queue.
* @param[in] queue_def queue definition referenced with \ref osMessageQ.
* @param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
* @return message queue ID for reference by other functions or NULL in case of error.
*/
osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, osThreadId thread_id)
{
k_err_t err;
if (!queue_def) {
return NULL;
}
thread_id = thread_id; // make compiler happy
err = tos_msg_q_create((k_msg_q_t *)queue_def->queue, queue_def->pool, queue_def->queue_sz);
return err == K_ERR_NONE ? (k_msg_q_t *)queue_def->queue : NULL;
}
/**
* @brief Put a Message to a Queue.
* @param[in] queue_id message queue ID obtained with \ref osMessageCreate.
* @param[in] info message information.
* @param[in] millisec timeout value or 0 in case of no time-out.
* @return status code that indicates the execution status of the function.
*/
osStatus osMessagePut(osMessageQId queue_id, uint32_t info, uint32_t millisec)
{
return errno_knl2cmsis(tos_msg_q_post((k_msg_q_t *)queue_id, (uint32_t*)info));
}
/**
* @brief Get a Message or Wait for a Message from a Queue.
* @param[in] queue_id message queue ID obtained with \ref osMessageCreate.
* @param[in] millisec timeout value or 0 in case of no time-out.
* @return event information that includes status code.
*/
osEvent osMessageGet(osMessageQId queue_id, uint32_t millisec)
{
osEvent event;
k_err_t err;
k_tick_t timeout;
void *msg_body = NULL;
if (millisec == osWaitForever) {
timeout = TOS_TIME_FOREVER;
} else {
timeout = tos_millisec2tick(millisec);
}
err = tos_msg_q_pend((k_msg_q_t *)queue_id, &msg_body, timeout);
if (err == K_ERR_NONE) {
event.def.message_id = queue_id;
event.status = errno_knl2cmsis(err);
event.value.v = (uint32_t)msg_body;
} else {
event.def.message_id = NULL;
event.status = osErrorOS;
}
return event;
}
#endif // Message Queues available
#endif // TOS_CFG_MESSAGE_QUEUE_EN

846
osal/cmsis_os/cmsis_os.h Normal file
View File

@@ -0,0 +1,846 @@
/* ----------------------------------------------------------------------
* $Date: 5. February 2013
* $Revision: V1.02
*
* Project: CMSIS-RTOS API
* Title: cmsis_os.h template header file
*
* Version 0.02
* Initial Proposal Phase
* Version 0.03
* osKernelStart added, optional feature: main started as thread
* osSemaphores have standard behavior
* osTimerCreate does not start the timer, added osTimerStart
* osThreadPass is renamed to osThreadYield
* Version 1.01
* Support for C++ interface
* - const attribute removed from the osXxxxDef_t typedef's
* - const attribute added to the osXxxxDef macros
* Added: osTimerDelete, osMutexDelete, osSemaphoreDelete
* Added: osKernelInitialize
* Version 1.02
* Control functions for short timeouts in microsecond resolution:
* Added: osKernelSysTick, osKernelSysTickFrequency, osKernelSysTickMicroSec
* Removed: osSignalGet
*----------------------------------------------------------------------------
*
* Copyright (c) 2013 ARM LIMITED
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - Neither the name of ARM nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*---------------------------------------------------------------------------*/
/**
\page cmsis_os_h Header File Template: cmsis_os.h
The file \b cmsis_os.h is a template header file for a CMSIS-RTOS compliant Real-Time Operating System (RTOS).
Each RTOS that is compliant with CMSIS-RTOS shall provide a specific \b cmsis_os.h header file that represents
its implementation.
The file cmsis_os.h contains:
- CMSIS-RTOS API function definitions
- struct definitions for parameters and return types
- status and priority values used by CMSIS-RTOS API functions
- macros for defining threads and other kernel objects
<b>Name conventions and header file modifications</b>
All definitions are prefixed with \b os to give an unique name space for CMSIS-RTOS functions.
Definitions that are prefixed \b os_ are not used in the application code but local to this header file.
All definitions and functions that belong to a module are grouped and have a common prefix, i.e. \b osThread.
Definitions that are marked with <b>CAN BE CHANGED</b> can be adapted towards the needs of the actual CMSIS-RTOS implementation.
These definitions can be specific to the underlying RTOS kernel.
Definitions that are marked with <b>MUST REMAIN UNCHANGED</b> cannot be altered. Otherwise the CMSIS-RTOS implementation is no longer
compliant to the standard. Note that some functions are optional and need not to be provided by every CMSIS-RTOS implementation.
<b>Function calls from interrupt service routines</b>
The following CMSIS-RTOS functions can be called from threads and interrupt service routines (ISR):
- \ref osSignalSet
- \ref osSemaphoreRelease
- \ref osPoolAlloc, \ref osPoolCAlloc, \ref osPoolFree
- \ref osMessagePut, \ref osMessageGet
- \ref osMailAlloc, \ref osMailCAlloc, \ref osMailGet, \ref osMailPut, \ref osMailFree
Functions that cannot be called from an ISR are verifying the interrupt status and return in case that they are called
from an ISR context the status code \b osErrorISR. In some implementations this condition might be caught using the HARD FAULT vector.
Some CMSIS-RTOS implementations support CMSIS-RTOS function calls from multiple ISR at the same time.
If this is impossible, the CMSIS-RTOS rejects calls by nested ISR functions with the status code \b osErrorISRRecursive.
<b>Define and reference object definitions</b>
With <b>\#define osObjectsExternal</b> objects are defined as external symbols. This allows to create a consistent header file
that is used throughout a project as shown below:
<i>Header File</i>
\code
#include <cmsis_os.h> // CMSIS RTOS header file
// Thread definition
extern void thread_sample (void const *argument); // function prototype
osThreadDef (thread_sample, osPriorityBelowNormal, 1, 100);
// Pool definition
osPoolDef(MyPool, 10, long);
\endcode
This header file defines all objects when included in a C/C++ source file. When <b>\#define osObjectsExternal</b> is
present before the header file, the objects are defined as external symbols. A single consistent header file can therefore be
used throughout the whole project.
<i>Example</i>
\code
#include "osObjects.h" // Definition of the CMSIS-RTOS objects
\endcode
\code
#define osObjectExternal // Objects will be defined as external symbols
#include "osObjects.h" // Reference to the CMSIS-RTOS objects
\endcode
*/
#ifndef _CMSIS_OS_H
#define _CMSIS_OS_H
/// \note MUST REMAIN UNCHANGED: \b osCMSIS identifies the CMSIS-RTOS API version.
#define osCMSIS 0x10002 ///< API version (main [31:16] .sub [15:0])
/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
#define osCMSIS_KERNEL 0x10000 ///< RTOS identification and version (main [31:16] .sub [15:0])
/// \note MUST REMAIN UNCHANGED: \b osKernelSystemId shall be consistent in every CMSIS-RTOS.
#define osKernelSystemId "TencentOS tiny V1.00" ///< RTOS identification string
/// \note MUST REMAIN UNCHANGED: \b osFeature_xxx shall be consistent in every CMSIS-RTOS.
#define osFeature_MainThread 1 ///< main thread 1=main can be thread, 0=not available
#define osFeature_Pool 1 ///< Memory Pools: 1=available, 0=not available
#define osFeature_MailQ 1 ///< Mail Queues: 1=available, 0=not available
#define osFeature_MessageQ 1 ///< Message Queues: 1=available, 0=not available
#define osFeature_Signals 0 ///< maximum number of Signal Flags available per thread
#define osFeature_Semaphore 30 ///< maximum count for \ref osSemaphoreCreate function
#define osFeature_Wait 0 ///< osWait function: 1=available, 0=not available
#define osFeature_SysTick 1 ///< osKernelSysTick functions: 1=available, 0=not available
#include <stdint.h>
#include <stddef.h>
#include "tos_k.h"
#ifdef __cplusplus
extern "C" {
#endif
// ==== Enumeration, structures, defines ====
/// Priority used for thread control.
/// \note MUST REMAIN UNCHANGED: \b osPriority shall be consistent in every CMSIS-RTOS.
typedef enum {
osPriorityIdle = -3, ///< priority: idle (lowest)
osPriorityLow = -2, ///< priority: low
osPriorityBelowNormal = -1, ///< priority: below normal
osPriorityNormal = 0, ///< priority: normal (default)
osPriorityAboveNormal = +1, ///< priority: above normal
osPriorityHigh = +2, ///< priority: high
osPriorityRealtime = +3, ///< priority: realtime (highest)
osPriorityError = 0x84 ///< system cannot determine priority or thread has illegal priority
} osPriority;
/// Timeout value.
/// \note MUST REMAIN UNCHANGED: \b osWaitForever shall be consistent in every CMSIS-RTOS.
#define osWaitForever 0xFFFFFFFF ///< wait forever timeout value
/// Status code values returned by CMSIS-RTOS functions.
/// \note MUST REMAIN UNCHANGED: \b osStatus shall be consistent in every CMSIS-RTOS.
typedef enum {
osOK = 0, ///< function completed; no error or event occurred.
osEventSignal = 0x08, ///< function completed; signal event occurred.
osEventMessage = 0x10, ///< function completed; message event occurred.
osEventMail = 0x20, ///< function completed; mail event occurred.
osEventTimeout = 0x40, ///< function completed; timeout occurred.
osErrorParameter = 0x80, ///< parameter error: a mandatory parameter was missing or specified an incorrect object.
osErrorResource = 0x81, ///< resource not available: a specified resource was not available.
osErrorTimeoutResource = 0xC1, ///< resource not available within given time: a specified resource was not available within the timeout period.
osErrorISR = 0x82, ///< not allowed in ISR context: the function cannot be called from interrupt service routines.
osErrorISRRecursive = 0x83, ///< function called multiple times from ISR with same object.
osErrorPriority = 0x84, ///< system cannot determine priority or thread has illegal priority.
osErrorNoMemory = 0x85, ///< system is out of memory: it was impossible to allocate or reserve memory for the operation.
osErrorValue = 0x86, ///< value of a parameter is out of range.
osErrorOS = 0xFF, ///< unspecified RTOS error: run-time error but no other error message fits.
os_status_reserved = 0x7FFFFFFF ///< prevent from enum down-size compiler optimization.
} osStatus;
/// Timer type value for the timer definition.
/// \note MUST REMAIN UNCHANGED: \b os_timer_type shall be consistent in every CMSIS-RTOS.
typedef enum {
osTimerOnce = 0, ///< one-shot timer
osTimerPeriodic = 1 ///< repeating timer
} os_timer_type;
/// Entry point of a thread.
/// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS.
typedef void (*os_pthread) (void const *argument);
/// Entry point of a timer call back function.
/// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS.
typedef void (*os_ptimer) (void const *argument);
// >>> the following data type definitions may shall adapted towards a specific RTOS
/// Thread ID identifies the thread (pointer to a thread control block).
/// \note CAN BE CHANGED: \b os_thread_cb is implementation specific in every CMSIS-RTOS.
typedef k_task_t *osThreadId;
/// Timer ID identifies the timer (pointer to a timer control block).
/// \note CAN BE CHANGED: \b os_timer_cb is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_TIMER_EN > 0u
typedef k_timer_t *osTimerId;
#endif
/// Mutex ID identifies the mutex (pointer to a mutex control block).
/// \note CAN BE CHANGED: \b os_mutex_cb is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_MUTEX_EN > 0u
typedef k_mutex_t *osMutexId;
#endif
/// Semaphore ID identifies the semaphore (pointer to a semaphore control block).
/// \note CAN BE CHANGED: \b os_semaphore_cb is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_SEM_EN > 0u
typedef k_sem_t *osSemaphoreId;
#endif
/// Pool ID identifies the memory pool (pointer to a memory pool control block).
/// \note CAN BE CHANGED: \b os_pool_cb is implementation specific in every CMSIS-RTOS.
typedef k_mmblk_pool_t *osPoolId;
/// Message ID identifies the message queue (pointer to a message queue control block).
/// \note CAN BE CHANGED: \b os_messageQ_cb is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
typedef k_msg_q_t *osMessageQId;
#endif
/// Mail ID identifies the mail queue (pointer to a mail queue control block).
/// \note CAN BE CHANGED: \b os_mailQ_cb is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_MAIL_QUEUE_EN > 0u
typedef k_mail_q_t *osMailQId;
#endif
/// Thread Definition structure contains startup information of a thread.
/// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS.
typedef struct os_thread_def {
char *name; ///< Thread name
os_pthread pthread; ///< start address of thread function
osPriority tpriority; ///< initial thread priority
uint32_t instances; ///< maximum number of instances of that thread function
k_stack_t *stackbase; ///< base address of task
uint32_t stacksize; ///< stack size requirements in bytes; 0 is default stack size
k_timeslice_t timeslice; ///< timeslice
k_task_t *task;
} osThreadDef_t;
/// Timer Definition structure contains timer parameters.
/// \note CAN BE CHANGED: \b os_timer_def is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_TIMER_EN > 0u
typedef struct os_timer_def {
os_ptimer cb; ///< start address of a timer function
k_timer_t *timer;
} osTimerDef_t;
#endif
/// Mutex Definition structure contains setup information for a mutex.
/// \note CAN BE CHANGED: \b os_mutex_def is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_MUTEX_EN > 0u
typedef struct os_mutex_def {
uint32_t dummy; ///< dummy value.
k_mutex_t *mutex;
} osMutexDef_t;
#endif
/// Semaphore Definition structure contains setup information for a semaphore.
/// \note CAN BE CHANGED: \b os_semaphore_def is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_SEM_EN > 0u
typedef struct os_semaphore_def {
uint32_t dummy; ///< dummy value.
k_sem_t *sem;
} osSemaphoreDef_t;
#endif
/// Definition structure for memory block allocation.
/// \note CAN BE CHANGED: \b os_pool_def is implementation specific in every CMSIS-RTOS.
typedef struct os_pool_def {
uint32_t pool_sz; ///< number of items (elements) in the pool
uint32_t item_sz; ///< size of an item
void *pool; ///< pointer to memory for pool
k_mmblk_pool_t *mmblk_pool; ///< memory blk pool handler
} osPoolDef_t;
/// Definition structure for message queue.
/// \note CAN BE CHANGED: \b os_messageQ_def is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
typedef struct os_messageQ_def {
uint32_t queue_sz; ///< number of elements in the queue
uint32_t item_sz; ///< size of an item
void *pool; ///< memory array for messages
k_msg_q_t *queue; ///< queue handler
} osMessageQDef_t;
#endif // TOS_CFG_MESSAGE_QUEUE_EN
/// Definition structure for mail queue.
/// \note CAN BE CHANGED: \b os_mailQ_def is implementation specific in every CMSIS-RTOS.
#if TOS_CFG_MAIL_QUEUE_EN > 0u
typedef struct os_mailQ_def {
uint32_t queue_sz; ///< number of elements in the queue
uint32_t item_sz; ///< size of an item
void *pool; ///< memory array for mail
} osMailQDef_t;
#endif // TOS_CFG_MAIL_QUEUE_EN
/// Event structure contains detailed information about an event.
/// \note MUST REMAIN UNCHANGED: \b os_event shall be consistent in every CMSIS-RTOS.
/// However the struct may be extended at the end.
#if (TOS_CFG_MAIL_QUEUE_EN > 0u) || (TOS_CFG_MESSAGE_QUEUE_EN > 0u)
typedef struct {
osStatus status; ///< status code: event or error information
union {
uint32_t v; ///< message as 32-bit value
void *p; ///< message or mail as void pointer
int32_t signals; ///< signal flags
} value; ///< event value
union {
#if TOS_CFG_MAIL_QUEUE_EN > 0u
osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
#endif
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
#endif
} def; ///< event definition
} osEvent;
#endif
// ==== Kernel Control Functions ====
/// Initialize the RTOS Kernel for creating objects.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osKernelInitialize shall be consistent in every CMSIS-RTOS.
osStatus osKernelInitialize(void);
/// Start the RTOS Kernel.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osKernelStart shall be consistent in every CMSIS-RTOS.
osStatus osKernelStart(void);
/// Check if the RTOS kernel is already started.
/// \note MUST REMAIN UNCHANGED: \b osKernelRunning shall be consistent in every CMSIS-RTOS.
/// \return 0 RTOS is not started, 1 RTOS is started.
int32_t osKernelRunning(void);
#if (defined (osFeature_SysTick) && (osFeature_SysTick != 0)) // System Timer available
/// Get the RTOS kernel system timer counter
/// \note MUST REMAIN UNCHANGED: \b osKernelSysTick shall be consistent in every CMSIS-RTOS.
/// \return RTOS kernel system timer as 32-bit value
uint32_t osKernelSysTick(void);
/// The RTOS kernel system timer frequency in Hz
/// \note Reflects the system timer setting and is typically defined in a configuration file.
#define osKernelSysTickFrequency TOS_CFG_CPU_CLOCK
/// Convert a microseconds value to a RTOS kernel system timer value.
/// \param microsec time value in microseconds.
/// \return time value normalized to the \ref osKernelSysTickFrequency
#define osKernelSysTickMicroSec(microsec) (((k_tick_t)microsec * (osKernelSysTickFrequency)) / 1000000)
#endif // System Timer available
// ==== Thread Management ====
/// Create a Thread Definition with function, priority, and stack requirements.
/// \param name name of the thread function.
/// \param priority initial priority of the thread function.
/// \param instances number of possible thread instances.
/// \param stacksz stack size (in bytes) requirements for the thread function.
/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osThreadDef(name, priority, instances, stacksz) \
extern const osThreadDef_t os_thread_def_##name
#else // define the object
#define osThreadDef(name, priority, instances, stacksz) \
k_task_t task_handler_##name; \
k_stack_t task_stack_##name[(stacksz)]; \
const osThreadDef_t os_thread_def_##name = \
{ #name, (os_pthread)(name), (osPriority)(priority), (instances), \
(&((task_stack_##name)[0])), (stacksz), ((k_timeslice_t)0u), (&(task_handler_##name)) }
#if (TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u)
#define osThreadDynamicDef(name, priority, instances, stacksz) \
const osThreadDef_t os_thread_def_##name = \
{ #name, (os_pthread)(name), (osPriority)(priority), (instances), \
(K_NULL), (stacksz), ((k_timeslice_t)0u), (K_NULL) }
#endif
#endif
/// Access a Thread definition.
/// \param name name of the thread definition object.
/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osThread(name) \
&os_thread_def_##name
/// Create a thread and add it to Active Threads and set it to state READY.
/// \param[in] thread_def thread definition referenced with \ref osThread.
/// \param[in] argument pointer that is passed to the thread function as start argument.
/// \return thread ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osThreadCreate shall be consistent in every CMSIS-RTOS.
osThreadId osThreadCreate(const osThreadDef_t *thread_def, void *argument);
/// Return the thread ID of the current running thread.
/// \return thread ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osThreadGetId shall be consistent in every CMSIS-RTOS.
osThreadId osThreadGetId(void);
/// Terminate execution of a thread and remove it from Active Threads.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osThreadTerminate shall be consistent in every CMSIS-RTOS.
osStatus osThreadTerminate(osThreadId thread_id);
/// Pass control to next thread that is in state \b READY.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osThreadYield shall be consistent in every CMSIS-RTOS.
osStatus osThreadYield(void);
/// Change priority of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in] priority new priority value for the thread function.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osThreadSetPriority shall be consistent in every CMSIS-RTOS.
osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority);
/// Get current priority of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \return current priority value of the thread function.
/// \note MUST REMAIN UNCHANGED: \b osThreadGetPriority shall be consistent in every CMSIS-RTOS.
osPriority osThreadGetPriority(osThreadId thread_id);
// ==== Generic Wait Functions ====
/// Wait for Timeout (Time Delay).
/// \param[in] millisec time delay value
/// \return status code that indicates the execution status of the function.
osStatus osDelay(uint32_t millisec);
#if (defined (osFeature_Wait) && (osFeature_Wait != 0)) // Generic Wait available
/// Wait for Signal, Message, Mail, or Timeout.
/// \param[in] millisec timeout value or 0 in case of no time-out
/// \return event that contains signal, message, or mail information or error code.
/// \note MUST REMAIN UNCHANGED: \b osWait shall be consistent in every CMSIS-RTOS.
osEvent osWait(uint32_t millisec);
#endif // Generic Wait available
#if TOS_CFG_TIMER_EN > 0u
// ==== Timer Management Functions ====
/// Define a Timer object.
/// \param name name of the timer object.
/// \param function name of the timer call back function.
/// \note CAN BE CHANGED: The parameter to \b osTimerDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osTimerDef(name, function) \
extern const osTimerDef_t os_timer_def_##name
#else // define the object
#define osTimerDef(name, function) \
k_timer_t timer_handler_##name; \
const osTimerDef_t os_timer_def_##name = \
{ (os_ptimer)(function), (&(timer_handler_##name)) }
#endif
/// Access a Timer definition.
/// \param name name of the timer object.
/// \note CAN BE CHANGED: The parameter to \b osTimer shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osTimer(name) \
&os_timer_def_##name
/// Create a timer.
/// \param[in] timer_def timer object referenced with \ref osTimer.
/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
/// \param[in] argument argument to the timer call back function.
/// \return timer ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osTimerCreate shall be consistent in every CMSIS-RTOS.
osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type, void *argument);
/// Start or restart a timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
/// \param[in] millisec time delay value of the timer.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osTimerStart shall be consistent in every CMSIS-RTOS.
osStatus osTimerStart(osTimerId timer_id, uint32_t millisec);
/// Stop the timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osTimerStop shall be consistent in every CMSIS-RTOS.
osStatus osTimerStop(osTimerId timer_id);
/// Delete a timer that was created by \ref osTimerCreate.
/// \param[in] timer_id timer ID obtained by \ref osTimerCreate.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osTimerDelete shall be consistent in every CMSIS-RTOS.
osStatus osTimerDelete(osTimerId timer_id);
#endif // TOS_CFG_TIMER_EN
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
// ==== Signal Management ====
/// Set the specified Signal Flags of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in] signals specifies the signal flags of the thread that should be set.
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
/// \note MUST REMAIN UNCHANGED: \b osSignalSet shall be consistent in every CMSIS-RTOS.
int32_t osSignalSet(osThreadId thread_id, int32_t signals);
/// Clear the specified Signal Flags of an active thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadCreate or \ref osThreadGetId.
/// \param[in] signals specifies the signal flags of the thread that shall be cleared.
/// \return previous signal flags of the specified thread or 0x80000000 in case of incorrect parameters.
/// \note MUST REMAIN UNCHANGED: \b osSignalClear shall be consistent in every CMSIS-RTOS.
int32_t osSignalClear(osThreadId thread_id, int32_t signals);
/// Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread.
/// \param[in] signals wait until all specified signal flags set or 0 for any single signal flag.
/// \param[in] millisec timeout value or 0 in case of no time-out.
/// \return event flag information or error code.
/// \note MUST REMAIN UNCHANGED: \b osSignalWait shall be consistent in every CMSIS-RTOS.
osEvent osSignalWait(int32_t signals, uint32_t millisec);
#endif // TOS_CFG_MESSAGE_QUEUE_EN
#if TOS_CFG_MUTEX_EN > 0u
// ==== Mutex Management ====
/// Define a Mutex.
/// \param name name of the mutex object.
/// \note CAN BE CHANGED: The parameter to \b osMutexDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osMutexDef(name) \
extern const osMutexDef_t os_mutex_def_##name
#else // define the object
#define osMutexDef(name) \
k_mutex_t mutex_handler_##name; \
const osMutexDef_t os_mutex_def_##name = { 0, (&(mutex_handler_##name)) }
#endif
/// Access a Mutex definition.
/// \param name name of the mutex object.
/// \note CAN BE CHANGED: The parameter to \b osMutex shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osMutex(name) \
&os_mutex_def_##name
/// Create and Initialize a Mutex object.
/// \param[in] mutex_def mutex definition referenced with \ref osMutex.
/// \return mutex ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osMutexCreate shall be consistent in every CMSIS-RTOS.
osMutexId osMutexCreate(const osMutexDef_t *mutex_def);
/// Wait until a Mutex becomes available.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osMutexWait shall be consistent in every CMSIS-RTOS.
osStatus osMutexWait(osMutexId mutex_id, uint32_t millisec);
/// Release a Mutex that was obtained by \ref osMutexWait.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osMutexRelease shall be consistent in every CMSIS-RTOS.
osStatus osMutexRelease(osMutexId mutex_id);
/// Delete a Mutex that was created by \ref osMutexCreate.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexCreate.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osMutexDelete shall be consistent in every CMSIS-RTOS.
osStatus osMutexDelete(osMutexId mutex_id);
#endif // TOS_CFG_MUTEX_EN
#if TOS_CFG_SEM_EN > 0u
// ==== Semaphore Management Functions ====
#if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0)) // Semaphore available
/// Define a Semaphore object.
/// \param name name of the semaphore object.
/// \note CAN BE CHANGED: The parameter to \b osSemaphoreDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osSemaphoreDef(name) \
extern const osSemaphoreDef_t os_semaphore_def_##name
#else // define the object
#define osSemaphoreDef(name) \
k_sem_t sem_handler_##name; \
const osSemaphoreDef_t os_semaphore_def_##name = { 0, (&(sem_handler_##name)) }
#endif
/// Access a Semaphore definition.
/// \param name name of the semaphore object.
/// \note CAN BE CHANGED: The parameter to \b osSemaphore shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osSemaphore(name) \
&os_semaphore_def_##name
/// Create and Initialize a Semaphore object used for managing resources.
/// \param[in] semaphore_def semaphore definition referenced with \ref osSemaphore.
/// \param[in] count number of available resources.
/// \return semaphore ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
osSemaphoreId osSemaphoreCreate(const osSemaphoreDef_t *semaphore_def, int32_t count);
/// Wait until a Semaphore token becomes available.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out.
/// \return number of available tokens, or -1 in case of incorrect parameters.
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS.
int32_t osSemaphoreWait(osSemaphoreId semaphore_id, uint32_t millisec);
/// Release a Semaphore token.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
osStatus osSemaphoreRelease(osSemaphoreId semaphore_id);
/// Delete a Semaphore that was created by \ref osSemaphoreCreate.
/// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osSemaphoreDelete shall be consistent in every CMSIS-RTOS.
osStatus osSemaphoreDelete(osSemaphoreId semaphore_id);
#endif // Semaphore available
#endif // TOS_CFG_SEM_EN
// ==== Memory Pool Management Functions ====
#if (defined (osFeature_Pool) && (osFeature_Pool != 0)) // Memory Pool Management available
/// \brief Define a Memory Pool.
/// \param name name of the memory pool.
/// \param no maximum number of blocks (objects) in the memory pool.
/// \param type data type of a single block (object).
/// \note CAN BE CHANGED: The parameter to \b osPoolDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osPoolDef(name, no, type) \
extern const osPoolDef_t os_pool_def_##name
#else // define the object
#define osPoolDef(name, no, type) \
k_mmblk_pool_t mmblk_pool_handler_##name; \
uint8_t mmblk_pool_buf_##name[(no) * sizeof(type)]; \
const osPoolDef_t os_pool_def_##name = \
{ (no), sizeof(type), (&((mmblk_pool_buf_##name)[0])), (&(mmblk_pool_handler_##name)) }
#endif
/// \brief Access a Memory Pool definition.
/// \param name name of the memory pool
/// \note CAN BE CHANGED: The parameter to \b osPool shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osPool(name) \
&os_pool_def_##name
/// Create and Initialize a memory pool.
/// \param[in] pool_def memory pool definition referenced with \ref osPool.
/// \return memory pool ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osPoolCreate shall be consistent in every CMSIS-RTOS.
osPoolId osPoolCreate(const osPoolDef_t *pool_def);
/// Allocate a memory block from a memory pool.
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
/// \return address of the allocated memory block or NULL in case of no memory available.
/// \note MUST REMAIN UNCHANGED: \b osPoolAlloc shall be consistent in every CMSIS-RTOS.
void *osPoolAlloc(osPoolId pool_id);
/// Allocate a memory block from a memory pool and set memory block to zero.
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
/// \return address of the allocated memory block or NULL in case of no memory available.
/// \note MUST REMAIN UNCHANGED: \b osPoolCAlloc shall be consistent in every CMSIS-RTOS.
void *osPoolCAlloc(osPoolId pool_id);
/// Return an allocated memory block back to a specific memory pool.
/// \param[in] pool_id memory pool ID obtain referenced with \ref osPoolCreate.
/// \param[in] block address of the allocated memory block that is returned to the memory pool.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osPoolFree shall be consistent in every CMSIS-RTOS.
osStatus osPoolFree(osPoolId pool_id, void *block);
#endif // Memory Pool Management available
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
// ==== Message Queue Management Functions ====
#if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0)) // Message Queues available
/// \brief Create a Message Queue Definition.
/// \param name name of the queue.
/// \param queue_sz maximum number of messages in the queue.
/// \param type data type of a single message element (for debugger).
/// \note CAN BE CHANGED: The parameter to \b osMessageQDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osMessageQDef(name, queue_sz, type) \
extern const osMessageQDef_t os_messageQ_def_##name
#else // define the object
#define osMessageQDef(name, queue_sz, type) \
k_msg_q_t msg_q_handler_##name; \
uint8_t msg_q_pool[queue_sz*sizeof(type)]; \
const osMessageQDef_t os_messageQ_def_##name = \
{ (queue_sz), sizeof(type), msg_q_pool, (&(msg_q_handler_##name)) }
#endif
/// \brief Access a Message Queue Definition.
/// \param name name of the queue
/// \note CAN BE CHANGED: The parameter to \b osMessageQ shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osMessageQ(name) \
&os_messageQ_def_##name
/// Create and Initialize a Message Queue.
/// \param[in] queue_def queue definition referenced with \ref osMessageQ.
/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
/// \return message queue ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osMessageCreate shall be consistent in every CMSIS-RTOS.
osMessageQId osMessageCreate(const osMessageQDef_t *queue_def, osThreadId thread_id);
/// Put a Message to a Queue.
/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
/// \param[in] info message information.
/// \param[in] millisec timeout value or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osMessagePut shall be consistent in every CMSIS-RTOS.
osStatus osMessagePut(osMessageQId queue_id, uint32_t info, uint32_t millisec);
/// Get a Message or Wait for a Message from a Queue.
/// \param[in] queue_id message queue ID obtained with \ref osMessageCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out.
/// \return event information that includes status code.
/// \note MUST REMAIN UNCHANGED: \b osMessageGet shall be consistent in every CMSIS-RTOS.
osEvent osMessageGet(osMessageQId queue_id, uint32_t millisec);
#endif // Message Queues available
#endif
#if TOS_CFG_MAIL_QUEUE_EN > 0u
// ==== Mail Queue Management Functions ====
#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0)) // Mail Queues available
/// \brief Create a Mail Queue Definition.
/// \param name name of the queue
/// \param queue_sz maximum number of messages in queue
/// \param type data type of a single message element
/// \note CAN BE CHANGED: The parameter to \b osMailQDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osMailQDef(name, queue_sz, type) \
extern const osMailQDef_t os_mailQ_def_##name
#else // define the object
#define osMailQDef(name, queue_sz, type) \
const osMailQDef_t os_mailQ_def_##name = \
{ (queue_sz), sizeof (type) }
#endif
/// \brief Access a Mail Queue Definition.
/// \param name name of the queue
/// \note CAN BE CHANGED: The parameter to \b osMailQ shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osMailQ(name) \
&os_mailQ_def_##name
/// Create and Initialize mail queue.
/// \param[in] queue_def reference to the mail queue definition obtain with \ref osMailQ
/// \param[in] thread_id thread ID (obtained by \ref osThreadCreate or \ref osThreadGetId) or NULL.
/// \return mail queue ID for reference by other functions or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osMailCreate shall be consistent in every CMSIS-RTOS.
osMailQId osMailCreate(const osMailQDef_t *queue_def, osThreadId thread_id);
/// Allocate a memory block from a mail.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osMailAlloc shall be consistent in every CMSIS-RTOS.
void *osMailAlloc(osMailQId queue_id, uint32_t millisec);
/// Allocate a memory block from a mail and set memory block to zero.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out
/// \return pointer to memory block that can be filled with mail or NULL in case of error.
/// \note MUST REMAIN UNCHANGED: \b osMailCAlloc shall be consistent in every CMSIS-RTOS.
void *osMailCAlloc(osMailQId queue_id, uint32_t millisec);
/// Put a mail to a queue.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] mail memory block previously allocated with \ref osMailAlloc or \ref osMailCAlloc.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osMailPut shall be consistent in every CMSIS-RTOS.
osStatus osMailPut(osMailQId queue_id, void *mail);
/// Get a mail from a queue.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] millisec timeout value or 0 in case of no time-out
/// \return event that contains mail information or error code.
/// \note MUST REMAIN UNCHANGED: \b osMailGet shall be consistent in every CMSIS-RTOS.
osEvent osMailGet(osMailQId queue_id, uint32_t millisec);
/// Free a memory block from a mail.
/// \param[in] queue_id mail queue ID obtained with \ref osMailCreate.
/// \param[in] mail pointer to the memory block that was obtained with \ref osMailGet.
/// \return status code that indicates the execution status of the function.
/// \note MUST REMAIN UNCHANGED: \b osMailFree shall be consistent in every CMSIS-RTOS.
osStatus osMailFree(osMailQId queue_id, void *mail);
#endif // Mail Queues available
#endif // TOS_CFG_MAIL_QUEUE_EN
#ifdef __cplusplus
}
#endif
#endif // _CMSIS_OS_H

896
osal/cmsis_os/cmsis_os2.c Normal file
View File

@@ -0,0 +1,896 @@
#include "cmsis_os2.h"
#include <string.h>
static k_prio_t priority_cmsis2knl(osPriority_t prio) {
if (prio == osPriorityError || prio == osPriorityISR ||
prio == osPriorityReserved) {
return K_TASK_PRIO_INVALID;
}
return (k_prio_t)(6 - prio / 8);
}
static osPriority_t priority_knl2cmsis(k_prio_t prio) {
return (osPriority_t)((6 - prio) * 8);
}
static osStatus_t errno_knl2cmsis(k_err_t err) {
osStatus_t state;
switch (err) {
case K_ERR_NONE:
state = osOK;
break;
case K_ERR_IN_IRQ:
state = osErrorISR;
break;
case K_ERR_OUT_OF_MEMORY:
state = osErrorNoMemory;
break;
case K_ERR_PEND_TIMEOUT:
state = osErrorTimeout;
break;
case K_ERR_PEND_DESTROY:
state = osErrorResource;
break;
default:
state = osError;
break;
}
return state;
}
/*---------------------------------------------------------------------------*/
osStatus_t osKernelInitialize(void) {
return errno_knl2cmsis(tos_knl_init());
}
osStatus_t osKernelGetInfo(osVersion_t* version,
char* id_buf,
uint32_t id_size) {
if (version != NULL) {
version->api = osCMSIS;
version->kernel = osCMSIS_KERNEL;
}
if ((id_buf != NULL) && (id_size != 0U)) {
if (id_size > sizeof(osKernelSystemId)) {
id_size = sizeof(osKernelSystemId);
}
memcpy(id_buf, osKernelSystemId, id_size);
}
return osOK;
}
osKernelState_t osKernelGetState(void) {
osKernelState_t state;
switch (k_knl_state) {
case KNL_STATE_RUNNING:
state = osKernelRunning;
break;
default:
state = osKernelInactive;
break;
}
return state;
}
osStatus_t osKernelStart(void) {
return errno_knl2cmsis(tos_knl_start());
}
int32_t osKernelLock(void) {
tos_knl_sched_lock();
if (knl_is_sched_locked()) {
return 1;
} else {
return 0;
}
}
int32_t osKernelUnlock(void) {
tos_knl_sched_unlock();
if (knl_is_sched_locked()) {
return 1;
} else {
return 0;
}
}
int32_t osKernelRestoreLock(int32_t lock) {
if (lock == 1) {
tos_knl_sched_lock();
} else if (lock == 0) {
tos_knl_sched_unlock();
} else {
return -1;
}
if (knl_is_sched_locked()) {
return 1;
} else {
return 0;
}
}
uint32_t osKernelSuspend(void) {
// todo
return 0;
}
void osKernelResume(uint32_t sleep_ticks) {
(void)sleep_ticks;
// todo
}
uint32_t osKernelGetTickCount(void) {
return (uint32_t)tos_systick_get();
}
uint32_t osKernelGetTickFreq(void) {
return TOS_CFG_CPU_TICK_PER_SECOND;
}
uint32_t osKernelGetSysTimerCount(void) {
k_tick_t ticks;
uint32_t val;
ticks = osKernelGetTickCount();
val = ticks * (TOS_CFG_CPU_CLOCK / TOS_CFG_CPU_TICK_PER_SECOND);
return val;
}
uint32_t osKernelGetSysTimerFreq(void) {
return TOS_CFG_CPU_CLOCK;
}
/*---------------------------------------------------------------------------*/
osThreadId_t osThreadNew(osThreadFunc_t func,
void* argument,
const osThreadAttr_t* attr) {
k_err_t err;
uint32_t stack_size = K_TASK_STK_SIZE_MIN;
k_task_t* taskId = NULL;
k_prio_t prio = osPriorityNormal;
if (attr && func) {
if (attr->priority != osPriorityNone) {
prio = priority_cmsis2knl(attr->priority);
}
if (attr->stack_size > 0U) {
stack_size = attr->stack_size;
}
if (attr->stack_mem && attr->cb_mem) {
err = tos_task_create((k_task_t*)attr->cb_mem, (char*)attr->name,
(k_task_entry_t)func, argument, prio,
attr->stack_mem, stack_size, 0);
taskId = err == K_ERR_NONE ? attr->cb_mem : NULL;
} else {
#if TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u
k_task_t* task;
err = tos_task_create_dyn(&task, (char*)attr->name, (k_task_entry_t)func,
argument, prio, stack_size, 0);
taskId = err == K_ERR_NONE ? task : NULL;
#endif
}
}
return (osThreadId_t)taskId;
}
const char* osThreadGetName(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
const char* name;
if (taskId == NULL) {
name = NULL;
} else {
name = taskId->name;
}
return name;
}
osThreadId_t osThreadGetId(void) {
return (osThreadId_t)tos_task_curr_task_get();
}
osThreadState_t osThreadGetState(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
osThreadState_t state = osThreadError;
if (taskId != NULL) {
if (tos_task_curr_task_get() == taskId) {
state = osThreadRunning;
} else if (task_state_is_sleeping(taskId)) {
state = osThreadBlocked;
} else if (task_state_is_pending(taskId)) {
state = osThreadBlocked;
} else if (task_state_is_suspended(taskId)) {
state = osThreadBlocked;
} else if (task_state_is_ready(taskId)) {
state = osThreadReady;
} else if (taskId->state == K_TASK_STATE_DELETED) {
state = osThreadTerminated;
}
}
return state;
}
uint32_t osThreadGetStackSize(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
return taskId->stk_size;
}
uint32_t osThreadGetStackSpace(osThreadId_t thread_id) {
(void)thread_id;
// todo
return 0;
}
osStatus_t osThreadSetPriority(osThreadId_t thread_id, osPriority_t priority) {
k_task_t* taskId = (k_task_t*)thread_id;
k_prio_t prio = priority_cmsis2knl(priority);
osStatus_t state;
if (taskId == NULL || prio == K_TASK_PRIO_INVALID) {
state = osErrorParameter;
} else {
state = errno_knl2cmsis(tos_task_prio_change(taskId, prio));
}
return state;
}
osPriority_t osThreadGetPriority(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
osPriority_t prio;
if (taskId == NULL) {
prio = osPriorityError;
} else {
prio = priority_knl2cmsis(taskId->prio);
}
return prio;
}
osStatus_t osThreadYield(void) {
osStatus_t state;
if (knl_is_inirq()) {
state = osErrorISR;
} else {
tos_task_yield();
state = osOK;
}
return state;
}
osStatus_t osThreadSuspend(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
osStatus_t state;
if (taskId == NULL) {
state = osErrorParameter;
} else {
state = errno_knl2cmsis(tos_task_suspend(taskId));
}
return state;
}
osStatus_t osThreadResume(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
osStatus_t state;
if (taskId == NULL) {
state = osErrorParameter;
} else {
state = errno_knl2cmsis(tos_task_resume(taskId));
}
return state;
}
osStatus_t osThreadDetach(osThreadId_t thread_id) {
(void)thread_id;
// todo
return osError;
}
osStatus_t osThreadJoin(osThreadId_t thread_id) {
(void)thread_id;
// todo
return osError;
}
__NO_RETURN void osThreadExit(void) {
tos_task_destroy(k_curr_task);
while (1)
;
}
osStatus_t osThreadTerminate(osThreadId_t thread_id) {
k_task_t* taskId = (k_task_t*)thread_id;
osStatus_t state;
if (taskId == NULL) {
state = osErrorParameter;
} else {
if (taskId->state == K_TASK_STATE_DELETED) {
state = osErrorResource;
} else {
state = errno_knl2cmsis(tos_task_destroy(taskId));
}
}
return state;
}
uint32_t osThreadGetCount(void) {
uint32_t count = 0;
TOS_CPU_CPSR_ALLOC();
k_task_t* task;
TOS_CPU_INT_DISABLE();
TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) {
count += 1;
}
TOS_CPU_INT_ENABLE();
return count;
}
uint32_t osThreadEnumerate(osThreadId_t* thread_array, uint32_t array_items) {
uint32_t count = 0;
if ((thread_array != NULL) && (array_items != 0U)) {
TOS_CPU_CPSR_ALLOC();
k_task_t* task;
TOS_CPU_INT_DISABLE();
TOS_LIST_FOR_EACH_ENTRY(task, k_task_t, stat_list, &k_stat_list) {
while (count < array_items) {
thread_array[count] = (osThreadId_t)task;
count += 1;
}
}
TOS_CPU_INT_ENABLE();
}
return count;
}
uint32_t osThreadFlagsSet(osThreadId_t thread_id, uint32_t flags) {
uint32_t rflags = 0xFFFFFFFF;
// todo
return rflags;
}
uint32_t osThreadFlagsClear(uint32_t flags) {
uint32_t rflags = 0xFFFFFFFF;
// todo
return rflags;
}
uint32_t osThreadFlagsGet(void) {
uint32_t rflags = 0xFFFFFFFF;
// todo
return rflags;
}
uint32_t osThreadFlagsWait(uint32_t flags, uint32_t options, uint32_t timeout) {
uint32_t rflags = 0xFFFFFFFF;
// todo
return rflags;
}
osStatus_t osDelay(uint32_t ticks) {
k_tick_t delay;
if (ticks == osWaitForever) {
delay = TOS_TIME_FOREVER;
} else {
delay = (k_tick_t)ticks;
}
return errno_knl2cmsis(tos_task_delay(delay));
}
osStatus_t osDelayUntil(uint32_t ticks) {
k_tick_t delay;
if (ticks == osWaitForever) {
delay = TOS_TIME_FOREVER;
} else {
k_tick_t now = tos_systick_get();
if ((k_tick_t)ticks < now) {
return osErrorParameter;
}
delay = (k_tick_t)ticks - now;
}
return errno_knl2cmsis(tos_task_delay(delay));
}
/*---------------------------------------------------------------------------*/
osTimerId_t osTimerNew(osTimerFunc_t func,
osTimerType_t type,
void* argument,
const osTimerAttr_t* attr) {
k_err_t err;
k_opt_t opt = TOS_OPT_TIMER_ONESHOT;
k_timer_t* timerId = NULL;
if (attr && func) {
if (type == osTimerPeriodic) {
opt = TOS_OPT_TIMER_PERIODIC;
} else if (type == osTimerOnce) {
opt = TOS_OPT_TIMER_ONESHOT;
}
if (attr->cb_mem) {
err = tos_timer_create((k_timer_t*)attr->cb_mem, (k_tick_t)1000u,
(k_tick_t)1000u, (k_timer_callback_t)func,
argument, opt);
timerId = err == K_ERR_NONE ? attr->cb_mem : NULL;
}
}
return (osTimerId_t)timerId;
}
const char* osTimerGetName(osTimerId_t timer_id) {
(void)timer_id;
// todo
return NULL;
}
osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks) {
k_timer_t* timerId = (k_timer_t*)timer_id;
osStatus_t state;
if (timerId == NULL) {
state = osErrorParameter;
} else {
tos_timer_delay_change(timerId, ticks);
tos_timer_period_change(timerId, ticks);
state = errno_knl2cmsis(tos_timer_start(timerId));
}
return state;
}
osStatus_t osTimerStop(osTimerId_t timer_id) {
k_timer_t* timerId = (k_timer_t*)timer_id;
osStatus_t state;
if (timerId == NULL) {
state = osErrorParameter;
} else {
state = errno_knl2cmsis(tos_timer_stop(timerId));
}
return state;
}
uint32_t osTimerIsRunning(osTimerId_t timer_id) {
k_timer_t* timerId = (k_timer_t*)timer_id;
uint32_t running;
if (timerId == NULL) {
running = 0U;
} else {
running = timerId->state == TIMER_STATE_RUNNING;
}
return running;
}
osStatus_t osTimerDelete(osTimerId_t timer_id) {
k_timer_t* timerId = (k_timer_t*)timer_id;
return errno_knl2cmsis(tos_timer_destroy(timerId));
}
/*---------------------------------------------------------------------------*/
osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t* attr) {
k_err_t err;
k_event_t* eventId = NULL;
if (attr) {
if (attr->cb_mem) {
err = tos_event_create((k_event_t*)attr->cb_mem, 0);
eventId = err == K_ERR_NONE ? attr->cb_mem : NULL;
}
}
return (osEventFlagsId_t)eventId;
}
const char* osEventFlagsGetName(osEventFlagsId_t ef_id) {
(void)ef_id;
// todo
return NULL;
}
uint32_t osEventFlagsSet(osEventFlagsId_t ef_id, uint32_t flags) {
k_event_t* eventId = (k_event_t*)ef_id;
k_err_t err;
uint32_t rflags;
if (eventId == NULL) {
rflags = (uint32_t)osErrorParameter;
} else {
err = tos_event_post_keep(eventId, (k_event_flag_t)flags);
rflags = err == K_ERR_NONE ? (uint32_t)eventId->flag
: (uint32_t)errno_knl2cmsis(err);
}
return rflags;
}
uint32_t osEventFlagsClear(osEventFlagsId_t ef_id, uint32_t flags) {
k_event_t* eventId = (k_event_t*)ef_id;
k_err_t err;
uint32_t rflags;
if (eventId == NULL) {
rflags = (uint32_t)osErrorParameter;
} else {
flags = eventId->flag & (~flags);
err = tos_event_post(eventId, (k_event_flag_t)flags);
rflags = err == K_ERR_NONE ? (uint32_t)eventId->flag
: (uint32_t)errno_knl2cmsis(err);
}
return rflags;
}
uint32_t osEventFlagsGet(osEventFlagsId_t ef_id) {
k_event_t* eventId = (k_event_t*)ef_id;
uint32_t rflags;
if (ef_id == NULL) {
rflags = 0U;
} else {
rflags = (uint32_t)eventId->flag;
}
return rflags;
}
uint32_t osEventFlagsWait(osEventFlagsId_t ef_id,
uint32_t flags,
uint32_t options,
uint32_t timeout) {
k_event_t* eventId = (k_event_t*)ef_id;
k_err_t err;
uint32_t rflags;
if (ef_id == NULL) {
rflags = (uint32_t)osErrorParameter;
} else {
k_event_flag_t flag_match;
k_opt_t opt_pend = 0;
timeout =
((timeout == 0) || (timeout == osWaitForever)) ? TOS_TIME_FOREVER : timeout;
if (options & (0x01 == 0)) {
opt_pend |= TOS_OPT_EVENT_PEND_ANY;
} else {
opt_pend |= TOS_OPT_EVENT_PEND_ALL;
}
if (options & (0x02 == 0)) {
opt_pend |= TOS_OPT_EVENT_PEND_CLR;
}
err = tos_event_pend(eventId, (k_event_flag_t)flags, &flag_match, (k_tick_t)timeout,
opt_pend);
rflags = err == K_ERR_NONE ? (uint32_t)flag_match
: (uint32_t)errno_knl2cmsis(err);
}
return rflags;
}
osStatus_t osEventFlagsDelete(osEventFlagsId_t ef_id) {
k_event_t* eventId = (k_event_t*)ef_id;
return errno_knl2cmsis(tos_event_destroy(eventId));
}
/*---------------------------------------------------------------------------*/
osMutexId_t osMutexNew(const osMutexAttr_t* attr) {
k_err_t err;
k_mutex_t* mutexId = NULL;
if (attr) {
if (attr->cb_mem) {
err = tos_mutex_create((k_mutex_t*)attr->cb_mem);
mutexId = (err == K_ERR_NONE) ? attr->cb_mem : NULL;
}
} else {
err = tos_mutex_create_dyn(&mutexId);
mutexId = (err == K_ERR_NONE) ? mutexId : NULL;
}
return (osMutexId_t)mutexId;
}
const char* osMutexGetName(osMutexId_t mutex_id) {
(void)mutex_id;
// todo
return NULL;
}
osStatus_t osMutexAcquire(osMutexId_t mutex_id, uint32_t timeout) {
k_mutex_t* mutexId = (k_mutex_t*)mutex_id;
return errno_knl2cmsis(tos_mutex_pend_timed(mutexId, timeout));
}
osStatus_t osMutexRelease(osMutexId_t mutex_id) {
k_mutex_t* mutexId = (k_mutex_t*)mutex_id;
return errno_knl2cmsis(tos_mutex_post(mutexId));
}
osThreadId_t osMutexGetOwner(osMutexId_t mutex_id) {
k_mutex_t* mutexId = (k_mutex_t*)mutex_id;
return (osThreadId_t)mutexId->owner;
}
osStatus_t osMutexDelete(osMutexId_t mutex_id) {
k_mutex_t* mutexId = (k_mutex_t*)mutex_id;
return errno_knl2cmsis(tos_mutex_destroy(mutexId));
}
/*---------------------------------------------------------------------------*/
osSemaphoreId_t osSemaphoreNew(uint32_t max_count,
uint32_t initial_count,
const osSemaphoreAttr_t* attr) {
k_err_t err;
k_sem_t* semId = NULL;
if (attr) {
if (attr->cb_mem) {
err =
tos_sem_create_max((k_sem_t*)attr->cb_mem, (k_sem_cnt_t)initial_count,
(k_sem_cnt_t)max_count);
semId = (err == K_ERR_NONE) ? attr->cb_mem : NULL;
}
} else {
err = tos_sem_create_max_dyn(&semId, (k_sem_cnt_t)initial_count, (k_sem_cnt_t)max_count);
semId = (err == K_ERR_NONE) ? semId: NULL;
}
return (osSemaphoreId_t)semId;
}
const char* osSemaphoreGetName(osSemaphoreId_t semaphore_id) {
(void)semaphore_id;
// todo
return NULL;
}
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout) {
k_sem_t* semId = (k_sem_t*)semaphore_id;
return errno_knl2cmsis(tos_sem_pend(semId, timeout));
}
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id) {
k_sem_t* semId = (k_sem_t*)semaphore_id;
return errno_knl2cmsis(tos_sem_post(semId));
}
uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id) {
k_sem_t* semId = (k_sem_t*)semaphore_id;
return (uint32_t)semId->count;
}
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id) {
k_sem_t* semId = (k_sem_t*)semaphore_id;
return errno_knl2cmsis(tos_sem_destroy(semId));
}
/*---------------------------------------------------------------------------*/
osMemoryPoolId_t osMemoryPoolNew(uint32_t block_count,
uint32_t block_size,
const osMemoryPoolAttr_t* attr) {
k_err_t err;
k_mmblk_pool_t* mpId = NULL;
if (attr) {
if (attr->cb_mem) {
err = tos_mmblk_pool_create((k_mmblk_pool_t*)attr->cb_mem, attr->mp_mem,
block_count, block_size);
mpId = (err == K_ERR_NONE) ? attr->cb_mem : NULL;
}
} else {
err = tos_mmblk_pool_create_dyn(&mpId, block_count, block_size);
mpId = (err == K_ERR_NONE) ? mpId : NULL;
}
return (osMemoryPoolId_t)mpId;
}
const char* osMemoryPoolGetName(osMemoryPoolId_t mp_id) {
(void)mp_id;
// todo
return NULL;
}
void* osMemoryPoolAlloc(osMemoryPoolId_t mp_id, uint32_t timeout) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
k_err_t err;
void* blk = NULL;
err = tos_mmblk_alloc(mpId, &blk);
return err == K_ERR_NONE ? blk : NULL;
}
osStatus_t osMemoryPoolFree(osMemoryPoolId_t mp_id, void* block) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
return errno_knl2cmsis(tos_mmblk_free(mpId, block));
}
uint32_t osMemoryPoolGetCapacity(osMemoryPoolId_t mp_id) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
return mpId->blk_max;
}
uint32_t osMemoryPoolGetBlockSize(osMemoryPoolId_t mp_id) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
return mpId->blk_size;
}
uint32_t osMemoryPoolGetCount(osMemoryPoolId_t mp_id) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
return mpId->blk_max - mpId->blk_free;
}
uint32_t osMemoryPoolGetSpace(osMemoryPoolId_t mp_id) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
return mpId->blk_free;
}
osStatus_t osMemoryPoolDelete(osMemoryPoolId_t mp_id) {
k_mmblk_pool_t* mpId = (k_mmblk_pool_t*)mp_id;
if (knl_object_alloc_is_dynamic(&mpId->knl_obj)) {
return errno_knl2cmsis(tos_mmblk_pool_destroy_dyn(mpId));
} else {
return errno_knl2cmsis(tos_mmblk_pool_destroy(mpId));
}
}
/*---------------------------------------------------------------------------*/
#if TOS_CFG_MESSAGE_QUEUE_EN > 0u
osMessageQueueId_t osMessageQueueNew(uint32_t msg_count,
uint32_t msg_size,
const osMessageQueueAttr_t* attr) {
k_err_t err;
k_msg_q_t* mqId = NULL;
if (attr) {
if (attr->mq_mem && msg_size == sizeof(void*)) {
err = tos_msg_q_create((k_msg_q_t*)attr->cb_mem, attr->mq_mem, msg_count);
mqId = err == K_ERR_NONE ? attr->cb_mem : NULL;
}
}
return mqId;
}
const char* osMessageQueueGetName(osMessageQueueId_t mq_id) {
(void)mq_id;
// todo
return NULL;
}
osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id,
const void* msg_ptr,
uint8_t msg_prio,
uint32_t timeout) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
return errno_knl2cmsis(tos_msg_q_post(mqId, (void*)msg_ptr));
}
osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id,
void* msg_ptr,
uint8_t* msg_prio,
uint32_t timeout) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
return errno_knl2cmsis(tos_msg_q_pend(mqId, &msg_ptr, timeout));
}
uint32_t osMessageQueueGetCapacity(osMessageQueueId_t mq_id) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
uint32_t capacity;
if (mqId == NULL) {
capacity = 0U;
} else {
capacity = mqId->ring_q.item_cnt;
}
return capacity;
}
uint32_t osMessageQueueGetMsgSize(osMessageQueueId_t mq_id) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
uint32_t size;
if (mqId == NULL) {
size = 0U;
} else {
size = mqId->ring_q.item_size;
}
return size;
}
uint32_t osMessageQueueGetCount(osMessageQueueId_t mq_id) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
uint32_t count;
if (mqId == NULL) {
count = 0U;
} else {
count = mqId->ring_q.total;
}
return count;
}
uint32_t osMessageQueueGetSpace(osMessageQueueId_t mq_id) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
uint32_t space;
if (mqId == NULL) {
space = 0U;
} else {
space = mqId->ring_q.item_cnt - mqId->ring_q.total;
}
return space;
}
osStatus_t osMessageQueueReset(osMessageQueueId_t mq_id) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
return errno_knl2cmsis(tos_msg_q_flush(mqId));
}
osStatus_t osMessageQueueDelete(osMessageQueueId_t mq_id) {
k_msg_q_t* mqId = (k_msg_q_t*)mq_id;
return errno_knl2cmsis(tos_msg_q_destroy(mqId));
}
#endif
/*---------------------------------------------------------------------------*/

799
osal/cmsis_os/cmsis_os2.h Normal file
View File

@@ -0,0 +1,799 @@
/*
* Copyright (c) 2013-2018 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*
* ----------------------------------------------------------------------
*
* $Date: 18. June 2018
* $Revision: V2.1.3
*
* Project: CMSIS-RTOS2 API
* Title: cmsis_os2.h header file
*
* Version 2.1.3
* Additional functions allowed to be called from Interrupt Service Routines:
* - osThreadGetId
* Version 2.1.2
* Additional functions allowed to be called from Interrupt Service Routines:
* - osKernelGetInfo, osKernelGetState
* Version 2.1.1
* Additional functions allowed to be called from Interrupt Service Routines:
* - osKernelGetTickCount, osKernelGetTickFreq
* Changed Kernel Tick type to uint32_t:
* - updated: osKernelGetTickCount, osDelayUntil
* Version 2.1.0
* Support for critical and uncritical sections (nesting safe):
* - updated: osKernelLock, osKernelUnlock
* - added: osKernelRestoreLock
* Updated Thread and Event Flags:
* - changed flags parameter and return type from int32_t to uint32_t
* Version 2.0.0
* Initial Release
*---------------------------------------------------------------------------*/
#ifndef CMSIS_OS2_H_
#define CMSIS_OS2_H_
/* Kernel version and identification string definition */
#define osCMSIS 0x20001U ///< API version (main[31:16].sub[15:0])
/// \note CAN BE CHANGED: \b osCMSIS_KERNEL identifies the underlying RTOS kernel and version number.
#define osCMSIS_KERNEL 0x10000U ///< RTOS identification and version (main[31:16].sub[15:0])
/// \note CAN BE CHANGED: \b osKernelSystemId identifies the underlying RTOS kernel.
#define osKernelSystemId "TencentOS tiny V1.00" ///< RTOS identification string
#ifndef __NO_RETURN
#if defined(__CC_ARM)
#define __NO_RETURN __declspec(noreturn)
#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#define __NO_RETURN __attribute__((__noreturn__))
#elif defined(__GNUC__)
#define __NO_RETURN __attribute__((__noreturn__))
#elif defined(__ICCARM__)
#define __NO_RETURN __noreturn
#else
#define __NO_RETURN
#endif
#endif
#include <stdint.h>
#include <stddef.h>
#include "tos_k.h"
#ifdef __cplusplus
extern "C"
{
#endif
// ==== Enumerations, structures, defines ====
/// Version information.
typedef struct {
uint32_t api; ///< API version (major.minor.rev: mmnnnrrrr dec).
uint32_t kernel; ///< Kernel version (major.minor.rev: mmnnnrrrr dec).
} osVersion_t;
/// Kernel state.
typedef enum {
osKernelInactive = 0, ///< Inactive.
osKernelReady = 1, ///< Ready.
osKernelRunning = 2, ///< Running.
osKernelLocked = 3, ///< Locked.
osKernelSuspended = 4, ///< Suspended.
osKernelError = -1, ///< Error.
osKernelReserved = 0x7FFFFFFFU ///< Prevents enum down-size compiler optimization.
} osKernelState_t;
/// Thread state.
typedef enum {
osThreadInactive = 0, ///< Inactive.
osThreadReady = 1, ///< Ready.
osThreadRunning = 2, ///< Running.
osThreadBlocked = 3, ///< Blocked.
osThreadTerminated = 4, ///< Terminated.
osThreadError = -1, ///< Error.
osThreadReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osThreadState_t;
/// Priority values.
typedef enum {
osPriorityNone = 0, ///< No priority (not initialized).
osPriorityIdle = 1, ///< Reserved for Idle thread.
osPriorityLow = 8, ///< Priority: low
osPriorityLow1 = 8+1, ///< Priority: low + 1
osPriorityLow2 = 8+2, ///< Priority: low + 2
osPriorityLow3 = 8+3, ///< Priority: low + 3
osPriorityLow4 = 8+4, ///< Priority: low + 4
osPriorityLow5 = 8+5, ///< Priority: low + 5
osPriorityLow6 = 8+6, ///< Priority: low + 6
osPriorityLow7 = 8+7, ///< Priority: low + 7
osPriorityBelowNormal = 16, ///< Priority: below normal
osPriorityBelowNormal1 = 16+1, ///< Priority: below normal + 1
osPriorityBelowNormal2 = 16+2, ///< Priority: below normal + 2
osPriorityBelowNormal3 = 16+3, ///< Priority: below normal + 3
osPriorityBelowNormal4 = 16+4, ///< Priority: below normal + 4
osPriorityBelowNormal5 = 16+5, ///< Priority: below normal + 5
osPriorityBelowNormal6 = 16+6, ///< Priority: below normal + 6
osPriorityBelowNormal7 = 16+7, ///< Priority: below normal + 7
osPriorityNormal = 24, ///< Priority: normal
osPriorityNormal1 = 24+1, ///< Priority: normal + 1
osPriorityNormal2 = 24+2, ///< Priority: normal + 2
osPriorityNormal3 = 24+3, ///< Priority: normal + 3
osPriorityNormal4 = 24+4, ///< Priority: normal + 4
osPriorityNormal5 = 24+5, ///< Priority: normal + 5
osPriorityNormal6 = 24+6, ///< Priority: normal + 6
osPriorityNormal7 = 24+7, ///< Priority: normal + 7
osPriorityAboveNormal = 32, ///< Priority: above normal
osPriorityAboveNormal1 = 32+1, ///< Priority: above normal + 1
osPriorityAboveNormal2 = 32+2, ///< Priority: above normal + 2
osPriorityAboveNormal3 = 32+3, ///< Priority: above normal + 3
osPriorityAboveNormal4 = 32+4, ///< Priority: above normal + 4
osPriorityAboveNormal5 = 32+5, ///< Priority: above normal + 5
osPriorityAboveNormal6 = 32+6, ///< Priority: above normal + 6
osPriorityAboveNormal7 = 32+7, ///< Priority: above normal + 7
osPriorityHigh = 40, ///< Priority: high
osPriorityHigh1 = 40+1, ///< Priority: high + 1
osPriorityHigh2 = 40+2, ///< Priority: high + 2
osPriorityHigh3 = 40+3, ///< Priority: high + 3
osPriorityHigh4 = 40+4, ///< Priority: high + 4
osPriorityHigh5 = 40+5, ///< Priority: high + 5
osPriorityHigh6 = 40+6, ///< Priority: high + 6
osPriorityHigh7 = 40+7, ///< Priority: high + 7
osPriorityRealtime = 48, ///< Priority: realtime
osPriorityRealtime1 = 48+1, ///< Priority: realtime + 1
osPriorityRealtime2 = 48+2, ///< Priority: realtime + 2
osPriorityRealtime3 = 48+3, ///< Priority: realtime + 3
osPriorityRealtime4 = 48+4, ///< Priority: realtime + 4
osPriorityRealtime5 = 48+5, ///< Priority: realtime + 5
osPriorityRealtime6 = 48+6, ///< Priority: realtime + 6
osPriorityRealtime7 = 48+7, ///< Priority: realtime + 7
osPriorityISR = 56, ///< Reserved for ISR deferred thread.
osPriorityError = -1, ///< System cannot determine priority or illegal priority.
osPriorityReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osPriority_t;
/// Entry point of a thread.
typedef void (*osThreadFunc_t) (void *argument);
/// Timer callback function.
typedef void (*osTimerFunc_t) (void *argument);
/// Timer type.
typedef enum {
osTimerOnce = 0, ///< One-shot timer.
osTimerPeriodic = 1 ///< Repeating timer.
} osTimerType_t;
// Timeout value.
#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.
// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait).
#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default).
#define osFlagsWaitAll 0x00000001U ///< Wait for all flags.
#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for.
// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx).
#define osFlagsError 0x80000000U ///< Error indicator.
#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1).
#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2).
#define osFlagsErrorResource 0xFFFFFFFDU ///< osErrorResource (-3).
#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4).
#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6).
// Thread attributes (attr_bits in \ref osThreadAttr_t).
#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default)
#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode
// Mutex attributes (attr_bits in \ref osMutexAttr_t).
#define osMutexRecursive 0x00000001U ///< Recursive mutex.
#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol.
#define osMutexRobust 0x00000008U ///< Robust mutex.
/// Status code values returned by CMSIS-RTOS functions.
typedef enum {
osOK = 0, ///< Operation completed successfully.
osError = -1, ///< Unspecified RTOS error: run-time error but no other error message fits.
osErrorTimeout = -2, ///< Operation not completed within the timeout period.
osErrorResource = -3, ///< Resource not available.
osErrorParameter = -4, ///< Parameter error.
osErrorNoMemory = -5, ///< System is out of memory: it was impossible to allocate or reserve memory for the operation.
osErrorISR = -6, ///< Not allowed in ISR context: the function cannot be called from interrupt service routines.
osStatusReserved = 0x7FFFFFFF ///< Prevents enum down-size compiler optimization.
} osStatus_t;
/// \details Thread ID identifies the thread.
typedef void *osThreadId_t;
/// \details Timer ID identifies the timer.
typedef void *osTimerId_t;
/// \details Event Flags ID identifies the event flags.
typedef void *osEventFlagsId_t;
/// \details Mutex ID identifies the mutex.
typedef void *osMutexId_t;
/// \details Semaphore ID identifies the semaphore.
typedef void *osSemaphoreId_t;
/// \details Memory Pool ID identifies the memory pool.
typedef void *osMemoryPoolId_t;
/// \details Message Queue ID identifies the message queue.
typedef void *osMessageQueueId_t;
#ifndef TZ_MODULEID_T
#define TZ_MODULEID_T
/// \details Data type that identifies secure software modules called by a process.
typedef uint32_t TZ_ModuleId_t;
#endif
/// Attributes structure for thread.
typedef struct {
const char *name; ///< name of the thread
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
void *stack_mem; ///< memory for stack
uint32_t stack_size; ///< size of stack
osPriority_t priority; ///< initial thread priority (default: osPriorityNormal)
TZ_ModuleId_t tz_module; ///< TrustZone module identifier
uint32_t reserved; ///< reserved (must be 0)
} osThreadAttr_t;
/// Attributes structure for timer.
typedef struct {
const char *name; ///< name of the timer
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
} osTimerAttr_t;
/// Attributes structure for event flags.
typedef struct {
const char *name; ///< name of the event flags
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
} osEventFlagsAttr_t;
/// Attributes structure for mutex.
typedef struct {
const char *name; ///< name of the mutex
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
} osMutexAttr_t;
/// Attributes structure for semaphore.
typedef struct {
const char *name; ///< name of the semaphore
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
} osSemaphoreAttr_t;
/// Attributes structure for memory pool.
typedef struct {
const char *name; ///< name of the memory pool
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
void *mp_mem; ///< memory for data storage
uint32_t mp_size; ///< size of provided memory for data storage
} osMemoryPoolAttr_t;
/// Attributes structure for message queue.
typedef struct {
const char *name; ///< name of the message queue
uint32_t attr_bits; ///< attribute bits
void *cb_mem; ///< memory for control block
uint32_t cb_size; ///< size of provided memory for control block
void *mq_mem; ///< memory for data storage
uint32_t mq_size; ///< size of provided memory for data storage
} osMessageQueueAttr_t;
// ==== Kernel Management Functions ====
/// Initialize the RTOS Kernel.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelInitialize (void);
/// Get RTOS Kernel Information.
/// \param[out] version pointer to buffer for retrieving version information.
/// \param[out] id_buf pointer to buffer for retrieving kernel identification string.
/// \param[in] id_size size of buffer for kernel identification string.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelGetInfo (osVersion_t *version, char *id_buf, uint32_t id_size);
/// Get the current RTOS Kernel state.
/// \return current RTOS Kernel state.
osKernelState_t osKernelGetState (void);
/// Start the RTOS Kernel scheduler.
/// \return status code that indicates the execution status of the function.
osStatus_t osKernelStart (void);
/// Lock the RTOS Kernel scheduler.
/// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelLock (void);
/// Unlock the RTOS Kernel scheduler.
/// \return previous lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelUnlock (void);
/// Restore the RTOS Kernel scheduler lock state.
/// \param[in] lock lock state obtained by \ref osKernelLock or \ref osKernelUnlock.
/// \return new lock state (1 - locked, 0 - not locked, error code if negative).
int32_t osKernelRestoreLock (int32_t lock);
/// Suspend the RTOS Kernel scheduler.
/// \return time in ticks, for how long the system can sleep or power-down.
uint32_t osKernelSuspend (void);
/// Resume the RTOS Kernel scheduler.
/// \param[in] sleep_ticks time in ticks for how long the system was in sleep or power-down mode.
void osKernelResume (uint32_t sleep_ticks);
/// Get the RTOS kernel tick count.
/// \return RTOS kernel current tick count.
uint32_t osKernelGetTickCount (void);
/// Get the RTOS kernel tick frequency.
/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second.
uint32_t osKernelGetTickFreq (void);
/// Get the RTOS kernel system timer count.
/// \return RTOS kernel current system timer count as 32-bit value.
uint32_t osKernelGetSysTimerCount (void);
/// Get the RTOS kernel system timer frequency.
/// \return frequency of the system timer in hertz, i.e. timer ticks per second.
uint32_t osKernelGetSysTimerFreq (void);
// ==== Thread Management Functions ====
/// Create a Thread Definition with function, priority, and stack requirements.
/// \param name name of the thread function.
/// \param priority initial priority of the thread function.
/// \param instances number of possible thread instances.
/// \param stacksz stack size (in bytes) requirements for the thread function.
/// \note CAN BE CHANGED: The parameters to \b osThreadDef shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal) // object is external
#define osThreadDef(name, priority, instances, stacksz) \
extern const osThreadAttr_t os_thread_def_##name
#else // define the object
#define osThreadDef(name, priority, instances, stacksz) \
k_task_t task_handler_##name; \
k_stack_t task_stack_##name[(stacksz)]; \
const osThreadAttr_t os_thread_def_##name = \
{ #name, 0, (&(task_handler_##name)), sizeof(k_task_t), (&((task_stack_##name)[0])), (stacksz), (osPriority_t)(priority) }
#if (TOS_CFG_TASK_DYNAMIC_CREATE_EN > 0u)
#define osThreadDynamicDef(name, priority, instances, stacksz) \
const osThreadAttr_t os_thread_def_##name = \
{ #name, 0, (K_NULL), sizeof(k_task_t), (K_NULL), (stacksz), (osPriority_t)(priority) }
#endif
#endif
/// Access a Thread definition.
/// \param name name of the thread definition object.
/// \note CAN BE CHANGED: The parameter to \b osThread shall be consistent but the
/// macro body is implementation specific in every CMSIS-RTOS.
#define osThread(name) \
&os_thread_def_##name
/// Create a thread and add it to Active Threads.
/// \param[in] func thread function.
/// \param[in] argument pointer that is passed to the thread function as start argument.
/// \param[in] attr thread attributes; NULL: default values.
/// \return thread ID for reference by other functions or NULL in case of error.
osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAttr_t *attr);
/// Get name of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return name as null-terminated string.
const char *osThreadGetName (osThreadId_t thread_id);
/// Return the thread ID of the current running thread.
/// \return thread ID for reference by other functions or NULL in case of error.
osThreadId_t osThreadGetId (void);
/// Get current thread state of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return current thread state of the specified thread.
osThreadState_t osThreadGetState (osThreadId_t thread_id);
/// Get stack size of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return stack size in bytes.
uint32_t osThreadGetStackSize (osThreadId_t thread_id);
/// Get available stack space of a thread based on stack watermark recording during execution.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return remaining stack space in bytes.
uint32_t osThreadGetStackSpace (osThreadId_t thread_id);
/// Change priority of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \param[in] priority new priority value for the thread function.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadSetPriority (osThreadId_t thread_id, osPriority_t priority);
/// Get current priority of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return current priority value of the specified thread.
osPriority_t osThreadGetPriority (osThreadId_t thread_id);
/// Pass control to next thread that is in state \b READY.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadYield (void);
/// Suspend execution of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadSuspend (osThreadId_t thread_id);
/// Resume execution of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadResume (osThreadId_t thread_id);
/// Detach a thread (thread storage can be reclaimed when thread terminates).
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadDetach (osThreadId_t thread_id);
/// Wait for specified thread to terminate.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadJoin (osThreadId_t thread_id);
/// Terminate execution of current running thread.
__NO_RETURN void osThreadExit (void);
/// Terminate execution of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \return status code that indicates the execution status of the function.
osStatus_t osThreadTerminate (osThreadId_t thread_id);
/// Get number of active threads.
/// \return number of active threads.
uint32_t osThreadGetCount (void);
/// Enumerate active threads.
/// \param[out] thread_array pointer to array for retrieving thread IDs.
/// \param[in] array_items maximum number of items in array for retrieving thread IDs.
/// \return number of enumerated threads.
uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items);
// ==== Thread Flags Functions ====
/// Set the specified Thread Flags of a thread.
/// \param[in] thread_id thread ID obtained by \ref osThreadNew or \ref osThreadGetId.
/// \param[in] flags specifies the flags of the thread that shall be set.
/// \return thread flags after setting or error code if highest bit set.
uint32_t osThreadFlagsSet (osThreadId_t thread_id, uint32_t flags);
/// Clear the specified Thread Flags of current running thread.
/// \param[in] flags specifies the flags of the thread that shall be cleared.
/// \return thread flags before clearing or error code if highest bit set.
uint32_t osThreadFlagsClear (uint32_t flags);
/// Get the current Thread Flags of current running thread.
/// \return current thread flags.
uint32_t osThreadFlagsGet (void);
/// Wait for one or more Thread Flags of the current running thread to become signaled.
/// \param[in] flags specifies the flags to wait for.
/// \param[in] options specifies flags options (osFlagsXxxx).
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return thread flags before clearing or error code if highest bit set.
uint32_t osThreadFlagsWait (uint32_t flags, uint32_t options, uint32_t timeout);
// ==== Generic Wait Functions ====
/// Wait for Timeout (Time Delay).
/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value
/// \return status code that indicates the execution status of the function.
osStatus_t osDelay (uint32_t ticks);
/// Wait until specified time.
/// \param[in] ticks absolute time in ticks
/// \return status code that indicates the execution status of the function.
osStatus_t osDelayUntil (uint32_t ticks);
// ==== Timer Management Functions ====
/// Create and Initialize a timer.
/// \param[in] func function pointer to callback function.
/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior.
/// \param[in] argument argument to the timer callback function.
/// \param[in] attr timer attributes; NULL: default values.
/// \return timer ID for reference by other functions or NULL in case of error.
osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
/// Get name of a timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
/// \return name as null-terminated string.
const char *osTimerGetName (osTimerId_t timer_id);
/// Start or restart a timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
/// \param[in] ticks \ref CMSIS_RTOS_TimeOutValue "time ticks" value of the timer.
/// \return status code that indicates the execution status of the function.
osStatus_t osTimerStart (osTimerId_t timer_id, uint32_t ticks);
/// Stop a timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osTimerStop (osTimerId_t timer_id);
/// Check if a timer is running.
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
/// \return 0 not running, 1 running.
uint32_t osTimerIsRunning (osTimerId_t timer_id);
/// Delete a timer.
/// \param[in] timer_id timer ID obtained by \ref osTimerNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osTimerDelete (osTimerId_t timer_id);
// ==== Event Flags Management Functions ====
/// Create and Initialize an Event Flags object.
/// \param[in] attr event flags attributes; NULL: default values.
/// \return event flags ID for reference by other functions or NULL in case of error.
osEventFlagsId_t osEventFlagsNew (const osEventFlagsAttr_t *attr);
/// Get name of an Event Flags object.
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
/// \return name as null-terminated string.
const char *osEventFlagsGetName (osEventFlagsId_t ef_id);
/// Set the specified Event Flags.
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
/// \param[in] flags specifies the flags that shall be set.
/// \return event flags after setting or error code if highest bit set.
uint32_t osEventFlagsSet (osEventFlagsId_t ef_id, uint32_t flags);
/// Clear the specified Event Flags.
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
/// \param[in] flags specifies the flags that shall be cleared.
/// \return event flags before clearing or error code if highest bit set.
uint32_t osEventFlagsClear (osEventFlagsId_t ef_id, uint32_t flags);
/// Get the current Event Flags.
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
/// \return current event flags.
uint32_t osEventFlagsGet (osEventFlagsId_t ef_id);
/// Wait for one or more Event Flags to become signaled.
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
/// \param[in] flags specifies the flags to wait for.
/// \param[in] options specifies flags options (osFlagsXxxx).
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return event flags before clearing or error code if highest bit set.
uint32_t osEventFlagsWait (osEventFlagsId_t ef_id, uint32_t flags, uint32_t options, uint32_t timeout);
/// Delete an Event Flags object.
/// \param[in] ef_id event flags ID obtained by \ref osEventFlagsNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osEventFlagsDelete (osEventFlagsId_t ef_id);
// ==== Mutex Management Functions ====
/// Create and Initialize a Mutex object.
/// \param[in] attr mutex attributes; NULL: default values.
/// \return mutex ID for reference by other functions or NULL in case of error.
osMutexId_t osMutexNew (const osMutexAttr_t *attr);
/// Get name of a Mutex object.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
/// \return name as null-terminated string.
const char *osMutexGetName (osMutexId_t mutex_id);
/// Acquire a Mutex or timeout if it is locked.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);
/// Release a Mutex that was acquired by \ref osMutexAcquire.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osMutexRelease (osMutexId_t mutex_id);
/// Get Thread which owns a Mutex object.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
/// \return thread ID of owner thread or NULL when mutex was not acquired.
osThreadId_t osMutexGetOwner (osMutexId_t mutex_id);
/// Delete a Mutex object.
/// \param[in] mutex_id mutex ID obtained by \ref osMutexNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osMutexDelete (osMutexId_t mutex_id);
// ==== Semaphore Management Functions ====
/// Create and Initialize a Semaphore object.
/// \param[in] max_count maximum number of available tokens.
/// \param[in] initial_count initial number of available tokens.
/// \param[in] attr semaphore attributes; NULL: default values.
/// \return semaphore ID for reference by other functions or NULL in case of error.
osSemaphoreId_t osSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr);
/// Get name of a Semaphore object.
/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
/// \return name as null-terminated string.
const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id);
/// Acquire a Semaphore token or timeout if no tokens are available.
/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout);
/// Release a Semaphore token up to the initial maximum count.
/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id);
/// Get current Semaphore token count.
/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
/// \return number of tokens available.
uint32_t osSemaphoreGetCount (osSemaphoreId_t semaphore_id);
/// Delete a Semaphore object.
/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osSemaphoreDelete (osSemaphoreId_t semaphore_id);
// ==== Memory Pool Management Functions ====
/// Create and Initialize a Memory Pool object.
/// \param[in] block_count maximum number of memory blocks in memory pool.
/// \param[in] block_size memory block size in bytes.
/// \param[in] attr memory pool attributes; NULL: default values.
/// \return memory pool ID for reference by other functions or NULL in case of error.
osMemoryPoolId_t osMemoryPoolNew (uint32_t block_count, uint32_t block_size, const osMemoryPoolAttr_t *attr);
/// Get name of a Memory Pool object.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \return name as null-terminated string.
const char *osMemoryPoolGetName (osMemoryPoolId_t mp_id);
/// Allocate a memory block from a Memory Pool.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return address of the allocated memory block or NULL in case of no memory is available.
void *osMemoryPoolAlloc (osMemoryPoolId_t mp_id, uint32_t timeout);
/// Return an allocated memory block back to a Memory Pool.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \param[in] block address of the allocated memory block to be returned to the memory pool.
/// \return status code that indicates the execution status of the function.
osStatus_t osMemoryPoolFree (osMemoryPoolId_t mp_id, void *block);
/// Get maximum number of memory blocks in a Memory Pool.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \return maximum number of memory blocks.
uint32_t osMemoryPoolGetCapacity (osMemoryPoolId_t mp_id);
/// Get memory block size in a Memory Pool.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \return memory block size in bytes.
uint32_t osMemoryPoolGetBlockSize (osMemoryPoolId_t mp_id);
/// Get number of memory blocks used in a Memory Pool.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \return number of memory blocks used.
uint32_t osMemoryPoolGetCount (osMemoryPoolId_t mp_id);
/// Get number of memory blocks available in a Memory Pool.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \return number of memory blocks available.
uint32_t osMemoryPoolGetSpace (osMemoryPoolId_t mp_id);
/// Delete a Memory Pool object.
/// \param[in] mp_id memory pool ID obtained by \ref osMemoryPoolNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osMemoryPoolDelete (osMemoryPoolId_t mp_id);
// ==== Message Queue Management Functions ====
/// Create and Initialize a Message Queue object.
/// \param[in] msg_count maximum number of messages in queue.
/// \param[in] msg_size maximum message size in bytes.
/// \param[in] attr message queue attributes; NULL: default values.
/// \return message queue ID for reference by other functions or NULL in case of error.
osMessageQueueId_t osMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr);
/// Get name of a Message Queue object.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return name as null-terminated string.
const char *osMessageQueueGetName (osMessageQueueId_t mq_id);
/// Put a Message into a Queue or timeout if Queue is full.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \param[in] msg_ptr pointer to buffer with message to put into a queue.
/// \param[in] msg_prio message priority.
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
osStatus_t osMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout);
/// Get a Message from a Queue or timeout if Queue is empty.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \param[out] msg_ptr pointer to buffer for message to get from a queue.
/// \param[out] msg_prio pointer to buffer for message priority or NULL.
/// \param[in] timeout \ref CMSIS_RTOS_TimeOutValue or 0 in case of no time-out.
/// \return status code that indicates the execution status of the function.
osStatus_t osMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout);
/// Get maximum number of messages in a Message Queue.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return maximum number of messages.
uint32_t osMessageQueueGetCapacity (osMessageQueueId_t mq_id);
/// Get maximum message size in a Memory Pool.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return maximum message size in bytes.
uint32_t osMessageQueueGetMsgSize (osMessageQueueId_t mq_id);
/// Get number of queued messages in a Message Queue.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return number of queued messages.
uint32_t osMessageQueueGetCount (osMessageQueueId_t mq_id);
/// Get number of available slots for messages in a Message Queue.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return number of available slots for messages.
uint32_t osMessageQueueGetSpace (osMessageQueueId_t mq_id);
/// Reset a Message Queue to initial empty state.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osMessageQueueReset (osMessageQueueId_t mq_id);
/// Delete a Message Queue object.
/// \param[in] mq_id message queue ID obtained by \ref osMessageQueueNew.
/// \return status code that indicates the execution status of the function.
osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);
#ifdef __cplusplus
}
#endif
#endif // CMSIS_OS2_H_

71
osal/cmsis_os/os_tick.h Normal file
View File

@@ -0,0 +1,71 @@
/**************************************************************************//**
* @file os_tick.h
* @brief CMSIS OS Tick header file
* @version V1.0.1
* @date 24. November 2017
******************************************************************************/
/*
* Copyright (c) 2017-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
#ifndef OS_TICK_H
#define OS_TICK_H
#include <stdint.h>
/// IRQ Handler.
#ifndef IRQHANDLER_T
#define IRQHANDLER_T
typedef void (*IRQHandler_t) (void);
#endif
/// Setup OS Tick timer to generate periodic RTOS Kernel Ticks
/// \param[in] freq tick frequency in Hz
/// \param[in] handler tick IRQ handler
/// \return 0 on success, -1 on error.
int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler);
/// Enable OS Tick timer interrupt
void OS_Tick_Enable (void);
/// Disable OS Tick timer interrupt
void OS_Tick_Disable (void);
/// Acknowledge execution of OS Tick timer interrupt
void OS_Tick_AcknowledgeIRQ (void);
/// Get OS Tick timer IRQ number
/// \return OS Tick IRQ number
int32_t OS_Tick_GetIRQn (void);
/// Get OS Tick timer clock frequency
/// \return OS Tick timer clock frequency in Hz
uint32_t OS_Tick_GetClock (void);
/// Get OS Tick timer interval reload value
/// \return OS Tick timer interval reload value
uint32_t OS_Tick_GetInterval (void);
/// Get OS Tick timer counter value
/// \return OS Tick timer counter value
uint32_t OS_Tick_GetCount (void);
/// Get OS Tick timer overflow status
/// \return OS Tick overflow status (1 - overflow, 0 - no overflow).
uint32_t OS_Tick_GetOverflow (void);
#endif /* OS_TICK_H */

35
osal/posix/Makefile Normal file
View File

@@ -0,0 +1,35 @@
###################################################################
#automatic detection QTOP and LOCALDIR
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
echo $$QTOP;\
else\
cd $(CUR_DIR); while /usr/bin/test ! -d qmk ; do \
dir=`cd ../;pwd`; \
if [ "$$dir" = "/" ] ; then \
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
exit 1; \
fi ; \
cd $$dir; \
done ; \
pwd; \
fi)
QTOP ?= $(realpath ${TRYQTOP})
ifeq ($(QTOP),)
$(error Please run this in a tree)
endif
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
####################################################################
TREE_LIB_ENABLE=0
lib=
subdirs=
CFGFLAGS += -I$(CUR_DIR)/include
include ${QTOP}/qmk/generic/Make.tpl

267
osal/posix/include/errno.h Normal file
View File

@@ -0,0 +1,267 @@
/*---------------------------------------------------------------------------- * 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 _POSIX_ERRNO_H_
#define _POSIX_ERRNO_H_
#define ENOERR 0
#define ENOERR_STR "No error."
#define E2BIG 1
#define E2BIG_STR "Argument list too long."
#define EACCES 2
#define EACCES_STR "Permission denied."
#define EADDRINUSE 3
#define EADDRINUSE_STR "Address in use."
#define EADDRNOTAVAIL 4
#define EADDRNOTAVAIL_STR "Address not available."
#define EAFNOSUPPORT 5
#define EAFNOSUPPORT_STR "Address family not supported."
#define EAGAIN 6
#define EAGAIN_STR "Resource unavailable, try again (may be the same value as [EWOULDBLOCK])."
#define EALREADY 7
#define EALREADY_STR "Connection already in progress."
#define EBADF 8
#define EBADF_STR "Bad file descriptor."
#define EBADMSG 9
#define EBADMSG_STR "Bad message."
#define EBUSY 10
#define EBUSY_STR "Device or resource busy."
#define ECANCELED 11
#define ECANCELED_STR "Operation canceled."
#define ECHILD 12
#define ECHILD_STR "No child processes."
#define ECONNABORTED 13
#define ECONNABORTED_STR "Connection aborted."
#define ECONNREFUSED 14
#define ECONNREFUSED_STR "Connection refused."
#define ECONNRESET 15
#define ECONNRESET_STR "Connection reset."
#define EDEADLK 16
#define EDEADLK_STR "Resource deadlock would occur."
#define EDESTADDRREQ 17
#define EDESTADDRREQ_STR "Destination address required."
#define EDOM 18
#define EDOM_STR "Mathematics argument out of domain of function."
#define EDQUOT 19
#define EDQUOT_STR "Reserved."
#define EEXIST 20
#define EEXIST_STR "File exists."
#define EFAULT 21
#define EFAULT_STR "Bad address."
#define EFBIG 22
#define EFBIG_STR "File too large."
#define EHOSTUNREACH 23
#define EHOSTUNREACH_STR "Host is unreachable."
#define EIDRM 24
#define EIDRM_STR "Identifier removed."
#define EILSEQ 25
#define EILSEQ_STR "Illegal byte sequence."
#define EINPROGRESS 26
#define EINPROGRESS_STR "Operation in progress."
#define EINTR 27
#define EINTR_STR "Interrupted function."
#define EINVAL 28
#define EINVAL_STR "Invalid argument."
#define EIO 29
#define EIO_STR "I/O error."
#define EISCONN 30
#define EISCONN_STR "Socket is connected."
#define EISDIR 31
#define EISDIR_STR "Is a directory."
#define ELOOP 32
#define ELOOP_STR "Too many levels of symbolic links."
#define EMFILE 33
#define EMFILE_STR "File descriptor value too large."
#define EMLINK 34
#define EMLINK_STR "Too many links."
#define EMSGSIZE 35
#define EMSGSIZE_STR "Message too large."
#define EMULTIHOP 36
#define EMULTIHOP_STR "Reserved."
#define ENAMETOOLONG 37
#define ENAMETOOLONG_STR "Filename too long."
#define ENETDOWN 38
#define ENETDOWN_STR "Network is down."
#define ENETRESET 39
#define ENETRESET_STR "Connection aborted by network."
#define ENETUNREACH 40
#define ENETUNREACH_STR "Network unreachable."
#define ENFILE 41
#define ENFILE_STR "Too many files open in system."
#define ENOBUFS 42
#define ENOBUFS_STR "No buffer space available."
#define ENODATA 43
#define ENODATA_STR "No message is available on the STREAM head read queue. "
#define ENODEV 44
#define ENODEV_STR "No such device."
#define ENOENT 45
#define ENOENT_STR "No such file or directory."
#define ENOEXEC 46
#define ENOEXEC_STR "Executable file format error."
#define ENOLCK 47
#define ENOLCK_STR "No locks available."
#define ENOLINK 48
#define ENOLINK_STR "Reserved."
#define ENOMEM 49
#define ENOMEM_STR "Not enough space."
#define ENOMSG 50
#define ENOMSG_STR "No message of the desired type."
#define ENOPROTOOPT 51
#define ENOPROTOOPT_STR "Protocol not available."
#define ENOSPC 52
#define ENOSPC_STR "No space left on device."
#define ENOSR 53
#define ENOSR_STR "No STREAM resources."
#define ENOSTR 54
#define ENOSTR_STR "Not a STREAM."
#define ENOSYS 55
#define ENOSYS_STR "Functionality not supported."
#define ENOTCONN 56
#define ENOTCONN_STR "The socket is not connected."
#define ENOTDIR 57
#define ENOTDIR_STR "Not a directory or a symbolic link to a directory."
#define ENOTEMPTY 58
#define ENOTEMPTY_STR "Directory not empty."
#define ENOTRECOVERABLE 59
#define ENOTRECOVERABLE_STR "State not recoverable."
#define ENOTSOCK 60
#define ENOTSOCK_STR "Not a socket."
#define ENOTSUP 61
#define ENOTSUP_STR "Not supported (may be the same value as [EOPNOTSUPP]). "
#define ENOTTY 62
#define ENOTTY_STR "Inappropriate I/O control operation."
#define ENXIO 63
#define ENXIO_STR "No such device or address."
#define EOPNOTSUPP 64
#define EOPNOTSUPP_STR "Operation not supported on socket (may be the same value as [ENOTSUP])."
#define EOVERFLOW 65
#define EOVERFLOW_STR "Value too large to be stored in data type."
#define EOWNERDEAD 66
#define EOWNERDEAD_STR "Previous owner died."
#define EPERM 67
#define EPERM_STR "Operation not permitted."
#define EPIPE 68
#define EPIPE_STR "Broken pipe."
#define EPROTO 69
#define EPROTO_STR "Protocol error."
#define EPROTONOSUPPORT 70
#define EPROTONOSUPPORT_STR "Protocol not supported."
#define EPROTOTYPE 71
#define EPROTOTYPE_STR "Protocol wrong type for socket."
#define ERANGE 72
#define ERANGE_STR "Result too large."
#define EROFS 73
#define EROFS_STR "Read-only file system."
#define ESPIPE 74
#define ESPIPE_STR "Invalid seek."
#define ESRCH 75
#define ESRCH_STR "No such process."
#define ESTALE 76
#define ESTALE_STR "Reserved."
#define ETIME 77
#define ETIME_STR "Stream ioctl() timeout."
#define ETIMEDOUT 78
#define ETIMEDOUT_STR "Connection timed out."
#define ETXTBSY 79
#define ETXTBSY_STR "Text file busy."
#define EWOULDBLOCK 80
#define EWOULDBLOCK_STR "Operation would block (may be the same value as [EAGAIN])."
#define EXDEV 81
#define EXDEV_STR "Cross-device link."
#endif /* _POSIX_ERRNO_H_ */

View File

@@ -0,0 +1,53 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_MQUEUE_H_
#define _POSIX_MQUEUE_H_
#include "tos_k.h"
#include "signal.h"
#include "time.h"
__CDECLS_BEGIN
typedef int mqd_t;
struct mq_attr {
long mq_flags; /* message queue flags */
long mq_maxmsg; /* maximum number of messages */
long mq_msgsize; /* maximum message size */
long mq_curmsgs; /* number of messages currently queued */
};
#define __NOTSUPP__
__API__ int mq_close(mqd_t mqdes);
__NOTSUPP__ int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat);
__NOTSUPP__ int mq_notify(mqd_t mqdes, const struct sigevent *notification);
__API__ mqd_t mq_open(const char *name, int oflag, ...);
__API__ ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);
__API__ int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
__NOTSUPP__ int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat);
__API__ ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abstime);
__NOTSUPP__ int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abstime);
__NOTSUPP__ int mq_unlink(const char *name);
__CDECLS_END
#endif /* _POSIX_MQUEUE_H_ */

View File

@@ -0,0 +1,47 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_PRIVATE_MQUEUE_H_
#define _POSIX_PRIVATE_MQUEUE_H_
#include "tos_k.h"
#include "private/posix_config.h"
__CDECLS_BEGIN
#define MQUEUE_MAX (POSIX_CFG_MQUEUE_MAX)
#define MQUEUE_MSG_MAX 20
#define MQUEUE_MSG_SIZE_MAX 50
typedef struct mqueue_control_st {
mqd_t id;
k_prio_mail_q_t kprio_mail_q;
} mqueue_ctl_t;
__KNL__ int mqueue_id_add(mqd_t id, mqueue_ctl_t *mqueue_ctl);
__KNL__ mqd_t mqueue_id_alloc(void);
__KNL__ int mqueue_id_free(mqd_t id);
__KNL__ mqueue_ctl_t *mqueue_by_id(mqd_t id);
__CDECLS_END
#endif /* _POSIX_PRIVATE_MQUEUE_H_ */

View File

@@ -0,0 +1,48 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_CONFIG_H_
#define _POSIX_CONFIG_H_
#define POSIX_CFG_PTHREAD_THREADS_MAX 32
#define POSIX_CFG_PTHREAD_DESTRUCTOR_ITERATIONS 4
#define POSIX_CFG_PTHREAD_KEYS_MAX 8
#define POSIX_CFG_TIMERS_MAX 8
#define POSIX_CFG_MQUEUE_MAX 8
#define POSIX_CFG_PTHREAD_BARRIER_EN 1u
#define POSIX_CFG_PTHREAD_COND_EN 1u
#define POSIX_CFG_PTHREAD_MUTEX_EN 1u
#define POSIX_CFG_PTHREAD_RWLOCK_EN 1u
#define POSIX_CFG_PTHREAD_SPIN_EN 1u
#define POSIX_CFG_SEM_EN 1u
#define POSIX_CFG_MQUEUE_EN 1u
#define POSIX_CFG_TIMER_EN 1u
#include "private/posix_config_check.h"
#endif /* _POSIX_CONFIG_H_ */

View File

@@ -0,0 +1,57 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_CONFIG_CHECK_H_
#define _POSIX_CONFIG_CHECK_H_
#include "tos_config.h"
#include "private/posix_config_default.h"
#if (POSIX_CFG_PTHREAD_COND_EN > 0u) && (TOS_CFG_SEM_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_SEM_EN to use pthread_cond"
#endif
#if (POSIX_CFG_PTHREAD_COND_EN > 0u) && (TOS_CFG_MUTEX_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_MUTEX_EN to use pthread_cond"
#endif
#if (POSIX_CFG_PTHREAD_MUTEX_EN > 0u) && (TOS_CFG_MUTEX_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_MUTEX_EN to use pthread_mutex"
#endif
#if (POSIX_CFG_PTHREAD_RWLOCK_EN > 0u) && (TOS_CFG_SEM_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_SEM_EN to use pthread_rwlock"
#endif
#if (POSIX_CFG_PTHREAD_RWLOCK_EN > 0u) && (TOS_CFG_MUTEX_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_MUTEX_EN to use pthread_rwlock"
#endif
#if (POSIX_CFG_SEM_EN > 0u) && (TOS_CFG_SEM_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_SEM_EN to use posix sem"
#endif
#if (POSIX_CFG_MQUEUE_EN > 0u) && (TOS_CFG_PRIORITY_MAIL_QUEUE_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_PRIORITY_MAIL_QUEUE_EN to use posix mqueue"
#endif
#if (POSIX_CFG_TIMER_EN > 0u) && (TOS_CFG_TIMER_EN == 0u)
#error "INVALID config, Must enable TOS_CFG_TIMER_EN to use posix timer"
#endif
#endif /* _POSIX_CONFIG_CHECK_H_ */

View File

@@ -0,0 +1,74 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_CONFIG_DEFAULT_H_
#define _POSIX_CONFIG_DEFAULT_H_
#ifndef POSIX_CFG_PTHREAD_THREADS_MAX
#define POSIX_CFG_PTHREAD_THREADS_MAX 32
#endif
#ifndef POSIX_CFG_PTHREAD_DESTRUCTOR_ITERATIONS
#define POSIX_CFG_PTHREAD_DESTRUCTOR_ITERATIONS 4
#endif
#ifndef POSIX_CFG_PTHREAD_KEYS_MAX
#define POSIX_CFG_PTHREAD_KEYS_MAX 8
#endif
#ifndef POSIX_CFG_TIMERS_MAX
#define POSIX_CFG_TIMERS_MAX 8
#endif
#ifndef POSIX_CFG_MQUEUE_MAX
#define POSIX_CFG_MQUEUE_MAX 8
#endif
#ifndef POSIX_CFG_PTHREAD_BARRIER_EN
#define POSIX_CFG_PTHREAD_BARRIER_EN 1u
#endif
#ifndef POSIX_CFG_PTHREAD_COND_EN
#define POSIX_CFG_PTHREAD_COND_EN 1u
#endif
#ifndef POSIX_CFG_PTHREAD_MUTEX_EN
#define POSIX_CFG_PTHREAD_MUTEX_EN 1u
#endif
#ifndef POSIX_CFG_PTHREAD_RWLOCK_EN
#define POSIX_CFG_PTHREAD_RWLOCK_EN 1u
#endif
#ifndef POSIX_CFG_PTHREAD_SPIN_EN
#define POSIX_CFG_PTHREAD_SPIN_EN 1u
#endif
#ifndef POSIX_CFG_SEM_EN
#define POSIX_CFG_SEM_EN 1u
#endif
#ifndef POSIX_CFG_MQUEUE_EN
#define POSIX_CFG_MQUEUE_EN 1u
#endif
#ifndef POSIX_CFG_TIMER_EN
#define POSIX_CFG_TIMER_EN 1u
#endif
#endif /* _POSIX_CONFIG_DEFAULT_H_ */

View File

@@ -0,0 +1,119 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_PRIVATE_PTHREAD_H_
#define _POSIX_PRIVATE_PTHREAD_H_
#include "tos_k.h"
#include "private/posix_config.h"
#include "sys/types.h"
__CDECLS_BEGIN
typedef struct pthread_control_st {
uint16_t threadstate : 4;
uint16_t cancelstate : 2;
uint16_t canceltype : 2;
uint16_t cancelpending : 1;
pthread_t id;
pthread_attr_t attr;
k_task_t ktask;
k_task_t *the_ktask;
k_sem_t joinner_sem;
void *(*start_routine)(void *); /* start routine of the pthread */
void *arg; /* argument for start routine */
void *retval; /* return value of start routine */
void *stackaddr; /* memory address of stack */
k_slist_t cleanup_ctl_list;
void **thread_data;
} pthread_ctl_t;
typedef struct pthread_cleanup_control_st {
void (*routine)(void *); /* function to be called */
void *arg; /* argument for the routine */
k_slist_t list;
} pthread_cleanup_ctl_t;
#define PTHREAD_KEYS_MAX (POSIX_CFG_PTHREAD_KEYS_MAX)
typedef void (*key_destructor_t)(void*);
typedef struct pthread_key_control_st {
k_bmtbl_t key_bitmap_tbl[TOS_BITMAP_SIZE(PTHREAD_KEYS_MAX)];
k_bitmap_t key_bitmap;
key_destructor_t destructors[PTHREAD_KEYS_MAX];
} pthread_key_ctl_t;
#define PTHREAD_INFO_SIZE (sizeof(pthread_ctl_t))
#define PTHREAD_STK_SIZE_MIN (K_TASK_STK_SIZE_MIN + PTHREAD_INFO_SIZE)
#define PTHREAD_DEFAULT_TIMESLICE 20
#define PTHREAD_DEFAULT_STACKSIZE (2048 + PTHREAD_INFO_SIZE)
#define PTHREAD_DEFAULT_INHERIT_SCHED PTHREAD_INHERIT_SCHED
#define PTHREAD_DEFAULT_SCHEDPOLICY SCHED_OTHER
#define PTHREAD_DEFAULT_PRIORITY (TOS_CFG_TASK_PRIO_MAX / 2)
#define PTHREAD_DEFAULT_DETACH_STATE PTHREAD_CREATE_JOINABLE
#define PTHREAD_DESTRUCTOR_ITERATIONS (POSIX_CFG_PTHREAD_DESTRUCTOR_ITERATIONS)
#define PTHREAD_THREADS_MAX (POSIX_CFG_PTHREAD_THREADS_MAX)
__KNL__ pthread_ctl_t *pthread_ctl_self(void);
__KNL__ pthread_ctl_t *pthread_ctl_by_id(pthread_t id);
__KNL__ int pthread_id_add(pthread_t id, pthread_ctl_t *info);
__KNL__ pthread_t pthread_id_alloc(void);
__KNL__ int pthread_id_free(pthread_t id);
__KNL__ void pthread_data_clear(pthread_key_t key);
__KNL__ int pthread_key_ctl_init(void);
__KNL__ pthread_key_t pthread_key_alloc(void);
__KNL__ int pthread_key_is_alloc(pthread_key_t key);
__KNL__ int pthread_key_free(pthread_key_t key);
__KNL__ int pthread_key_destructor_register(pthread_key_t key, key_destructor_t destructor);
__KNL__ key_destructor_t pthread_key_destructor_get(pthread_key_t key);
__KNL__ int pthread_ctl_reap(int pthreads_ready2reap);
__KNL__ void pthread_lock(void);
__KNL__ void pthread_unlock(void);
__KNL__ int pthread_lock_init(void);
__KNL__ int pthread_init(void);
__CDECLS_END
#endif /* _POSIX_PRIVATE_PTHREAD_H_ */

View File

@@ -0,0 +1,36 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_PRIVATE_TIME_H_
#define _POSIX_PRIVATE_TIME_H_
#include "tos_k.h"
__CDECLS_BEGIN
#define MILLISECOND_PER_SECOND 1000UL
#define MICROSECOND_PER_SECOND 1000000UL
#define NANOSECOND_PER_SECOND 1000000000UL
__KNL__ k_tick_t timespec_to_ktick(const struct timespec *tp);
__KNL__ void ktick_to_timespec(k_tick_t ktick, struct timespec *tp);
__CDECLS_END
#endif /* _POSIX_PRIVATE_TIME_H_ */

View File

@@ -0,0 +1,50 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_PRIVATE_TIMER_H_
#define _POSIX_PRIVATE_TIMER_H_
#include "tos_k.h"
#include "private/posix_config.h"
#include "signal.h"
__CDECLS_BEGIN
#define TIMERS_MAX (POSIX_CFG_TIMERS_MAX)
typedef struct ptimer_control_st {
timer_t id;
k_timer_t ktimer;
void (*sigev_notify_function)(union sigval);
union sigval sigev_value;
} ptimer_ctl_t;
__KNL__ int timer_id_add(timer_t id, ptimer_ctl_t *ptimer_ctl);
__KNL__ timer_t timer_id_alloc(void);
__KNL__ int timer_id_free(timer_t id);
__KNL__ ptimer_ctl_t *timer_by_id(timer_t id);
__CDECLS_END
#endif /* _POSIX_PRIVATE_TIMER_H_*/

View File

@@ -0,0 +1,189 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_PTHREAD_H_
#define _POSIX_PTHREAD_H_
#include "tos_k.h"
#include "stddef.h"
#include "limits.h"
#include "sys/types.h"
#include "sched.h"
#include "time.h"
__CDECLS_BEGIN
extern int __pthread_canceled;
#define PTHREAD_CANCELD ((void *)(&__pthread_canceled))
/* type of mutex */
#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
/* state of the thread */
#define PTHREAD_STATE_DETACHED 1 /* The thread is running but detached */
#define PTHREAD_STATE_RUNNING 2 /* The thread is running and will wait to join when it exits */
#define PTHREAD_STATE_JOIN 3 /* The thread has exited and is waiting to be joined */
#define PTHREAD_STATE_EXITED 4 /* The thread has exited and is ready to be reaped */
/* cancelability state */
#define PTHREAD_CANCEL_ENABLE 1
#define PTHREAD_CANCEL_DISABLE 2
/* cancelability type */
#define PTHREAD_CANCEL_ASYNCHRONOUS 1
#define PTHREAD_CANCEL_DEFERRED 2
/* values for detachstate*/
#define PTHREAD_CREATE_JOINABLE 1
#define PTHREAD_CREATE_DETACHED 2
/* values for inheritsched */
#define PTHREAD_INHERIT_SCHED 1
#define PTHREAD_EXPLICIT_SCHED 2
#define PTHREAD_ONCE_INIT 0
#define PTHREAD_COND_INITIALIZER
#define PTHREAD_MUTEX_INITIALIZER
#define PTHREAD_RWLOCK_INITIALIZER
#define __NOTSUPP__
__NOTSUPP__ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void(*child)(void));
__API__ int pthread_attr_destroy(pthread_attr_t *attr);
__API__ int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
__NOTSUPP__ int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize);
__API__ int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched);
__API__ int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);
__API__ int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);
__NOTSUPP__ int pthread_attr_getscope(const pthread_attr_t *attr, int *contentionscope);
__API__ int pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t *stacksize);
__API__ int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);
__API__ int pthread_attr_init(pthread_attr_t *attr);
__API__ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
__NOTSUPP__ int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize);
__API__ int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);
__API__ int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);
__API__ int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
__NOTSUPP__ int pthread_attr_setscope(pthread_attr_t *attr, int contentionscope);
__API__ int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize);
__API__ int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
__API__ int pthread_barrier_destroy(pthread_barrier_t *barrier);
__API__ int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count);
__API__ int pthread_barrier_wait(pthread_barrier_t *barrier);
__NOTSUPP__ int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
__NOTSUPP__ int pthread_barrierattr_getpshared(const pthread_barrierattr_t *attr, int *pshared);
__NOTSUPP__ int pthread_barrierattr_init(pthread_barrierattr_t *attr);
__NOTSUPP__ int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int pshared);
__API__ int pthread_cancel(pthread_t thread);
__API__ int pthread_cond_broadcast(pthread_cond_t *cond);
__API__ int pthread_cond_destroy(pthread_cond_t *cond);
__API__ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
__API__ int pthread_cond_signal(pthread_cond_t *cond);
__API__ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
__API__ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
__NOTSUPP__ int pthread_condattr_destroy(pthread_condattr_t *attr);
__NOTSUPP__ int pthread_condattr_getclock(const pthread_condattr_t *attr, clockid_t *clock_id);
__NOTSUPP__ int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared);
__NOTSUPP__ int pthread_condattr_init(pthread_condattr_t *attr);
__NOTSUPP__ int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id);
__NOTSUPP__ int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared);
__API__ int pthread_create(pthread_t *pthread, const pthread_attr_t *attr, void *(*entry)(void*), void *arg);
__API__ int pthread_detach(pthread_t thread);
__API__ int pthread_equal(pthread_t t1, pthread_t t2);
__API__ void pthread_exit(void *value_ptr);
__NOTSUPP__ int pthread_getconcurrency(void);
__NOTSUPP__ int pthread_getcpuclockid(pthread_t thread_id, clockid_t *clock_id);
__API__ int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);
__API__ void *pthread_getspecific(pthread_key_t key);
__API__ int pthread_join(pthread_t thread, void **value_ptr);
__API__ int pthread_key_create(pthread_key_t *, void (*)(void*));
__API__ int pthread_key_delete(pthread_key_t);
__NOTSUPP__ int pthread_mutex_consistent(pthread_mutex_t *mutex);
__API__ int pthread_mutex_destroy(pthread_mutex_t *mutex);
__NOTSUPP__ int pthread_mutex_getprioceiling(const pthread_mutex_t *mutex, int *prioceiling);
__API__ int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
__API__ int pthread_mutex_lock(pthread_mutex_t *mutex);
__NOTSUPP__ int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling);
__API__ int pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abstime);
__API__ int pthread_mutex_trylock(pthread_mutex_t *mutex);
__API__ int pthread_mutex_unlock(pthread_mutex_t *mutex);
__API__ int pthread_mutexattr_destroy(pthread_mutexattr_t *);
__NOTSUPP__ int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *mutex, int *prioceiling);
__NOTSUPP__ int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *mutex, int *protocol);
__NOTSUPP__ int pthread_mutexattr_getpshared(const pthread_mutexattr_t *mutex, int *pshared);
__NOTSUPP__ int pthread_mutexattr_getrobust(const pthread_mutexattr_t *mutex, int *robust);
__API__ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type);
__API__ int pthread_mutexattr_init(pthread_mutexattr_t *attr);
__NOTSUPP__ int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mutex, int prioceiling);
__NOTSUPP__ int pthread_mutexattr_setprotocol(pthread_mutexattr_t *mutex, int protocol);
__NOTSUPP__ int pthread_mutexattr_setpshared(pthread_mutexattr_t *mutex, int pshared);
__NOTSUPP__ int pthread_mutexattr_setrobust(pthread_mutexattr_t *mutex, int robust);
__API__ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);
__API__ int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
__API__ int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
__API__ int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
__API__ int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
__API__ int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, const struct timespec *abstime);
__API__ int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, const struct timespec *abstime);
__API__ int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
__API__ int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
__API__ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
__API__ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
__NOTSUPP__ int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
__NOTSUPP__ int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared);
__NOTSUPP__ int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
__NOTSUPP__ int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared);
__API__ pthread_t pthread_self(void);
__API__ int pthread_setcancelstate(int state, int *oldstate);
__API__ int pthread_setcanceltype(int type, int *oldtype);
__NOTSUPP__ int pthread_setconcurrency(int new_level);
__API__ int pthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);
__API__ int pthread_setschedprio(pthread_t, int);
__API__ int pthread_setspecific(pthread_key_t key, const void *value);
__API__ int pthread_spin_destroy(pthread_spinlock_t *lock);
__API__ int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
__API__ int pthread_spin_lock(pthread_spinlock_t *lock);
__API__ int pthread_spin_trylock(pthread_spinlock_t *lock);
__API__ int pthread_spin_unlock(pthread_spinlock_t *lock);
__API__ void pthread_testcancel(void);
__API__ void pthread_cleanup_pop(int execute);
__API__ void pthread_cleanup_push(void (*routine)(void*), void *arg);
__CDECLS_END
#endif /* _POSIX_PTHREAD_H_ */

View File

@@ -0,0 +1,47 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_SCHED_H_
#define _POSIX_SCHED_H_
#include "tos_k.h"
#include "sys/types.h"
#include "time.h"
__CDECLS_BEGIN
/* Scheduling Psolicies, values for schedpolicy */
#define SCHED_FIFO 0 /* First in-first out (FIFO) scheduling policy. */
#define SCHED_RR 1 /* Round robin scheduling policy. */
#define SCHED_OTHER 2 /* Another scheduling policy. */
#define __NOTSUPP__
__API__ int sched_get_priority_max(int policy);
__API__ int sched_get_priority_min(int policy);
__API__ int sched_getparam(pid_t pid, struct sched_param *param);
__NOTSUPP__ int sched_getscheduler(pid_t pid);
__API__ int sched_rr_get_interval(pid_t pid, struct timespec *interval);
__API__ int sched_setparam(pid_t pid, const struct sched_param *param);
__NOTSUPP__ int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);
__API__ int sched_yield(void);
__CDECLS_END
#endif /* _POSIX_SCHED_H_ */

View File

@@ -0,0 +1,45 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_SEMAPHORE_H_
#define _POSIX_SEMAPHORE_H_
#include "tos_k.h"
#include "time.h"
__CDECLS_BEGIN
typedef k_sem_t sem_t;
#define __NOTSUPP__
__NOTSUPP__ int sem_close(sem_t *sem);
__API__ int sem_destroy(sem_t *sem);
__API__ int sem_getvalue(sem_t *sem, int *sval);
__API__ int sem_init(sem_t *sem, int pshared, unsigned value);
__NOTSUPP__ sem_t *sem_open(const char *name, int oflag, ...);
__API__ int sem_post(sem_t *sem);
__API__ int sem_timedwait(sem_t *sem, const struct timespec *abstime);
__API__ int sem_trywait(sem_t *sem);
__NOTSUPP__ int sem_unlink(const char *name);
__API__ int sem_wait(sem_t *sem);
__CDECLS_END
#endif /* _POSIX_SEMAPHORE_H_ */

View File

@@ -0,0 +1,37 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_SIGNAL_H_
#define _POSIX_SIGNAL_H_
#include "sys/types.h"
union sigval {
int sival_int; /* integer signal value */
void *sival_ptr; /* pointer signal value */
};
struct sigevent {
int sigev_notify; /* notification type */
int sigev_signo; /* signal number */
union sigval sigev_value; /* signal value */
void (*sigev_notify_function)(union sigval); /* notification function */
pthread_attr_t *sigev_notify_attributes; /* notification attributes */
};
#endif /* _POSIX_SIGNAL_H_ */

View File

@@ -0,0 +1,62 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_SYS_TIME_H_
#define _POSIX_SYS_TIME_H_
#include "sys/types.h"
#include "time.h"
__CDECLS_BEGIN
struct timeval {
long tv_sec;
long tv_usec;
};
struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
#define TIMEVAL_TO_TIMESPEC(tv, ts) { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
}
#define TIMESPEC_TO_TIMEVAL(tv, ts) { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
}
struct timezone {
int tz_minuteswest; /* minutes west of Greenwich */
int tz_dsttime; /* type of dst correction */
};
__API__ int getitimer(int which, struct itimerval *value);
__API__ int gettimeofday(struct timeval *tp, void *tzp);
__API__ int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
#if 0
int select(int, fd_set *restrict, fd_set *restrict, fd_set *restrict, struct timeval *restrict);
#endif
__API__ int utimes(const char *path, const struct timeval [2]);
__CDECLS_END
#endif /* _POSIX_SYS_TIME_H_ */

View File

@@ -0,0 +1,131 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_SYS_TYPES_H_
#define _POSIX_SYS_TYPES_H_
#include "stddef.h"
#include "stdint.h"
typedef uint32_t blkcnt_t; /* Used for file block counts. */
typedef size_t blksize_t; /* Used for block sizes. */
typedef uint64_t clock_t; /* Used for system times in clock ticks or CLOCKS_PER_SEC; see <time.h>. */
typedef uint32_t clockid_t; /* Used for clock ID type in the clock and timer functions. */
typedef uint32_t dev_t; /* Used for device IDs. */
typedef uint32_t fsblkcnt_t; /* Used for file system block counts. */
typedef uint32_t fsfilcnt_t; /* Used for file system file counts. */
typedef uint32_t gid_t; /* Used for group IDs. */
typedef uint32_t id_t; /* Used as a general identifier; can be used to contain at least a pid_t, uid_t, or gid_t. */
typedef uint32_t ino_t; /* Used for file serial numbers. */
typedef uint32_t key_t; /* Used for XSI interprocess communication. */
typedef uint32_t mode_t; /* Used for some file attributes. */
typedef uint32_t nlink_t; /* Used for link counts. */
typedef uint32_t off_t; /* Used for file sizes. */
typedef int pid_t; /* Used for process IDs and process group IDs. */
typedef uint32_t uid_t; /* Used for user IDs. */
#if 0 /* we donnot typedef a size_t or ssize_t here, use what is supplied by stddef.h */
size_t /* Used for sizes of objects. */
ssize_t /* Used for a count of bytes or an error indication. */
#endif
typedef int ssize_t;
typedef uint32_t suseconds_t; /* Used for time in microseconds. */
typedef uint32_t time_t; /* Used for time in seconds. */
struct sched_param {
int sched_priority; /* Process or thread execution scheduling priority. */
};
/* Used to identify a thread attribute object. */
typedef struct pthread_attr_st {
uint32_t detachstate : 2;
uint32_t inheritsched : 2; /* inherit parent priority/policy? */
uint32_t schedpolicy : 2; /* pthread scheduler policy */
uint32_t stackaddr_valid : 1;
uint32_t stacksize_valid : 1;
struct sched_param schedparam;
void *stackaddr; /* address of memory to be used as stack */
size_t stacksize; /* size of the stack allocated for the pthread */
} pthread_attr_t;
/* Used to identify a barrier. */
typedef k_barrier_t pthread_barrier_t;
/* Used to define a barrier attributes object. */
typedef uint32_t pthread_barrierattr_t;
/* Used for condition variables. */
typedef k_sem_t pthread_cond_t;
/* Used to identify a condition attribute object. */
typedef int pthread_condattr_t;
/* Used for thread-specific data keys. */
typedef int pthread_key_t;
/* Used to identify a mutex attribute object. */
typedef struct pthread_mutexattr_st {
uint8_t type : 4;
uint8_t reserved : 4;
} pthread_mutexattr_t;
/* Used for mutexes. */
typedef struct pthread_mutex_st {
k_mutex_t kmutex;
pthread_mutexattr_t attr;
} pthread_mutex_t;
/* Used for dynamic package initialization. */
typedef int pthread_once_t;
/* Used for read-write locks. */
typedef k_rwlock_t pthread_rwlock_t;
/* Used for read-write lock attributes. */
typedef int pthread_rwlockattr_t;
/* Used to identify a spin lock. */
typedef struct pthread_spinlock_st {
uint8_t is_destroyed : 1;
uint8_t is_locked : 1;
} pthread_spinlock_t;
/* Used to identify a thread. */
typedef pid_t pthread_t;
/* Used for timer ID returned by timer_create(). */
typedef int timer_t;
/* Used to identify a trace stream attributes object */
typedef int trace_attr_t;
/* Used to identify a trace event type. */
typedef int trace_event_id_t;
/* Used to identify a trace event type set. */
typedef int trace_event_set_t;
/* Used to identify a trace stream. */
typedef int trace_id_t;
#endif /* _POSIX_SYS_TYPES_H_ */

87
osal/posix/include/time.h Normal file
View File

@@ -0,0 +1,87 @@
/*----------------------------------------------------------------------------
* 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 _POSIX_TIME_H_
#define _POSIX_TIME_H_
#include "tos_k.h"
#include "sys/types.h"
#include "signal.h"
__CDECLS_BEGIN
struct tm {
int tm_sec; /* Seconds [0,60] */
int tm_min; /* Minutes [0,59] */
int tm_hour; /* Hour [0,23] */
int tm_mday; /* Day of month [1,31] */
int tm_mon; /* Month of year [0,11] */
int tm_year; /* Years since 1900 */
int tm_wday; /* Day of week [0,6] (Sunday =0) */
int tm_yday; /* Day of year [0,365] */
};
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};
struct itimerspec {
struct timespec it_interval; /* timer period */
struct timespec it_value; /* timer expiration */
};
#define CLOCK_REALTIME 0
#define __NOTSUPP__
__API__ char *asctime(const struct tm *timeptr);
__API__ char *asctime_r(const struct tm *asctime_r, char *buf);
__API__ clock_t clock(void);
__API__ int clock_getcpuclockid(pid_t pid, clockid_t *clock_id);
__API__ int clock_getres(clockid_t clock_id, struct timespec *res);
__API__ int clock_gettime(clockid_t clock_id, struct timespec *tp);
__API__ int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *rqtp, struct timespec *rmtp);
__API__ int clock_settime(clockid_t clock_id, const struct timespec *tp);
__API__ char *ctime(const time_t *clock);
__API__ char *ctime_r(const time_t *clock, char *buf);
__API__ double difftime(time_t time1, time_t time0);
__API__ struct tm *getdate(const char *string);
__API__ struct tm *gmtime(const time_t *timer);
__API__ struct tm *gmtime_r(const time_t *timer, struct tm *result);
__API__ struct tm *localtime(const time_t *timer);
__API__ struct tm *localtime_r(const time_t *timer, struct tm *result);
__API__ time_t mktime(struct tm *timeptr);
__API__ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
__API__ size_t strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr);
#if 0
__API__ size_t strftime_l(char *s, size_t maxsize, const char *format, const struct tm *timeptr, locale_t locale);
#endif
__API__ char *strptime(const char *buf, const char *format, struct tm *tm);
__API__ time_t time(time_t *tloc);
__API__ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid);
__API__ int timer_delete(timer_t timerid);
__NOTSUPP__ int timer_getoverrun(timer_t timerid);
__API__ int timer_gettime(timer_t timerid, struct itimerspec *value);
__API__ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);
__API__ void tzset(void);
__CDECLS_END
#endif /* _POSIX_TIME_H_ */

View File

@@ -0,0 +1,30 @@
/*----------------------------------------------------------------------------
* 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_POSIX_H_
#define _TOS_POSIX_H_
#include "tos_k.h"
__CDECLS_BEGIN
__API__ int tos_posix_init(void);
__CDECLS_END
#endif /* _TOS_POSIX_H_ */

173
osal/posix/mqueue.c Normal file
View File

@@ -0,0 +1,173 @@
/*----------------------------------------------------------------------------
* 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 "private/posix_config.h"
#include "errno.h"
#include "mqueue.h"
#include "private/time.h"
#include "private/mqueue.h"
#if POSIX_CFG_MQUEUE_EN > 0u
__API__ int mq_close(mqd_t mqdes)
{
k_err_t kerr;
mqueue_ctl_t *the_ctl;
the_ctl = mqueue_by_id(mqdes);
if (!the_ctl) {
return EINVAL;
}
kerr = tos_prio_mail_q_destroy_dyn((k_prio_mail_q_t *)&the_ctl->kprio_mail_q);
mqueue_id_free(mqdes);
tos_mmheap_free(the_ctl);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__NOTSUPP__ int mq_getattr(mqd_t mqdes, struct mq_attr *mqstat)
{
return EOPNOTSUPP;
}
__NOTSUPP__ int mq_notify(mqd_t mqdes, const struct sigevent *notification)
{
return EOPNOTSUPP;
}
__API__ mqd_t mq_open(const char *name, int oflag, ...)
{
mqd_t id;
k_err_t kerr;
mode_t mode;
va_list arg;
mqueue_ctl_t *the_ctl;
struct mq_attr *attr;
id = mqueue_id_alloc();
if (id == -1) {
return -1;
}
va_start(arg, oflag);
mode = va_arg(arg, mode_t);
mode = mode; /* make compiler happy */
attr = va_arg(arg, struct mq_attr *);
va_end(arg);
if (attr->mq_maxmsg > MQUEUE_MSG_MAX ||
attr->mq_msgsize > MQUEUE_MSG_SIZE_MAX) {
return EINVAL;
}
the_ctl = (mqueue_ctl_t *)tos_mmheap_alloc(sizeof(mqueue_ctl_t));
if (!the_ctl) {
return -1;
}
kerr = tos_prio_mail_q_create_dyn((k_prio_mail_q_t *)&the_ctl->kprio_mail_q,
attr->mq_maxmsg, attr->mq_msgsize);
if (kerr != K_ERR_NONE) {
tos_mmheap_free(the_ctl);
return -1;
}
the_ctl->id = id;
mqueue_id_add(id, the_ctl);
return id;
}
__API__ ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio)
{
k_err_t kerr;
mqueue_ctl_t *the_ctl;
the_ctl = mqueue_by_id(mqdes);
if (!the_ctl) {
return EINVAL;
}
kerr = tos_prio_mail_q_pend((k_prio_mail_q_t *)&the_ctl->kprio_mail_q, msg_ptr, &msg_len, TOS_TIME_FOREVER);
if (kerr == K_ERR_NONE) {
return 0;
}
return msg_len;
}
__API__ int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio)
{
k_err_t kerr;
mqueue_ctl_t *the_ctl;
the_ctl = mqueue_by_id(mqdes);
if (!the_ctl) {
return EINVAL;
}
kerr = tos_prio_mail_q_post((k_prio_mail_q_t *)&the_ctl->kprio_mail_q, (void *)msg_ptr, msg_len, msg_prio);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__NOTSUPP__ int mq_setattr(mqd_t mqdes, const struct mq_attr *mqstat, struct mq_attr *omqstat)
{
return EOPNOTSUPP;
}
__API__ ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio, const struct timespec *abstime)
{
k_err_t kerr;
k_tick_t ktick;
mqueue_ctl_t *the_ctl;
the_ctl = mqueue_by_id(mqdes);
if (!the_ctl) {
return EINVAL;
}
ktick = timespec_to_ktick(abstime);
kerr = tos_prio_mail_q_pend((k_prio_mail_q_t *)&the_ctl->kprio_mail_q, (void *)msg_ptr, &msg_len, ktick);
if (kerr == K_ERR_NONE) {
return 0;
}
return msg_len;
}
__NOTSUPP__ int mq_timedsend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio, const struct timespec *abstime)
{
return EOPNOTSUPP;
}
__NOTSUPP__ int mq_unlink(const char *name)
{
return EOPNOTSUPP;
}
#endif /* POSIX_CFG_MQUEUE_EN */

97
osal/posix/mqueue_prv.c Normal file
View File

@@ -0,0 +1,97 @@
/*----------------------------------------------------------------------------
* 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_k.h"
#include "mqueue.h"
#include "private/mqueue.h"
__STATIC__ mqueue_ctl_t *mqueue_ctl_table[MQUEUE_MAX] = { 0 };
__KNL__ int mqueue_id_add(mqd_t id, mqueue_ctl_t *mqueue_ctl)
{
TOS_CPU_CPSR_ALLOC();
if (id < 0 ||
id >= TOS_COUNT_OF(mqueue_ctl_table) ||
mqueue_ctl_table[id]) {
return -1;
}
TOS_CPU_INT_DISABLE();
mqueue_ctl_table[id] = mqueue_ctl;
TOS_CPU_INT_ENABLE();
return 0;
}
__KNL__ mqd_t mqueue_id_alloc(void)
{
TOS_CPU_CPSR_ALLOC();
int i = 0;
TOS_CPU_INT_DISABLE();
for (i = 0; i < TOS_COUNT_OF(mqueue_ctl_table); ++i) {
if (!mqueue_ctl_table[i]) {
TOS_CPU_INT_ENABLE();
return (mqd_t)i;
}
}
TOS_CPU_INT_ENABLE();
return -1;
}
__KNL__ int mqueue_id_free(mqd_t id)
{
TOS_CPU_CPSR_ALLOC();
if (id < 0 ||
id >= TOS_COUNT_OF(mqueue_ctl_table) ||
!mqueue_ctl_table[id]) {
return -1;
}
TOS_CPU_INT_DISABLE();
mqueue_ctl_table[id] = K_NULL;
TOS_CPU_INT_ENABLE();
return 0;
}
__KNL__ mqueue_ctl_t *mqueue_by_id(mqd_t id)
{
mqueue_ctl_t *the_ctl;
the_ctl = mqueue_ctl_table[id];
if (!the_ctl) {
return K_NULL;
}
if (the_ctl->id != id) {
return K_NULL;
}
return the_ctl;
}

1606
osal/posix/pthread.c Normal file

File diff suppressed because it is too large Load Diff

302
osal/posix/pthread_prv.c Normal file
View File

@@ -0,0 +1,302 @@
/*----------------------------------------------------------------------------
* 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_k.h"
#include "pthread.h"
#include "private/pthread.h"
__STATIC__ k_mutex_t pthread_mutex;
__STATIC__ pthread_ctl_t *thread_ctl_table[PTHREAD_THREADS_MAX] = { 0 };
__STATIC__ pthread_key_ctl_t pthread_key_ctl;
__KNL__ pthread_ctl_t *pthread_ctl_self(void)
{
TOS_CPU_CPSR_ALLOC();
int i = 0;
k_task_t *self_task;
pthread_ctl_t *the_info;
self_task = tos_task_curr_task_get();
TOS_CPU_INT_DISABLE();
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
the_info = thread_ctl_table[i];
if (the_info && the_info->the_ktask == self_task) {
TOS_CPU_INT_ENABLE();
return the_info;
}
}
TOS_CPU_INT_ENABLE();
return K_NULL;
}
__KNL__ pthread_ctl_t *pthread_ctl_by_id(pthread_t id)
{
pthread_ctl_t *the_ctl;
the_ctl = thread_ctl_table[id];
if (!the_ctl) {
return K_NULL;
}
if (the_ctl->id != id) {
return K_NULL;
}
if (the_ctl->threadstate == PTHREAD_STATE_EXITED) {
return K_NULL;
}
return the_ctl;
}
__KNL__ int pthread_id_add(pthread_t id, pthread_ctl_t *info)
{
TOS_CPU_CPSR_ALLOC();
if (id < 0 ||
id >= TOS_COUNT_OF(thread_ctl_table) ||
thread_ctl_table[id]) {
return -1;
}
TOS_CPU_INT_DISABLE();
thread_ctl_table[id] = info;
TOS_CPU_INT_ENABLE();
return 0;
}
__KNL__ pthread_t pthread_id_alloc(void)
{
TOS_CPU_CPSR_ALLOC();
int i = 0;
TOS_CPU_INT_DISABLE();
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
if (!thread_ctl_table[i]) {
TOS_CPU_INT_ENABLE();
return (pthread_t)i;
}
}
TOS_CPU_INT_ENABLE();
return -1;
}
__KNL__ int pthread_id_free(pthread_t id)
{
TOS_CPU_CPSR_ALLOC();
if (id < 0 ||
id >= TOS_COUNT_OF(thread_ctl_table) ||
!thread_ctl_table[id]) {
return -1;
}
TOS_CPU_INT_DISABLE();
thread_ctl_table[id] = K_NULL;
TOS_CPU_INT_ENABLE();
return 0;
}
__KNL__ void pthread_data_clear(pthread_key_t key)
{
int i = 0;
pthread_ctl_t *the_ctl;
for (i = 0; i < TOS_COUNT_OF(thread_ctl_table); ++i) {
the_ctl = thread_ctl_table[i];
if (the_ctl && the_ctl->thread_data) {
the_ctl->thread_data[key] = K_NULL;
}
}
}
__STATIC__ int pthread_key_ctl_init(void)
{
int i = 0;
if (tos_bitmap_create_full(&pthread_key_ctl.key_bitmap,
pthread_key_ctl.key_bitmap_tbl,
PTHREAD_KEYS_MAX) != K_ERR_NONE) {
return -1;
}
for (i = 0; i < PTHREAD_KEYS_MAX; ++i) {
pthread_key_ctl.destructors[i] = K_NULL;
}
return 0;
}
__KNL__ pthread_key_t pthread_key_alloc(void)
{
int lsb;
lsb = tos_bitmap_lsb(&pthread_key_ctl.key_bitmap);
if (lsb > PTHREAD_KEYS_MAX) {
return -1;
}
tos_bitmap_reset(&pthread_key_ctl.key_bitmap, lsb);
return (pthread_key_t)lsb;
}
__KNL__ int pthread_key_is_alloc(pthread_key_t key)
{
if (key > PTHREAD_KEYS_MAX || key < 0) {
return K_FALSE;
}
return tos_bitmap_is_reset(&pthread_key_ctl.key_bitmap, key);
}
__KNL__ int pthread_key_free(pthread_key_t key)
{
if (key > PTHREAD_KEYS_MAX || key < 0) {
return -1;
}
if (tos_bitmap_is_set(&pthread_key_ctl.key_bitmap, key)) {
/* what we created is a full bitmap, if the bit is set means it is not used */
return -1;
}
/* make it avaliable again */
tos_bitmap_set(&pthread_key_ctl.key_bitmap, key);
return 0;
}
__KNL__ int pthread_key_destructor_register(pthread_key_t key, key_destructor_t destructor)
{
if (key > PTHREAD_KEYS_MAX || key < 0) {
return -1;
}
if (tos_bitmap_is_set(&pthread_key_ctl.key_bitmap, key)) {
/* what we created is a full bitmap, if the bit is set means it is not used */
return -1;
}
pthread_key_ctl.destructors[key] = destructor;
return 0;
}
__STATIC__ int pthread_key_destructor_is_register(pthread_key_t key)
{
if (key > PTHREAD_KEYS_MAX || key < 0) {
return K_FALSE;
}
if (tos_bitmap_is_set(&pthread_key_ctl.key_bitmap, key)) {
/* what we created is a full bitmap, if the bit is set means it is not used */
return K_FALSE;
}
return pthread_key_ctl.destructors[key] != K_NULL;
}
__KNL__ key_destructor_t pthread_key_destructor_get(pthread_key_t key)
{
if (!pthread_key_destructor_is_register(key)) {
return K_NULL;
}
return pthread_key_ctl.destructors[key];
}
__KNL__ int pthread_ctl_reap(int pthreads_ready2reap)
{
int i = 0;
pthread_ctl_t *the_ctl;
int pthreads_reaped = 0;
if (pthreads_ready2reap == 0) {
return 0;
}
for (i = 0; pthreads_ready2reap && i < TOS_COUNT_OF(thread_ctl_table); ++i) {
the_ctl = thread_ctl_table[i];
if (!the_ctl || the_ctl->threadstate != PTHREAD_STATE_EXITED) {
continue;
}
pthread_id_free((pthread_t)i);
tos_sem_destroy(&the_ctl->joinner_sem);
if (the_ctl->stackaddr) {
/* the_ctl is just on this stack */
tos_mmheap_free(the_ctl->stackaddr);
}
--pthreads_ready2reap;
++pthreads_reaped;
}
return pthreads_reaped;
}
__KNL__ void pthread_lock(void)
{
tos_mutex_pend(&pthread_mutex);
}
__KNL__ void pthread_unlock(void)
{
tos_mutex_post(&pthread_mutex);
}
__STATIC__ int pthread_lock_init(void)
{
if (tos_mutex_create(&pthread_mutex) != K_ERR_NONE) {
return -1;
}
return 0;
}
__KNL__ int pthread_init(void)
{
if (pthread_lock_init() != 0) {
return -1;
}
if (pthread_key_ctl_init() != 0) {
return -1;
}
return 0;
}

105
osal/posix/sched.c Normal file
View File

@@ -0,0 +1,105 @@
/*----------------------------------------------------------------------------
* 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_k.h"
#include "errno.h"
#include "sched.h"
#include "private/pthread.h"
#include "private/time.h"
__API__ int sched_get_priority_max(int policy)
{
return K_TASK_PRIO_IDLE - 1;
}
__API__ int sched_get_priority_min(int policy)
{
return 0;
}
__API__ int sched_getparam(pid_t pid, struct sched_param *param)
{
pthread_ctl_t *the_ctl;
TOS_PTR_SANITY_CHECK_RC(param, EINVAL);
the_ctl = pthread_ctl_by_id(pid);
if (!the_ctl) {
return EINVAL;
}
*param = the_ctl->attr.schedparam;
return 0;
}
__NOTSUPP__ int sched_getscheduler(pid_t pid)
{
return EOPNOTSUPP;
}
__API__ int sched_rr_get_interval(pid_t pid, struct timespec *interval)
{
#if TOS_CFG_ROUND_ROBIN_EN > 0u
k_tick_t ktick;
pthread_ctl_t *the_ctl;
TOS_PTR_SANITY_CHECK_RC(interval, EINVAL);
the_ctl = pthread_ctl_by_id(pid);
if (!the_ctl) {
return EINVAL;
}
ktick = the_ctl->the_ktask->timeslice_reload;
ktick_to_timespec(ktick, interval);
return 0;
#else
return EOPNOTSUPP;
#endif
}
__API__ int sched_setparam(pid_t pid, const struct sched_param *param)
{
pthread_ctl_t *the_ctl;
TOS_PTR_SANITY_CHECK_RC(param, EINVAL);
the_ctl = pthread_ctl_by_id(pid);
if (!the_ctl) {
return EINVAL;
}
the_ctl->attr.schedparam = *param;
return 0;
}
__NOTSUPP__ int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param)
{
return EOPNOTSUPP;
}
__API__ int sched_yield(void)
{
tos_task_yield();
return 0;
}

137
osal/posix/semaphore.c Normal file
View File

@@ -0,0 +1,137 @@
/*----------------------------------------------------------------------------
* 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 "private/posix_config.h"
#include "errno.h"
#include "semaphore.h"
#include "private/time.h"
#if POSIX_CFG_SEM_EN > 0u
__NOTSUPP__ int sem_close(sem_t *sem)
{
return EOPNOTSUPP;
}
__API__ int sem_destroy(sem_t *sem)
{
k_err_t kerr;
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
kerr = tos_sem_destroy((k_sem_t *)sem);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__API__ int sem_getvalue(sem_t *sem, int *sval)
{
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
TOS_PTR_SANITY_CHECK_RC(sval, EINVAL);
*sval = ((k_sem_t *)sem)->count;
return 0;
}
__API__ int sem_init(sem_t *sem, int pshared, unsigned value)
{
k_err_t kerr;
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
kerr = tos_sem_create((k_sem_t *)sem, value);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__NOTSUPP__ sem_t *sem_open(const char *name, int oflag, ...)
{
return K_NULL;
}
__API__ int sem_post(sem_t *sem)
{
k_err_t kerr;
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
kerr = tos_sem_post((k_sem_t *)sem);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__API__ int sem_timedwait(sem_t *sem, const struct timespec *abstime)
{
k_err_t kerr;
k_tick_t ktick;
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
ktick = timespec_to_ktick(abstime);
kerr = tos_sem_pend((k_sem_t *)sem, ktick);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__API__ int sem_trywait(sem_t *sem)
{
k_err_t kerr;
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
kerr = tos_sem_pend((k_sem_t *)sem, TOS_TIME_NOWAIT);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__NOTSUPP__ int sem_unlink(const char *name)
{
return EOPNOTSUPP;
}
__API__ int sem_wait(sem_t *sem)
{
k_err_t kerr;
TOS_PTR_SANITY_CHECK_RC(sem, EINVAL);
kerr = tos_sem_pend((k_sem_t *)sem, TOS_TIME_FOREVER);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
#endif /* POSIX_CFG_SEM_EN */

180
osal/posix/time.c Normal file
View 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.
*---------------------------------------------------------------------------*/
#include "tos_k.h"
#include "private/posix_config.h"
#include "errno.h"
#include "time.h"
#include "private/time.h"
#include "private/timer.h"
__API__ clock_t clock(void)
{
return tos_systick_get();
}
__API__ int clock_gettime(clockid_t clock_id, struct timespec *tp)
{
k_tick_t ktick;
TOS_PTR_SANITY_CHECK_RC(tp, EINVAL);
if (clock_id != CLOCK_REALTIME) {
return EINVAL;
}
/* use systick rather than rtc now */
ktick = tos_systick_get();
ktick_to_timespec(ktick, tp);
return 0;
}
#if POSIX_CFG_TIMER_EN > 0u
__STATIC__ void timer_callback(void *arg)
{
ptimer_ctl_t *the_ctl;
the_ctl = (ptimer_ctl_t *)arg;
the_ctl->sigev_notify_function(the_ctl->sigev_value);
}
__API__ int timer_create(clockid_t clockid, struct sigevent *evp, timer_t *timerid)
{
k_err_t kerr;
timer_t id;
ptimer_ctl_t *the_ctl;
TOS_PTR_SANITY_CHECK_RC(timerid, EINVAL);
TOS_PTR_SANITY_CHECK_RC(evp, EINVAL);
TOS_PTR_SANITY_CHECK_RC(evp->sigev_notify_function, EINVAL);
id = timer_id_alloc();
if (id == -1) {
return ENOMEM;
}
clockid = clockid; /* make compiler happy */
the_ctl = (ptimer_ctl_t *)tos_mmheap_alloc(sizeof(ptimer_ctl_t));
if (!the_ctl) {
return ENOMEM;
}
the_ctl->sigev_notify_function = evp->sigev_notify_function;
the_ctl->sigev_value = evp->sigev_value;
kerr = tos_timer_create((k_timer_t *)&the_ctl->ktimer, 1u, 1u,
timer_callback, the_ctl,
TOS_OPT_TIMER_PERIODIC);
if (kerr != K_ERR_NONE) {
tos_mmheap_free(the_ctl);
return EBUSY;
}
the_ctl->id = id;
timer_id_add(id, the_ctl);
return 0;
}
__API__ int timer_delete(timer_t timerid)
{
k_err_t kerr;
ptimer_ctl_t *the_ctl;
TOS_PTR_SANITY_CHECK_RC(timerid, EINVAL);
the_ctl = timer_by_id(timerid);
if (!the_ctl) {
return EINVAL;
}
kerr = tos_timer_destroy(&the_ctl->ktimer);
timer_id_free(timerid);
tos_mmheap_free(the_ctl);
if (kerr == K_ERR_NONE) {
return 0;
}
return EINVAL;
}
__NOTSUPP__ int timer_getoverrun(timer_t timerid)
{
return EOPNOTSUPP;
}
__API__ int timer_gettime(timer_t timerid, struct itimerspec *value)
{
k_tick_t expires, period;
ptimer_ctl_t *the_ctl;
the_ctl = timer_by_id(timerid);
if (!the_ctl) {
return EINVAL;
}
if (!value) {
return 0;
}
expires = the_ctl->ktimer.expires;
period = the_ctl->ktimer.period;
ktick_to_timespec(expires, &value->it_value);
ktick_to_timespec(period, &value->it_interval);
return 0;
}
__API__ int timer_settime(timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue)
{
k_tick_t delay, period;
ptimer_ctl_t *the_ctl;
TOS_PTR_SANITY_CHECK_RC(value, EINVAL);
the_ctl = timer_by_id(timerid);
if (!the_ctl) {
return EINVAL;
}
if (ovalue) {
timer_gettime(timerid, ovalue);
}
delay = timespec_to_ktick(&value->it_value);
period = timespec_to_ktick(&value->it_interval);
tos_timer_stop(&the_ctl->ktimer);
tos_timer_delay_change(&the_ctl->ktimer, delay);
tos_timer_period_change(&the_ctl->ktimer, period);
tos_timer_start(&the_ctl->ktimer);
return 0;
}
#endif /* POSIX_CFG_TIMER_EN */

54
osal/posix/time_prv.c Normal file
View File

@@ -0,0 +1,54 @@
/*----------------------------------------------------------------------------
* 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 "time.h"
#include "private/time.h"
__KNL__ k_tick_t timespec_to_ktick(const struct timespec *tp)
{
int nsecond, second;
struct timespec curr_tp;
TOS_PTR_SANITY_CHECK_RC(tp, (k_tick_t)-1);
clock_gettime(CLOCK_REALTIME, &curr_tp);
if (tp->tv_nsec - curr_tp.tv_nsec < 0) {
nsecond = NANOSECOND_PER_SECOND - (curr_tp.tv_nsec - tp->tv_nsec);
second = tp->tv_sec - curr_tp.tv_sec - 1;
} else {
nsecond = tp->tv_nsec - curr_tp.tv_nsec;
second = tp->tv_sec - curr_tp.tv_sec;
}
if (second < 0) {
return (k_tick_t)0u;
}
return (k_tick_t)(second * TOS_CFG_CPU_TICK_PER_SECOND + nsecond * TOS_CFG_CPU_TICK_PER_SECOND / NANOSECOND_PER_SECOND);
}
__KNL__ void ktick_to_timespec(k_tick_t ktick, struct timespec *tp)
{
if (!tp) {
return;
}
tp->tv_sec = ktick / TOS_CFG_CPU_TICK_PER_SECOND;
tp->tv_nsec = (ktick % TOS_CFG_CPU_TICK_PER_SECOND) * ((long)1000000000 / TOS_CFG_CPU_TICK_PER_SECOND);
}

97
osal/posix/timer_prv.c Normal file
View File

@@ -0,0 +1,97 @@
/*----------------------------------------------------------------------------
* 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_k.h"
#include "time.h"
#include "private/timer.h"
__STATIC__ ptimer_ctl_t *ptimer_ctl_table[TIMERS_MAX] = { 0 };
__KNL__ int timer_id_add(timer_t id, ptimer_ctl_t *ptimer_ctl)
{
TOS_CPU_CPSR_ALLOC();
if (id < 0 ||
id >= TOS_COUNT_OF(ptimer_ctl_table) ||
ptimer_ctl_table[id]) {
return -1;
}
TOS_CPU_INT_DISABLE();
ptimer_ctl_table[id] = ptimer_ctl;
TOS_CPU_INT_ENABLE();
return 0;
}
__KNL__ timer_t timer_id_alloc(void)
{
TOS_CPU_CPSR_ALLOC();
int i = 0;
TOS_CPU_INT_DISABLE();
for (i = 0; i < TOS_COUNT_OF(ptimer_ctl_table); ++i) {
if (!ptimer_ctl_table[i]) {
TOS_CPU_INT_ENABLE();
return (timer_t)i;
}
}
TOS_CPU_INT_ENABLE();
return -1;
}
__KNL__ int timer_id_free(timer_t id)
{
TOS_CPU_CPSR_ALLOC();
if (id < 0 ||
id >= TOS_COUNT_OF(ptimer_ctl_table) ||
!ptimer_ctl_table[id]) {
return -1;
}
TOS_CPU_INT_DISABLE();
ptimer_ctl_table[id] = K_NULL;
TOS_CPU_INT_ENABLE();
return 0;
}
__KNL__ ptimer_ctl_t *timer_by_id(timer_t id)
{
ptimer_ctl_t *the_ctl;
the_ctl = ptimer_ctl_table[id];
if (!the_ctl) {
return K_NULL;
}
if (the_ctl->id != id) {
return K_NULL;
}
return the_ctl;
}

26
osal/posix/tos_posix.c Normal file
View File

@@ -0,0 +1,26 @@
/*----------------------------------------------------------------------------
* 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_k.h"
#include "private/pthread.h"
__API__ int tos_posix_init(void)
{
return pthread_init();
}