CMSIS RTOS -- embOS segger
#ifndef __CMSIS_OS_H__
#define __CMSIS_OS_H__ #include <stdint.h>
#include <stddef.h> #include "RTOS.h" // API version (main [31:16] .sub [15:0])
#define osCMSIS 0x10002
// RTOS identification and version (main [31:16] .sub [15:0])
#define osCMSIS_RTX ((4<<16)|00)
// RTOS identification string
#define osKernelSystemId "EMBOS V4.00"
//
// main thread 1=main can be thread, 0=not available
#define osFeature_MainThread 1
//
// Memory Pools: 1=available, 0=not available
#define osFeature_Pool 1
//
// Mail Queues: 1=available, 0=not available
#define osFeature_MailQ 1
//
// Message Queues: 1=available, 0=not available
#define osFeature_MessageQ 1
//
// maximum number of Signal Flags available per thread
// bit31 = 0x80000000 : incorrect parameters
#define osFeature_Signals 31
//
// maximum count for osSemaphoreCreate function
#define osFeature_Semaphore 0xFFFFFFFF
//
// osWait function: 1=available, 0=not available
#define osFeature_Wait 0
//
// osKernelSysTick functions: 1=available, 0=not available
#define osFeature_SysTick 1
//
//
//
#ifdef __cplusplus
extern "C"
{
#endif // ==== Enumeration, structures, defines =======================================
//
// Priority used for thread control.
// MUST REMAIN UNCHANGED: osPriority shall be consistent in every CMSIS-RTOS.
//
typedef enum
{
osPriorityIdle = -, // priority: idle (lowest)
osPriorityLow = -, // priority: low
osPriorityBelowNormal = -, // priority: below normal
osPriorityNormal = , // priority: normal (default)
osPriorityAboveNormal = +, // priority: above normal
osPriorityHigh = +, // priority: high
osPriorityRealtime = +, // priority: realtime (highest)
osPriorityError = 0x84 // system cannot determine priority
} osPriority; // or thread has illegal priority // Timeout value.
// MUST REMAIN UNCHANGED: osWaitForever shall be consistent in every CMSIS-RTOS.
//
#define osWaitForever 0xFFFFFFFF // wait forever timeout value
// Status code values returned by CMSIS-RTOS functions.
// MUST REMAIN UNCHANGED: osStatus shall be consistent in every CMSIS-RTOS.
//
typedef enum
{
// function completed; no error or event occurred.
osOK = ,
//
// function completed; signal event occurred.
osEventSignal = 0x08,
// function completed; message event occurred.
osEventMessage = 0x10,
// function completed; mail event occurred.
osEventMail = 0x20,
//
// function completed; timeout occurred.
osEventTimeout = 0x40,
//
// parameter error: a mandatory parameter was missing or specified an incorrect object.
osErrorParameter = 0x80,
//
// resource not available: a specified resource was not available.
osErrorResource = 0x81,
// resource not available within given time: a specified resource was not available within the timeout period.
osErrorTimeoutResource = 0xC1,
// not allowed in ISR context: the function cannot be called from interrupt service routines.
osErrorISR = 0x82,
// function called multiple times from ISR with same object.
osErrorISRRecursive = 0x83,
// system cannot determine priority or thread has illegal priority.
osErrorPriority = 0x84,
// system is out of memory: it was impossible to allocate or reserve memory for the operation.
osErrorNoMemory = 0x85,
// value of a parameter is out of range.
osErrorValue = 0x86,
// unspecified RTOS error: run-time error but no other error message fits.
osErrorOS = 0xFF,
//
os_status_reserved = 0x7FFFFFFF
// prevent from enum down-size compiler optimization.
// 32 bits for osStatus
} osStatus; // Timer type value for the timer definition.
// MUST REMAIN UNCHANGED: os_timer_type shall be consistent in every CMSIS-RTOS.
//
typedef enum
{
osTimerOnce = , // one-shot timer
osTimerPeriodic = // repeating timer --- EMBOS can not support !
} os_timer_type; typedef struct _CMSIS_OS_GLOBAL
{
uint32_t dummy;
} CMSIS_OS_GLOBAL; extern CMSIS_OS_GLOBAL os_global; // Entry point of a thread.
// MUST REMAIN UNCHANGED: os_pthread shall be consistent in every CMSIS-RTOS.
//
typedef void (*os_pthread)( void * argument ); // Entry point of a timer call back function.
// MUST REMAIN UNCHANGED: os_ptimer shall be consistent in every CMSIS-RTOS.
//
typedef void (*os_ptimer)( void * argument ); // >>> the following data type definitions may shall adapted towards a specific RTOS // Thread ID identifies the thread (pointer to a thread control block).
// CAN BE CHANGED: os_thread_cb is implementation specific in every CMSIS-RTOS.
//
typedef OS_TASK osThreadType;
typedef osThreadType * osThreadId; // Timer ID identifies the timer (pointer to a timer control block).
// CAN BE CHANGED: os_timer_cb is implementation specific in every CMSIS-RTOS.
//
typedef OS_TIMER_EX osTimerType;
typedef osTimerType * osTimerId; // Mutex ID identifies the mutex (pointer to a mutex control block).
// CAN BE CHANGED: os_mutex_cb is implementation specific in every CMSIS-RTOS.
//
typedef OS_RSEMA osMutexType;
typedef osMutexType * osMutexId; // Semaphore ID identifies the semaphore (pointer to a semaphore control block).
// CAN BE CHANGED: os_semaphore_cb is implementation specific in every CMSIS-RTOS.
//
typedef OS_CSEMA osSemaphoreType;
typedef osSemaphoreType * osSemaphoreId; // Pool ID identifies the memory pool (pointer to a memory pool control block).
// CAN BE CHANGED: os_pool_cb is implementation specific in every CMSIS-RTOS.
//
typedef OS_MEMF osPoolType;
typedef osPoolType * osPoolId; // Message ID identifies the message queue (pointer to a message queue control block).
// CAN BE CHANGED: os_messageQ_cb is implementation specific in every CMSIS-RTOS.
//
// OS_MAILBOX : Messages of fixed size
// CMSIS_OS : Messages of fixed size : 4 Bytes for Value or Pointer
//
typedef OS_MAILBOX osMessageQType;
typedef osMessageQType * osMessageQId; // Mail ID identifies the mail queue (pointer to a mail queue control block).
// CAN BE CHANGED: os_mailQ_cb is implementation specific in every CMSIS-RTOS.
//
// OS_MAILBOX : Messages of fixed size
// CMSIS_OS : Messages of fixed size : 1..32767 Bytes for Buffer
//
typedef struct _osMailQ_cb
{
osMessageQId messageId;
osPoolId poolId;
} osMailQType; typedef osMailQType * osMailQId; // Thread Definition structure contains startup information of a thread.
// CAN BE CHANGED: os_thread_def is implementation specific in every CMSIS-RTOS.
//
typedef struct os_thread_def
{
osThreadId threadId;
uint8_t * name;
os_pthread pthread; // start address of thread function
osPriority tpriority; // initial thread priority
uint32_t stacksize; // stack size requirements in bytes;
uint32_t * stack; //
} osThreadDef_t; // Timer Definition structure contains timer parameters.
// CAN BE CHANGED: os_timer_def is implementation specific in every CMSIS-RTOS.
//
typedef const struct os_timer_def
{
osTimerId timerId;
os_ptimer ptimer;
} osTimerDef_t; // Mutex Definition structure contains setup information for a mutex.
// CAN BE CHANGED: os_mutex_def is implementation specific in every CMSIS-RTOS.
//
typedef struct os_mutex_def
{
osMutexId mutexId;
} osMutexDef_t; // Semaphore Definition structure contains setup information for a semaphore.
// CAN BE CHANGED: os_semaphore_def is implementation specific in every CMSIS-RTOS.
//
typedef struct os_semaphore_def
{
osSemaphoreId semaphoreId;
} osSemaphoreDef_t; // Definition structure for memory block allocation.
// CAN BE CHANGED: os_pool_def is implementation specific in every CMSIS-RTOS.
//
typedef struct os_pool_def
{
osPoolId poolId;
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
} osPoolDef_t; // Definition structure for message queue.
// CAN BE CHANGED: os_messageQ_def is implementation specific in every CMSIS-RTOS.
//
typedef struct os_messageQ_def
{
osMessageQId messageQId;
uint32_t queue_sz; // number of elements in the queue
void * pool; // memory array for messages
} osMessageQDef_t; // Definition structure for mail queue.
// CAN BE CHANGED: os_mailQ_def is implementation specific in every CMSIS-RTOS.
//
typedef struct os_mailQ_def
{
osMailQId mailId;
osMessageQDef_t * messageQDef;
osPoolDef_t * poolDef;
uint32_t queue_sz; // number of elements in the queue
uint32_t item_sz; // size of an item
} osMailQDef_t; // Event structure contains detailed information about an event.
// MUST REMAIN UNCHANGED: os_event shall be consistent in every CMSIS-RTOS.
// However the struct may be extended at the end.
//
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
{
osMailQId mail_id; // mail id obtained by osMailCreate
osMessageQId message_id; // message id obtained by osMessageCreate
} def; // event definition } osEvent; // ======= Kernel Control Functions ============================================ // The RTOS kernel system timer frequency in Hz.
// Reflects the system timer setting and is typically defined in a configuration file.
#define osKernelSysTickFrequency ( OS_FSYS )
// The RTOS kernel frequency in Hz.
// Reflects the system timer setting and is typically defined in a configuration file.
#define osKernelTickFrequency ( OS_TICK_FREQ )
//
#define osKernelTickPeriod ( 1 / osKernelTickFrequency )
#define osKernelTicksPerSecond ( osKernelTickFrequency ) #if ( osKernelTickFrequency == 1000 )
#define osKernelTicksPerMilliSec ( 1 )
#else
#define osKernelTicksPerMilliSec ( osKernelTickFrequency / 1000 )
#endif //
// Convert timeout in millisec to system ticks
#if ( osKernelTickFrequency == 1000 )
#define osKernelTicksByMilliSec( millisec ) ( millisec )
#else
#define osKernelTicksByMilliSec( millisec ) ( ( millisec ) * osKernelTicksPerMilliSec )
#endif // Convert timeout in second to system ticks
#define osKernelTicksBySecond( second ) ( ( second ) * osKernelTicksPerSecond ) // Convert kernel ticks to millisec
#if ( osKernelTickFrequency == 1000 )
#define osKernelTicks2MilliSec( ticks ) ( ticks )
#else
#define osKernelTicks2MilliSec( ticks ) ( ( ticks ) / osKernelTicksPerMilliSec )
#endif // Convert kernel ticks to second
#define osKernelTicks2Second( ticks ) ( ( ticks ) / osKernelTicksPerSecond )
//
//
#define osKernelSysTicksPerSecond ( osKernelSysTickFrequency )
#define osKernelSysTicksPerMilliSec ( osKernelSysTickFrequency / 1000 )
//
// Convert timeout in millisec to system ticks
#define osKernelSysTicksByMilliSec( millisec ) ( ( millisec ) * osKernelSysTicksPerMilliSec )
// Convert timeout in second to system ticks
#define osKernelSysTicksBySecond( second ) ( ( second ) * osKernelSysTicksPerSecond )
// Convert system ticks to millisec
#define osKernelSysTicks2MilliSec( ticks ) ( ( ticks ) / osKernelSysTicksPerMilliSec )
// Convert system ticks to second
#define osKernelSysTicks2Second( ticks ) ( ( ticks ) / osKernelSysTicksPerSecond )
// #define osKernelSysTickMicroSec_i \
( osKernelSysTickFrequency / )
//
#define osKernelSysTickMicroSec_f \
( ( ( (uint64_t)( osKernelSysTickFrequency - * ( osKernelSysTickFrequency / ) ) ) << ) / )
//
// Convert a microseconds value to a RTOS kernel system timer value.
#define osKernelSysTickMicroSec(microsec) \
( ( microsec * osKernelSysTickMicroSec_i ) + ( ( microsec * osKernelSysTickMicroSec_f ) >> ) )
//
#define osKernelSysTickMilliSec(millisec) \
osKernelSysTicksByMilliSec(millisec) // return RTOS kernel time as 32-bit value in milli second
//
//#include "rt_Time.h"
//#define osKernelTickTime ( os_time / osKernelTicksPerMilliSec )
//
#define osKernelTickTime ( OS_Time / osKernelTicksPerMilliSec )
#define osKernelTickCount() OS_GetTime32()
#define osKernelSysTick() OS_GetTime_Cycles() osStatus osKernelInitialize( void );
osStatus osKernelStart( void );
int32_t osKernelRunning( void ); // ======= 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.
// CAN BE CHANGED: The parameters to osThreadDef shall be consistent but the
// macro body is implementation specific in every CMSIS-RTOS.
//
#if defined (osObjectsExternal)
#define osThreadDef(name, thread, priority, instances, stacksz) \
extern osThreadDef_t os_thread_def_##name
#else
#define osThreadDef(name, thread, priority, instances, stacksz) \
OS_TASK os_thread_id_##name; \
uint32_t os_thread_stack_##name[ ( (stacksz ? stacksz : OS_STKSIZE ) + ) / ]; \
osThreadDef_t os_thread_def_##name = \
{ &os_thread_id_##name, #name, (os_pthread)(thread), (priority),\
(( ( (stacksz ? stacksz : OS_STKSIZE ) + ) / ) << ), \
os_thread_stack_##name }
#endif #define osThread(name) \
&os_thread_def_##name osThreadId osThreadCreate( osThreadDef_t * thread_def, void * argument );
osThreadId osThreadGetId( void );
osStatus osThreadTerminate( osThreadId thread_id );
osStatus osThreadYield( void );
osStatus osThreadSetPriority( osThreadId thread_id, osPriority priority );
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))
osEvent osWait( uint32_t millisec );
#endif // ======= Timer Management Functions ==========================================
//
// Define a Timer object.
// param name name of the timer object.
// param function name of the timer call back function.
// CAN BE CHANGED: The parameter to osTimerDef shall be consistent but the
// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal)
#define osTimerDef(name, function) \
extern osTimerDef_t os_timer_def_##name
#else
#define osTimerDef(name, function) \
OS_TIMER_EX os_timer_id_##name; \
osTimerDef_t os_timer_def_##name = \
{&os_timer_id_##name, (function) }
#endif #define osTimer(name) \
&os_timer_def_##name osTimerId osTimerCreate( osTimerDef_t * timer_def, os_timer_type type,
void * argument );
osStatus osTimerStart( osTimerId timer_id, uint32_t millisec );
osStatus osTimerStop( osTimerId timer_id );
osStatus osTimerDelete( osTimerId timer_id ); // ======= Signal Management ===================================================
//
int32_t osSignalSet( osThreadId thread_id, int32_t signals );
int32_t osSignalClear( osThreadId thread_id, int32_t signals );
osEvent osSignalWait( int32_t signals, uint32_t millisec ); // ======= Mutex Management ====================================================
#if defined (osObjectsExternal)
#define osMutexDef(name) \
extern osMutexDef_t os_mutex_def_##name
#else
#define osMutexDef(name) \
OS_RSEMA os_mutex_id_##name; \
osMutexDef_t os_mutex_def_##name = { &os_mutex_id_##name }
#endif #define osMutex(name) \
&os_mutex_def_##name osMutexId osMutexCreate( osMutexDef_t * mutex_def );
osStatus osMutexWait( osMutexId mutex_id, uint32_t millisec );
osStatus osMutexRelease( osMutexId mutex_id );
osStatus osMutexDelete( osMutexId mutex_id ); // ======= Semaphore Management Functions ====================================== #if (defined (osFeature_Semaphore) && (osFeature_Semaphore != 0))
//
// Define a Semaphore object.
// param name name of the semaphore object.
// CAN BE CHANGED: The parameter to osSemaphoreDef shall be consistent but the
// macro body is implementation specific in every CMSIS-RTOS.
//
#if defined (osObjectsExternal)
#define osSemaphoreDef(name) \
extern osSemaphoreDef_t os_semaphore_def_##name
#else
#define osSemaphoreDef(name) \
OS_CSEMA os_semaphore_id_##name; \
osSemaphoreDef_t os_semaphore_def_##name = { &os_semaphore_id_##name }
#endif #define osSemaphore(name) \
&os_semaphore_def_##name osSemaphoreId osSemaphoreCreate( osSemaphoreDef_t * semaphore_def,
int32_t count );
int32_t osSemaphoreWait( osSemaphoreId semaphore_id, uint32_t millisec );
osStatus osSemaphoreRelease( osSemaphoreId semaphore_id );
osStatus osSemaphoreDelete( osSemaphoreId semaphore_id ); #endif // ============= Memory Pool Management Functions ==============================
//
#if (defined (osFeature_Pool) && (osFeature_Pool != 0))
//
// \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).
// CAN BE CHANGED: The parameter to osPoolDef shall be consistent but the
// macro body is implementation specific in every CMSIS-RTOS.
#if defined (osObjectsExternal)
#define osPoolDef(name, no, type) \
extern osPoolDef_t os_pool_def_##name
#else
#define osPoolDef(name, no, type) \
OS_MEMF os_pool_id_##name; \
uint32_t \
os_pool_m_##name[ ( ( OS_MEMF_SIZEOF_BLOCKCONTROL + sizeof(type) + ) / ) * (no) ]; \
osPoolDef_t \
os_pool_def_##name = \
{ &os_pool_id_##name, (no), \
( ( ( OS_MEMF_SIZEOF_BLOCKCONTROL + sizeof(type) + ) / ) << ), \
(os_pool_m_##name) }
#endif #define osPool(name) \
&os_pool_def_##name osPoolId osPoolCreate( osPoolDef_t * pool_def );
void * osPoolAlloc( osPoolId pool_id );
void * osPoolCAlloc( osPoolId pool_id );
osStatus osPoolFree( osPoolId pool_id, void * block ); #endif // ======= Message Queue Management Functions ================================== #if (defined (osFeature_MessageQ) && (osFeature_MessageQ != 0))
//
// \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).
// CAN BE CHANGED: The parameter to osMessageQDef shall be consistent but the
// macro body is implementation specific in every CMSIS-RTOS.
//
#if defined (osObjectsExternal)
#define osMessageQDef(name, queue_sz, type) \
extern osMessageQDef_t os_messageQ_def_##name
#else
#define osMessageQDef(name, queue_sz, type) \
OS_MAILBOX os_messageQ_id_##name;\
uint32_t os_messageQ_q_##name[ (queue_sz) ] = { }; \
osMessageQDef_t os_messageQ_def_##name = \
{ &os_messageQ_id_##name, (queue_sz << ) , (os_messageQ_q_##name) }
#endif #define osMessageQ(name) \
&os_messageQ_def_##name osMessageQId osMessageCreate( osMessageQDef_t * queue_def,
osThreadId thread_id );
osStatus osMessagePut( osMessageQId queue_id, uint32_t info, uint32_t millisec );
osEvent osMessageGet( osMessageQId queue_id, uint32_t millisec );
osStatus osMessageDelete( osMessageQId queue_id ); #endif
// ======= Mail Queue Management Functions =====================================
#if (defined (osFeature_MailQ) && (osFeature_MailQ != 0))
//
// \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
// CAN BE CHANGED: The parameter to osMailQDef shall be consistent but the
// macro body is implementation specific in every CMSIS-RTOS.
//
#if defined (osObjectsExternal)
#define osMailQDef(name, queue_sz, type) \
extern osMailQDef_t os_mailQ_def_##name
#else
#define osMailQDef(name, queue_sz, type) \
osMailQ_cb os_MailQ_id_##name;\
osPoolDef(mail_##name, queue_sz, type); \
osMessageQDef(mail_##name, queue_sz); \
osMailQDef_t os_mailQ_def_##name = \
{ &os_MailQ_id_##name, osMessageQ(mail_##name), osPool(mail_##name), \
queue_sz, ( ( (sizeof(type) + ) >> ) << ) }
#endif #define osMailQ(name) \
&os_mailQ_def_##name
osMailQId osMailCreate( osMailQDef_t * queue_def, osThreadId thread_id );
void * osMailAlloc( osMailQId queue_id, uint32_t millisec );
void * osMailCAlloc( osMailQId queue_id, uint32_t millisec );
osStatus osMailPut( osMailQId queue_id, void * mail );
osEvent osMailGet( osMailQId queue_id, uint32_t millisec );
osStatus osMailFree( osMailQId queue_id, void * mail ); #endif // ============= Memory Management Functions =================================== osStatus osMemoryLock( uint32_t timeout ); void osMemoryUnlock( void ); /*
* ANSI C offers some basic dynamic memory management functions.
* These are malloc, free, and realloc. Unfortunately, these routines are
* not thread-safe, unless a special thread-safe implementation exists
* in the compiler specific runtime libraries; they can only be used from
* one task or by multiple tasks if they are called sequentially.
*
* Therefore, embOS offer task-safe variants of these routines.
* These variants have the same names as their ANSI counterparts,
* but are prefixed OS_; they are called OS_malloc(), OS_free(), OS_realloc().
*
* The thread-safe variants that embOS offers use the standard ANSI routines,
* but they guarantee that the calls are serialized using a resource semaphore.
*
* If heap memory management is not supported by the standard C-libraries
* for a specific CPU, embOS heap memory management is not implemented.
*
* Heap type memory management is part of the embOS libraries.
* It does not use any resources if it is not referenced by the application
* (that is, if the application does not use any memory management API function).
*
* Note that another aspect of these routines may still be a problem:
* the memory used for the functions (known as heap) may fragment.
*
* This can lead to a situation where the total amount of memory is sufficient,
* but there is not enough memory available in a single block
* to satisfy an allocation request.
*
*/ /* Allocates a block of size bytes of memory, returning a pointer
* to the beginning of the block. The content of the newly allocated block of
* memory is not initialized, remaining with indeterminate values.
*
* On success, a pointer to the memory block allocated by the function.
* The type of this pointer is always void*, which can be cast to the desired
* type of data pointer in order to be dereferenceable.
*
* If the function failed to allocate the requested block of memory,
* a null pointer is returned.
*
*/
void * osMalloc( size_t size, uint32_t timeout ); /* Allocates a block of memory for an array of num elements,
* each of them size bytes long, and initializes all its bits to zero.
*
* The effective result is the allocation of a zero-initialized memory block
* of (num*size) bytes.
*
* On success, a pointer to the memory block allocated by the function.
* The type of this pointer is always void*, which can be cast to the desired
* type of data pointer in order to be dereferenceable.
*
* If the function failed to allocate the requested block of memory,
* a null pointer is returned.
*
*/
void * osCalloc( size_t nelem, size_t elsize, uint32_t timeout ); /* Changes the size of the memory block pointed to by ptr.
* The function may move the memory block to a new location (whose address is
* returned by the function).
*
* The content of the memory block is preserved up to the lesser of the new
* and old sizes, even if the block is moved to a new location.
*
* If the new size is larger, the value of the newly allocated portion
* is indeterminate.
*
* In case that ptr is a null pointer, the function behaves like malloc,
* assigning a new block of size bytes and returning a pointer to its beginning.
*
* If the function fails to allocate the requested block of memory,
* a null pointer is returned, and the memory block pointed to by argument ptr
* is not deallocated (it is still valid, and with its contents unchanged).
*
* A pointer to the reallocated memory block, which may be either the same
* as ptr or a new location. The type of this pointer is void*, which can be
* cast to the desired type of data pointer in order to be dereferenceable.
*/
void * osRealloc( void * ptr, size_t size, uint32_t timeout ); /* A block of memory previously allocated by a call to malloc, calloc or realloc
* is deallocated, making it available again for further allocations.
*
* If ptr does not point to a block of memory allocated with the above functions
* it causes undefined behavior.
* If ptr is a null pointer, the function does nothing.
*
* Notice that this function does not change the value of ptr itself,
* hence it still points to the same (now invalid) location.
*
*/
void osFree( void * ptr ); /*
* Informs RTOS that interrupt code is executing.
*
* If osEnterInterrupt() is used, it should be the first function to be called
* in the interrupt handler. It must be used with osLeaveInterrupt() as the last
* function called. The use of this function has the following effects, it:
*
* disables task switches
* keeps interrupts in internal routines disabled.
*/
void osEnterInterrupt( void ); /*
* Informs RTOS that the end of the interrupt routine has been reached;
* executes task switching within ISR.
*
* If osLeaveInterrupt()is used, it should be the last function to be called
* in the interrupt handler. If the interrupt has caused a task switch, it will
* be executed (unless the program which was interrupted was in a critical region).
*
*/
void osLeaveInterrupt( void ); uint32_t osDisableInterrupt( void ); void osRestoreInterrupt( uint32_t val ); #ifdef __cplusplus
}
#endif #endif // __CMSIS_OS_H__
#include "cmsis_os.h"
#include <stdlib.h> #define CMSIS2EMBOS(x) ((x)+3)
#define EMBOS2CMSIS(x) ( (osPriority)( (x) -3) ) CMSIS_OS_GLOBAL os_global; //
// System Timer available
//
// Get the RTOS kernel system timer counter.
// MUST REMAIN UNCHANGED: osKernelSysTick shall be consistent in every CMSIS-RTOS.
// return : RTOS kernel system timer as 32-bit value
uint32_t osKernelSysTick0( void )
{
// returns the system time in timer clock cycles
return OS_GetTime_Cycles( );
} // ============= Kernel Control Functions ======================================
//
// Initialize the RTOS Kernel for creating objects.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osKernelInitialize shall be consistent in every CMSIS-RTOS.
//
osStatus osKernelInitialize( void )
{
OS_IncDI();
OS_InitKern( );
OS_InitHW( );
return osOK;
} // Start the RTOS Kernel.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osKernelStart shall be consistent in every CMSIS-RTOS.
//
osStatus osKernelStart( void )
{
/* This function starts the embOS scheduler and schould be the last function
* called from main().
*
* It will activate and start the task with the highest priority.
* automatically enables interrupts, and never return
*/
OS_Running = 1u;
OS_StartASM( );
return osOK;
} osStatus osKernelStartThread( osThreadDef_t * thread_def, void * argument )
{
osThreadCreate( thread_def, argument );
return osKernelStart( );
} // Check if the RTOS kernel is already started.
// MUST REMAIN UNCHANGED: osKernelRunning shall be consistent in every CMSIS-RTOS.
// return : 0 RTOS is not started, 1 RTOS is started.
//
int32_t osKernelRunning( void )
{
return OS_IsRunning(); // OS_Running;
} // ============= Thread Management =============================================
//
// Create a thread and add it to Active Threads and set it to state READY.
// param[in] thread_def thread definition referenced with 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.
// MUST REMAIN UNCHANGED: osThreadCreate shall be consistent in every CMSIS-RTOS.
//
osThreadId osThreadCreate( osThreadDef_t * thread_def, void * argument )
{
OS_CreateTaskEx( thread_def->threadId, (char *) thread_def->name,
CMSIS2EMBOS( thread_def->tpriority ),
(void (*)( void * )) ( thread_def->pthread ), thread_def->stack,
thread_def->stacksize, , argument );
return thread_def->threadId;
} // Return the thread ID of the current running thread.
// return : thread ID for reference by other functions or NULL in case of error.
// MUST REMAIN UNCHANGED: osThreadGetId shall be consistent in every CMSIS-RTOS.
//
osThreadId osThreadGetId( void )
{
return OS_GetTaskID();
} // Terminate execution of a thread and remove it from Active Threads.
// param[in] thread_id thread ID obtained by osThreadCreate or osThreadGetId.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osThreadTerminate shall be consistent in every CMSIS-RTOS.
//
osStatus osThreadTerminate( osThreadId thread_id )
{
// If pTaskis the NULLpointer, the current task terminates.
// The specified task will terminate immediately.
// The memory used for stack and task control block can be reassigned.
OS_TerminateTask( thread_id );
return osOK;
} // Pass control to next thread that is in state READY.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osThreadYield shall be consistent in every CMSIS-RTOS.
//
osStatus osThreadYield( void )
{
// Calls the scheduler to force a task switch.
OS_Yield( );
return osOK;
} // Change priority of an active thread.
// param[in] thread_id thread ID obtained by osThreadCreate or osThreadGetId.
// param[in] priority new priority value for the thread function.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osThreadSetPriority shall be consistent in every CMSIS-RTOS.
//
osStatus osThreadSetPriority( osThreadId thread_id, osPriority priority )
{
OS_SetPriority( thread_id, CMSIS2EMBOS( priority ) );
return osOK;
} // Get current priority of an active thread.
// param[in] thread_id thread ID obtained by osThreadCreate or osThreadGetId.
// return : current priority value of the thread function.
// MUST REMAIN UNCHANGED: osThreadGetPriority shall be consistent in every CMSIS-RTOS.
//
osPriority osThreadGetPriority( osThreadId thread_id )
{
return EMBOS2CMSIS( OS_GetPriority( 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 )
{
OS_Delay( osKernelTicksByMilliSec( millisec ) );
return osOK;
} // 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.
// MUST REMAIN UNCHANGED: osWait shall be consistent in every CMSIS-RTOS.
//
osEvent osWait( uint32_t millisec )
{
osEvent event;
event.status = osOK;
return event;
} // ============= Timer Management Functions ====================================
//
// Create a timer.
// param[in] timer_def timer object referenced with 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.
// MUST REMAIN UNCHANGED: osTimerCreate shall be consistent in every CMSIS-RTOS.
//
osTimerId osTimerCreate( osTimerDef_t * timer_def, os_timer_type type,
void * argument )
{
OS_CreateTimerEx( timer_def->timerId,
(OS_TIMER_EX_ROUTINE *) ( timer_def->ptimer ), -, argument );
return timer_def->timerId;
} // Start or restart a timer.
// param[in] timer_id timer ID obtained by osTimerCreate.
// param[in] millisec time delay value of the timer.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osTimerStart shall be consistent in every CMSIS-RTOS.
//
osStatus osTimerStart( osTimerId timer_id, uint32_t millisec )
{
OS_SetTimerPeriodEx( timer_id, osKernelTicksByMilliSec( millisec ) );
OS_RetriggerTimerEx( timer_id );
return osOK;
} // Stop the timer.
// param[in] timer_id timer ID obtained by osTimerCreate.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osTimerStop shall be consistent in every CMSIS-RTOS.
//
osStatus osTimerStop( osTimerId timer_id )
{
OS_StopTimerEx( timer_id );
return osOK;
} // Delete a timer that was created by osTimerCreate.
// param[in] timer_id timer ID obtained by osTimerCreate.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osTimerDelete shall be consistent in every CMSIS-RTOS.
//
osStatus osTimerDelete( osTimerId timer_id )
{
OS_DeleteTimerEx( timer_id );
return osOK;
} // ============= Signal Management =============================================
//
// Set the specified Signal Flags of an active thread.
// param[in] thread_id thread ID obtained by osThreadCreate or 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.
// MUST REMAIN UNCHANGED: osSignalSet shall be consistent in every CMSIS-RTOS.
//
int32_t osSignalSet( osThreadId thread_id, int32_t signals )
{
// Returns a list of events that have occurred for a specified task.
// The event mask of the events that have actually occurred
// the actual events remain signaled
//
int32_t result = OS_GetEventsOccurred( thread_id );
OS_SignalEvent( signals, thread_id );
return result;
} int32_t OS_ClearEvent( osThreadId thread_id, int32_t signals )
{
if ( thread_id == )
thread_id = osThreadGetId( );
int32_t result = thread_id.Events;
// uint32_t val = osDisableInterrupt( );
OS_DisableInt( ); // MOV.W R1, #0x80 MSR.W BASEPRI, R1
thread_id.Events &= ~signals;
if ( OS_Global.Counters.Cnt.DI == )
OS_EnableInt( ); // MOV.W R1, #0x00 MSR.W BASEPRI, R1
// osRestoreInterrupt( val );
return result;
} // Clear the specified Signal Flags of an active thread.
// param[in] thread_id thread ID obtained by osThreadCreate or 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.
// MUST REMAIN UNCHANGED: osSignalClear shall be consistent in every CMSIS-RTOS.
//
int32_t osSignalClear( osThreadId thread_id, int32_t signals )
{
// Returns the actual state of events
// and then clears the events of a specified task.
// Returns the actual state of events and then
// clears ** the ALL events ** of a specified task.
//
// return OS_ClearEvents( thread_id );
//
return OS_ClearEvent( thread_id );
} // Wait for one or more Signal Flags to become signaled for the current 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.
// MUST REMAIN UNCHANGED: osSignalWait shall be consistent in every CMSIS-RTOS.
//
osEvent osSignalWait( int32_t signals, uint32_t millisec )
{
osEvent event;
event.status = osEventSignal; // Not allowed in ISR ?
// event.status = osErrorISR
//
// The task is not suspended even if no events are signaled.
if ( millisec == )
{
// Returns a list of events that have occurred for a specified task.
// The event mask of the events that have actually occurred.
event.value.signals = OS_GetEventsOccurred( );
} else if ( millisec == osWaitForever )
{
if ( signals == ) // Wait forever until any single signal flag
{
// Waits for one of the events specified in the bitmask and
// clears the event memory after an event occurs
event.value.signals = OS_WaitEvent( 0xFFFFFFFF );
} else // Wait forever until all specified signal flags set
{
// Waits for one or more of the events specified by the Eventmask
// and clears only those events that were specified in the eventmask.
event.value.signals = OS_WaitSingleEvent( signals );
}
} else
{
if ( signals == ) // Wait millisec until any single signal flag
{
// Waits for the specified events for a given time, and clears
// ** the event memory ** after one of the requsted events occurs,
// or after the timeout expired.
event.value.signals = OS_WaitEventTimed( 0xFFFFFFFF,
osKernelTicksByMilliSec( millisec ) );
} else // Wait millisec until all specified signal flags set
{
// Waits for the specified events for a given time; after an event occurs,
// only ** the requested events ** are cleared.
event.value.signals = OS_WaitSingleEventTimed( signals,
osKernelTicksByMilliSec( millisec ) );
}
} if ( event.value.signals == )
{
event.status = ( millisec > ) ? osEventTimeout : osOK;
} return event;
} // ============= Mutex Management ==============================================
//
/* Resource semaphores are used for managingresources by avoiding conflicts
* caused by simultaneous use of a resource. The resource managed can be of
* any kind: a part of the program that is not reentrant, a piece of hardware
* like the display, a flash prom that can only be written to by a single task
* at a time, a motor in a CNC control that can only be controlled by one task
* at a time, and a lot more.
*
* The basic procedure is as follows:
* Any task that uses a resource first claims it calling the OS_Use() or
* OS_Request() routines of embOS. If the resource is available, the program
* execution of the task continues, but the resource is blocked for other tasks.
*
* If a second task now tries to use the same resource while it is in use
* by the first task, this second task is suspended until the first task releases
* the resource. However, if the first task that uses the resource calls
* OS_Use() again for that resource, it is not suspended because the resource
* is blocked only for other tasks.
*
* A resource semaphore contains a counter that keeps track of how many times
* the resource has been claimed by calling OS_Request() or OS_Use()
* by a particular task. It is released when that counter reaches 0,
* which means the OS_Unuse() routine has to be called exactly the same number
* of times as OS_Use() or OS_Request(). If it is not, the resource remains
* blocked for other tasks.
*
* On the other hand, a task cannot release a resource that it does not own
* by calling OS_Unuse().
*
* counter = 0 after OS_CreateRSema()
* counter++ : OS_Use() or OS_Request()
* counter-- : OS_Unuse()
*
* A programmer can prefer mutex rather than creating a semaphore with count 1.
*/
// Create and Initialize a Mutex object.
// param[in] mutex_def mutex definition referenced with osMutex.
// return : mutex ID for reference by other functions or NULL in case of error.
// MUST REMAIN UNCHANGED: osMutexCreate shall be consistent in every CMSIS-RTOS.
//
osMutexId osMutexCreate( osMutexDef_t * mutex_def )
{
OS_CreateRSema( mutex_def->mutexId );
return mutex_def->mutexId;
} // Wait until a Mutex becomes available.
// param[in] mutex_id mutex ID obtained by 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.
// MUST REMAIN UNCHANGED: osMutexWait shall be consistent in every CMSIS-RTOS.
//
osStatus osMutexWait( osMutexId mutex_id, uint32_t millisec )
{
osStatus status = osOK; if ( millisec == )
{
if ( OS_Request( mutex_id ) == )
{
status = osErrorResource;
}
} else if ( millisec == osWaitForever )
{
OS_Use( mutex_id );
} else if ( == OS_UseTimed( mutex_id, osKernelTicksByMilliSec( millisec ) ) )
{
status = osErrorTimeoutResource;
} return status;
} // Release a Mutex that was obtained by osMutexWait.
// param[in] mutex_id mutex ID obtained by osMutexCreate.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osMutexRelease shall be consistent in every CMSIS-RTOS.
//
osStatus osMutexRelease( osMutexId mutex_id )
{
OS_Unuse( mutex_id );
return osOK;
} // Delete a Mutex that was created by osMutexCreate.
// param[in] mutex_id mutex ID obtained by osMutexCreate.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osMutexDelete shall be consistent in every CMSIS-RTOS.
//
osStatus osMutexDelete( osMutexId mutex_id )
{
OS_DeleteRSema( mutex_id );
return osOK;
} // ============= Semaphore Management Functions ================================
/* Counting semaphores are counters that are managed by embOS.
* They are not as widely used as resource semaphores, events or mailboxes,
* but they can be very useful sometimes.
*
* They are used in situations where a task needs to wait for something
* that can be signaled one or more times.
*
* The semaphores can be accessed from any point, any task,
* or any interrupt in any way.
*
* OS_CreateCSema()
* Creates a counting semaphore with a specified initial count value
*
* OS_SignalCSema()
* Increments the counter of a semaphore.
* If one or more tasks are waiting for an event to be signaled to this
* semaphore, the task that has the highest priority will become the running task
*
* OS_WaitCSema()
* Decrements the counter of a semaphore.
* If the counter of the semaphore is not 0, the counter is decremented
* and program execution continues.
* If the counter is 0, WaitCSema()waits until the counter is incremented by
* another task, a timer or an interrupt handler via a call to OS_SignalCSema().
* The counter is then decremented and program execution continues.
*
* OS_WaitCSemaTimed()
* Decrements a semaphore counter if the semaphore is available
* within a specified time.
* If the semaphore was not signaled within the specified time, the program
* execution continues but returns a value of 0.
*
* OS_CSemaRequest()
* Decrements the counter of a semaphore, if it is signaled.
* If the counter is 0, OS_CSemaRequest() does not wait and does not modify
* the semaphore counter. The function returns with error state.
*
*/ // Create and Initialize a Semaphore object used for managing resources.
// param[in] semaphore_def semaphore definition referenced with osSemaphore.
// param[in] count number of available resources.
// return : semaphore ID for reference by other functions or NULL in case of error.
// MUST REMAIN UNCHANGED: osSemaphoreCreate shall be consistent in every CMSIS-RTOS.
//
osSemaphoreId osSemaphoreCreate( osSemaphoreDef_t * semaphore_def,
int32_t count )
{
// Creates a counting semaphore with a specified initial count value.
OS_CreateCSema( semaphore_def->semaphoreId, count );
return semaphore_def->semaphoreId;
} // Wait until a Semaphore token becomes available.
// param[in] semaphore_id semaphore object referenced with osSemaphoreCreate.
// param[in] millisec timeout value or 0 in case of no time-out.
// return : number of available tokens : (tokens after wait) + 1
// or -1 in case of incorrect parameters.
// MUST REMAIN UNCHANGED: osSemaphoreWait shall be consistent in every CMSIS-RTOS.
//
int32_t osSemaphoreWait( osSemaphoreId semaphore_id, uint32_t millisec )
{
int32_t result = -; // OS_WaitCSemaTimed() timeout if ( millisec == )
{
// Decrements the counter of a semaphore, if it is signaled
if ( OS_CSemaRequest( semaphore_id ) )
{
// Returns the counter value of a specified semaphore
result = OS_GetCSemaValue( semaphore_id );
}
} else if ( millisec == osWaitForever )
{
// Decrements the counter of a semaphore
// If the counter of the semaphore is not 0, the counter is decremented
// and program execution continues.
// If the counter is 0, WaitCSema() waits until the counter is incremented
// by another task, a timer or an interrupt handler
// via a call to OS_SignalCSema().
OS_WaitCSema( semaphore_id ); // Returns the counter value of a specified semaphore
result = OS_GetCSemaValue( semaphore_id );
}
// Decrements a semaphore counter if the semaphore is available
// within a specified time.
else if ( OS_WaitCSemaTimed( semaphore_id,
osKernelTicksByMilliSec( millisec ) ) )
{
result = OS_GetCSemaValue( semaphore_id );
} return result + ;
} /**
* @brief Release a Semaphore token
* @param semaphore_id semaphore object referenced with osSemaphore.
* @retval status code that indicates the execution status of the function.
* @note MUST REMAIN UNCHANGED: osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
*/
osStatus osSemaphoreRelease( osSemaphoreId semaphore_id )
{
// Increments the counter of a semaphore
// If one or more tasks are waiting for an event to be signaled to
// this semaphore, the task that has the highest priority will
// become the running task.
OS_SignalCSema( semaphore_id );
return osOK;
} // Release a Semaphore token.
// param[in] semaphore_id semaphore object referenced with osSemaphoreCreate.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osSemaphoreRelease shall be consistent in every CMSIS-RTOS.
//
osStatus osSemaphoreDelete( osSemaphoreId semaphore_id )
{
// Deletes a specified semaphore.
// Before deleting a semaphore, make sure that no task is waiting for it
// and that notask will signal that semaphore at a later point.
OS_DeleteCSema( semaphore_id );
return osOK;
} // ============= Memory Pool Management Functions ============================== // Create and Initialize a memory pool.
// param[in] pool_def memory pool definition referenced with osPool.
// return : memory pool ID for reference by other functions or NULL in case of error.
// MUST REMAIN UNCHANGED: osPoolCreate shall be consistent in every CMSIS-RTOS.
//
osPoolId osPoolCreate( osPoolDef_t * pool_def )
{
// void OS_MEMF_Create (OS_MEMF* pMEMF, void* pPool, OS_UINT NumBlocks, OS_UINT BlockSize);
// BlockSize is aligment at 4 Bytes !!!
//
OS_MEMF_Create( pool_def->poolId, pool_def->pool, pool_def->pool_sz,
pool_def->item_sz );
return pool_def->poolId;
} // Allocate a memory block from a memory pool.
// param[in] pool_id memory pool ID obtain referenced with osPoolCreate.
// return : address of the allocated memory block or NULL in case of no memory available.
// MUST REMAIN UNCHANGED: osPoolAlloc shall be consistent in every CMSIS-RTOS.
//
// Requests allocation of a memory block.
// Waits until a block of memory is available
// If there is no free memory block in the pool, the calling task is suspended
// until a memory block becomes available.
//
void * osPoolAlloc( osPoolId pool_id )
{
return OS_MEMF_Alloc( pool_id, );
} // Requests allocation of a memory block. Waits until a block of memory
// is available or the timeout has expired.
//
void * osPoolAllocTimed( osPoolId pool_id, uint32_t millisec )
{
return OS_MEMF_AllocTimed( pool_id, osKernelTicksByMilliSec( millisec ), );
} // Requests allocation of a memory block. Continues execution in any case.
// The calling task is never suspended by calling OS_MEMF_Request()
//
void * osPoolRequest( osPoolId pool_id )
{
return OS_MEMF_Request( 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 osPoolCreate.
// return : address of the allocated memory block or NULL in case of no memory available.
// MUST REMAIN UNCHANGED: osPoolCAlloc shall be consistent in every CMSIS-RTOS.
void * osPoolCAlloc( osPoolId pool_id )
{
void * p = osPoolAlloc( pool_id ); if ( p )
{
memset( p, , pool_id->BlockSize );
} return p;
} // Return an allocated memory block back to a specific memory pool.
// param[in] pool_id memory pool ID obtain referenced with 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.
// MUST REMAIN UNCHANGED: osPoolFree shall be consistent in every CMSIS-RTOS.
osStatus osPoolFree( osPoolId pool_id, void * block )
{
OS_MEMF_Release( pool_id, block );
return osOK;
} // ============= Message Queue Management Functions ============================= // Create and Initialize a Message Queue.
// param[in] queue_def queue definition referenced with osMessageQ.
// param[in] thread_id thread ID (obtained by osThreadCreate or osThreadGetId) or NULL.
// return : message queue ID for reference by other functions or NULL in case of error.
// MUST REMAIN UNCHANGED: osMessageCreate shall be consistent in every CMSIS-RTOS.
//
osMessageQId osMessageCreate( osMessageQDef_t * queue_def,
osThreadId thread_id )
{
OS_CreateMB( queue_def->messageQId, , queue_def->queue_sz, queue_def->pool );
return queue_def->messageQId;
} // Put a Message to a Queue.
// param[in] queue_id message queue ID obtained with 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.
// MUST REMAIN UNCHANGED: osMessagePut shall be consistent in every CMSIS-RTOS.
//
osStatus osMessagePut( osMessageQId queue_id, uint32_t info, uint32_t millisec )
{
osStatus status = osOK; if ( millisec == )
{
if ( OS_PutMailCond( queue_id, (const void *) &info ) > )
{
status = osErrorResource;
}
}
else if ( millisec == osWaitForever )
{
OS_PutMail( queue_id, (const void *) &info );
}
else
{
OS_TIME osKernelTickCountPrev = osKernelTickCount(); while ( )
{
if ( OS_PutMailCond( queue_id, (const void *) &info ) == )
return status; osDelay( ); if ( ( osKernelTickCount() - osKernelTickCountPrev )
> osKernelTicksByMilliSec( millisec ) )
return osErrorTimeoutResource;
}
} return status;
} // Get a Message or Wait for a Message from a Queue.
// param[in] queue_id message queue ID obtained with osMessageCreate.
// param[in] millisec timeout value or 0 in case of no time-out.
// return : event information that includes status code.
// MUST REMAIN UNCHANGED: osMessageGet shall be consistent in every CMSIS-RTOS.
//
osEvent osMessageGet( osMessageQId queue_id, uint32_t millisec )
{
osEvent event;
event.status = osEventMessage; // The task is not suspended even if no events are signaled.
if ( millisec == )
{
if ( OS_GetMailCond( queue_id, &event.value.v ) > )
{
event.status = osOK;
}
} else if ( millisec == osWaitForever )
{
OS_GetMail( queue_id, &event.value.v );
} else if ( OS_GetMailTimed( queue_id, &event.value.v,
osKernelTicksByMilliSec( millisec ) ) > )
{
event.status = osEventTimeout;
} return event;
} osStatus osMessageDelete( osMessageQId queue_id )
{
OS_DeleteMB( queue_id );
return osOK;
} // ============= Mail Queue Management Functions =============================== // Mail Queues available
// Create and Initialize mail queue.
// param[in] queue_def reference to the mail queue definition obtain with osMailQ
// param[in] thread_id thread ID (obtained by osThreadCreate or osThreadGetId) or NULL.
// return : mail queue ID for reference by other functions or NULL in case of error.
// MUST REMAIN UNCHANGED: osMailCreate shall be consistent in every CMSIS-RTOS.
//
osMailQId osMailCreate( osMailQDef_t * queue_def, osThreadId thread_id )
{
queue_def->mailId->messageId = osMessageCreate( queue_def->messageQDef,
thread_id );
queue_def->mailId->poolId = osPoolCreate( queue_def->poolDef );
return queue_def->mailId;
} // Allocate a memory block from a mail.
// param[in] queue_id mail queue ID obtained with 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.
// MUST REMAIN UNCHANGED: osMailAlloc shall be consistent in every CMSIS-RTOS.
//
void * osMailAlloc( osMailQId queue_id, uint32_t millisec )
{
void * p; if ( millisec == )
{
p = osPoolRequest( queue_id->poolId );
} else if ( millisec == osWaitForever )
{
p = osPoolAlloc( queue_id->poolId );
} else
{
p = osPoolAllocTimed( queue_id->poolId, millisec );
} return p;
} // Allocate a memory block from a mail and set memory block to zero.
// param[in] queue_id mail queue ID obtained with 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.
// MUST REMAIN UNCHANGED: osMailCAlloc shall be consistent in every CMSIS-RTOS.
//
void * osMailCAlloc( osMailQId queue_id, uint32_t millisec )
{
void * p = osMailAlloc( queue_id, millisec ); if ( p )
{
memset( p, , queue_id->poolId->BlockSize );
} return p;
} // Put a mail to a queue.
// param[in] queue_id mail queue ID obtained with osMailCreate.
// param[in] mail memory block previously allocated with osMailAlloc or osMailCAlloc.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osMailPut shall be consistent in every CMSIS-RTOS.
//
osStatus osMailPut( osMailQId queue_id, void * mail )
{
return osMessagePut( queue_id->messageId, (uint32_t) mail, osWaitForever );
} // Get a mail from a queue.
// param[in] queue_id mail queue ID obtained with osMailCreate.
// param[in] millisec timeout value or 0 in case of no time-out
// return : event that contains mail information or error code.
// MUST REMAIN UNCHANGED: osMailGet shall be consistent in every CMSIS-RTOS.
//
osEvent osMailGet( osMailQId queue_id, uint32_t millisec )
{
osEvent event = osMessageGet( queue_id->messageId, millisec ); if ( event.status == osEventMessage )
{
event.status = osEventMail;
} return event;
} // Free a memory block from a mail.
// param[in] queue_id mail queue ID obtained with osMailCreate.
// param[in] mail pointer to the memory block that was obtained with osMailGet.
// return : status code that indicates the execution status of the function.
// MUST REMAIN UNCHANGED: osMailFree shall be consistent in every CMSIS-RTOS.
//
osStatus osMailFree( osMailQId queue_id, void * mail )
{
return osPoolFree( queue_id->poolId, mail );
} // ============= Memory Management Functions =================================== static osMutexDef( cmsis_memory )
;
static osMutexId cmsis_memory; osStatus osMemoryLock( uint32_t timeout )
{
if ( cmsis_memory == )
cmsis_memory = osMutexCreate( osMutex( cmsis_memory ) ); return osMutexWait( cmsis_memory, timeout );
} void osMemoryUnlock( void )
{
osMutexRelease( cmsis_memory );
} /* Allocates a block of size bytes of memory, returning a pointer
* to the beginning of the block. The content of the newly allocated block of
* memory is not initialized, remaining with indeterminate values.
*
* On success, a pointer to the memory block allocated by the function.
* The type of this pointer is always void*, which can be cast to the desired
* type of data pointer in order to be dereferenceable.
*
* If the function failed to allocate the requested block of memory,
* a null pointer is returned.
*
*/
void * osMalloc( size_t size, uint32_t timeout )
{
void * p = ;
osStatus status = osMemoryLock( timeout );
if ( status == osOK )
{
p = malloc( size );
osMemoryUnlock( );
}
return p;
} /* Allocates a block of memory for an array of num elements,
* each of them size bytes long, and initializes all its bits to zero.
*
* The effective result is the allocation of a zero-initialized memory block
* of (num*size) bytes.
*
* On success, a pointer to the memory block allocated by the function.
* The type of this pointer is always void*, which can be cast to the desired
* type of data pointer in order to be dereferenceable.
*
* If the function failed to allocate the requested block of memory,
* a null pointer is returned.
*
*/
void * osCalloc( size_t nelem, size_t elsize, uint32_t timeout )
{
void * p = osMalloc( nelem * elsize, timeout ); if ( p )
{
memset( p, , nelem * elsize );
} return p;
} /* Changes the size of the memory block pointed to by ptr.
* The function may move the memory block to a new location (whose address is
* returned by the function).
*
* The content of the memory block is preserved up to the lesser of the new
* and old sizes, even if the block is moved to a new location.
*
* If the new size is larger, the value of the newly allocated portion
* is indeterminate.
*
* In case that ptr is a null pointer, the function behaves like malloc,
* assigning a new block of size bytes and returning a pointer to its beginning.
*
* If the function fails to allocate the requested block of memory,
* a null pointer is returned, and the memory block pointed to by argument ptr
* is not deallocated (it is still valid, and with its contents unchanged).
*
* A pointer to the reallocated memory block, which may be either the same
* as ptr or a new location. The type of this pointer is void*, which can be
* cast to the desired type of data pointer in order to be dereferenceable.
*/
void * osRealloc( void * ptr, size_t size, uint32_t timeout )
{
void * p = ;
osStatus status = osMemoryLock( timeout );
if ( status == osOK )
{
p = realloc( ptr, size );
osMemoryUnlock( );
}
return p;
} /* A block of memory previously allocated by a call to malloc, calloc or realloc
* is deallocated, making it available again for further allocations.
*
* If ptr does not point to a block of memory allocated with the above functions
* it causes undefined behavior.
* If ptr is a null pointer, the function does nothing.
*
* Notice that this function does not change the value of ptr itself,
* hence it still points to the same (now invalid) location.
*
*/
void osFree( void * ptr )
{
osMemoryLock( osWaitForever );
free( ptr );
osMemoryUnlock( );
} /*
* Informs RTOS that interrupt code is executing.
*
* If osEnterInterrupt() is used, it should be the first function to be called
* in the interrupt handler. It must be used with osLeaveInterrupt() as the last
* function called. The use of this function has the following effects, it:
*
* disables task switches
* keeps interrupts in internal routines disabled.
*/
void osEnterInterrupt( void )
{
OS_EnterInterrupt()
;
} /*
* Informs RTOS that the end of the interrupt routine has been reached;
* executes task switching within ISR.
*
* If osLeaveInterrupt()is used, it should be the last function to be called
* in the interrupt handler. If the interrupt has caused a task switch, it will
* be executed (unless the program which was interrupted was in a critical region).
*
*/
void osLeaveInterrupt( void )
{
OS_LeaveInterrupt()
;
} uint32_t osDisableInterrupt( void )
{
__istate_t s = __get_interrupt_state( );
__disable_interrupt( );
return (uint32_t) s; } void osRestoreInterrupt( uint32_t val )
{
__set_interrupt_state( (__istate_t ) val );
}
#include "cmsis_os.h" #if defined(osFeature_MainThread) && (osFeature_MainThread > 0 ) /*----------------------------------------------------------------------------
* RTX Startup
*---------------------------------------------------------------------------*/ /* Main Thread definition */
extern int main (void); osThreadDef( main, main, osPriorityNormal, , OS_MAINSTKSIZE ); extern int __low_level_init(void);
extern void __iar_data_init3(void);
extern void exit(int arg); __noreturn __stackless void __cmain(void) {
int a; if (__low_level_init() != ) {
__iar_data_init3();
}
osKernelInitialize();
osThreadCreate(&os_thread_def_main, NULL);
a = osKernelStart();
exit(a);
} #endif
CMSIS RTOS -- embOS segger的更多相关文章
- 在多任务(RTOS)环境中使用看门狗
最近在SEGGER的博客上看到一篇有关在实时操作系统使用看门狗的文章.从一个失败的太空项目出发,分析了看门狗的作用及使用,自我感觉很有启发,特此翻译此文并推荐给各位同仁.为了阅读方便,有些航天领域名词 ...
- RTOS之CMSIS-RTOS
CMSIS-RTOS 是实时操作系统的通用 API.它提供了标准化的编程接口,它只是封装了RTX/embos,以后还可能封装freeRTOS,uc/os等等第三方OS,CMSIS RTOS是ARM现在 ...
- 聊聊CMSIS-RTOS是什么东东
起因:发布自己翻译用的CMSIS_RTOS_Tutorial后,陆续收到网友关于“CMSIS-RTOS是干么的?”之类的问题,再次统一回复. 众所周知,实时操作系统是嵌入式领域的基石.而可选的嵌入式操 ...
- STM32F429i-DISCO FreeRTOS keil STM32CubeMX
目标: 在STM32F429 Disco开发板上用FreeRTOS双线程点亮双闪led. 准备: 0. STM32F429i-DISCO 1. keil ARMMDK 5.13 2. STM32Cub ...
- CMSIS_RTOS_Tutorial自译中文版
一.序言 本资料是Trevor Martin编写的<The Designers Guide to the Cortex-M Processor Family>的摘要,并得到Elsevier ...
- CMSIS-RTOS 时间管理之时间延迟Time Delay
时间管理 Time Management 此RTOS除了可以把你的应用代码作为线程运行,它还可以提供一些时间服务功能,使用这些功能你就可以访问RTOS的一些系统调用. 时间延迟Time Delay 在 ...
- ARM官方《CMSIS-RTOS教程》之线程Threads
创建线程Creating Threads 一旦RTOS开始运行,就会有很多系统调用来管理和控制活跃的线程.默认情况下,main()函数自动被创建为第一个可运行的线程.在第一个例子里我们使用main() ...
- CMSIS-RTOS的使用
CMSIS-RTOS实现通常作为库提供.要将RTOS功能添加到现有的基于CMSIS的应用程序,需要添加RTOS库(通常是配置文件).RTOS库的可用功能在头文件cmsis_os.h中定义,该文件特定于 ...
- cmsis dap interface firmware
cmsis dap interface firmware The source code of the mbed HDK (tools + libraries) is available in thi ...
随机推荐
- Apache二级域名配置方法
下面这个Apache二级域名配置方法是今天在其它BBS看到的,以前我配置是都是配置每个为一个虚拟目录今天正在想如何写没想到找到了. Apache二级域名实现方法介绍 首先,你的拥有一个有泛域名解析的顶 ...
- 嵌入式 GDB调试死锁示例
死锁:一种情形,此时执行程序中两个或多个线程发生永久堵塞(等待),每个线程都在等待被 其他线程占用并堵塞了的资源.例如,如果线程A锁住了记录1并等待记录2,而线程B锁住了记录2并等待记录1,这样两个线 ...
- A woman without arms
任吉美出生在中国烟台海阳一个极为普通的渔民家里.她先天残疾,没有胳膊和手. 小吉美注定要比别人生活得更艰难.她不能自己穿衣,不能自己端碗吃饭,也不能像兄弟姐妹们一样帮助妈妈干家务活,她觉得自己成了家里 ...
- Javascript实现局部刷新
<div id="altContent"> 要刷新的区域000000</div><input type="button& ...
- 浅谈“be practical and realistic”
一 “实事求是”这个词,一般认为是古人的一种治学观念,后来经咏芝的发明.阐释.以及“应用”,成为“基本思想路线”(具体可参看大学思想政治教科书),被称为“活的灵魂”.这里不想过多地牵扯政治话题,仅就我 ...
- 2015 NI 校招笔试机试面试
美国国家仪器NI也算是入驻上海很好的一家外企了,它是我们院的合作公司,加上今年NI在我们院扩招实习生,这次是一个难得的机会可以进入NI实习,可惜我并没有好好把握... 一.笔试 几个做错的印象特别深刻 ...
- oracle 数据库远程导出
exp 用户名/密码@IP:端口/数据库名 file=文件路径 full=y; exp scebm1/ebm@10.3.10.16:1521/scebm file=D:scebm20140527.dm ...
- 一起来画画!8款最佳HTML5绘图工具
HTML5无疑是当前最受宠的一项技术,今天推荐8款HTML5绘图工具,同样惊艳你的眼球!这些绘图工具大多数是用HTML5画布(Canvas)实现的,部分辅以Javascript.对每一个web设计者来 ...
- 关于python requests包新版本设置代理的问题
在更新了requests包之后,发现我电脑上的charles工具无法再成功抓取到数据包.百度了半年都没有找到原因. 然后 我使用了 google 查到了 charles的最新的文档发现.需要设置代理, ...
- 【转】XML之命名空间的作用(xmlns)
原文链接:http://blog.csdn.net/zhch152/article/details/8191377 命名空间的作用,下面的内容是转载的,大家可以看看: 问题的出现:XML的元素名字 ...