首页 > 代码库 > CMSIS RTOS -- embOS segger

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  __cplusplusextern "C"{#endif// ==== Enumeration, structures, defines =======================================//// Priority used for thread control.// MUST REMAIN UNCHANGED: 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} 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 = 0,  //  // 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 = http://www.mamicode.com/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 = 0,            // one-shot timer  osTimerPeriodic = 1         // 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 / 1000000 )//#define osKernelSysTickMicroSec_f  \  ( ( ( (uint64_t)( osKernelSysTickFrequency - 1000000 * ( osKernelSysTickFrequency / 1000000 ) ) ) << 16 ) / 1000000 )//// Convert a microseconds value to a RTOS kernel system timer value.#define osKernelSysTickMicroSec(microsec)   \  ( ( microsec * osKernelSysTickMicroSec_i ) + ( ( microsec * osKernelSysTickMicroSec_f ) >> 16 ) )//#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 ) + 3 ) / 4];        osThreadDef_t os_thread_def_##name =                                      { &os_thread_id_##name, #name, (os_pthread)(thread), (priority),        (( ( (stacksz ? stacksz : OS_STKSIZE ) + 3 ) / 4) << 2 ),               os_thread_stack_##name }#endif#define osThread(name)    &os_thread_def_##nameosThreadId 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_##nameosTimerId 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_##nameosMutexId 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_##nameosSemaphoreId 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) + 3 ) / 4) * (no) ];   osPoolDef_t   os_pool_def_##name =                        { &os_pool_id_##name, (no),                          ( ( ( OS_MEMF_SIZEOF_BLOCKCONTROL + sizeof(type) + 3 ) / 4) << 2 ),                          (os_pool_m_##name) }#endif#define osPool(name)   &os_pool_def_##nameosPoolId 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) ] = { 0 };   osMessageQDef_t os_messageQ_def_##name =       { &os_messageQ_id_##name, (queue_sz << 2 ) , (os_messageQ_q_##name) }#endif#define osMessageQ(name)   &os_messageQ_def_##nameosMessageQId 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) + 3) >> 2 ) << 2 ) }#endif#define osMailQ(name)    &os_mailQ_def_##nameosMailQId 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 valueuint32_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, 2, 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 ), -1, 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 == 0 )    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 == 0 )    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 == 0 )  {    // 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( 0 );  }  else if ( millisec == osWaitForever )  {    if ( signals == 0 ) // 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 == 0 ) // 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 == 0 )  {    event.status = ( millisec > 0 ) ? 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 == 0 )  {    if ( OS_Request( mutex_id ) == 0 )    {      status = osErrorResource;    }  }  else if ( millisec == osWaitForever )  {    OS_Use( mutex_id );  }  else if ( 0 == 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 = -1; // OS_WaitCSemaTimed() timeout  if ( millisec == 0 )  {    // 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 + 1;}/** * @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, 0 );}// 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 ), 0 );}// 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, 0 );}// 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, 0, 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, 4, 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 == 0 )  {    if ( OS_PutMailCond( queue_id, (const void *) &info ) > 0 )    {      status = osErrorResource;    }  }  else if ( millisec == osWaitForever )  {    OS_PutMail( queue_id, (const void *) &info );  }  else  {    OS_TIME osKernelTickCountPrev = osKernelTickCount();    while ( 1 )    {      if ( OS_PutMailCond( queue_id, (const void *) &info ) == 0 )        return status;      osDelay( 1 );      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 == 0 )  {    if ( OS_GetMailCond( queue_id, &event.value.v ) > 0 )    {      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 ) ) > 0 )  {    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 == 0 )  {    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, 0, 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 == 0 )    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 = 0;  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, 0, 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 = 0;  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, 1, 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() != 0) {    __iar_data_init3();  }  osKernelInitialize();  osThreadCreate(&os_thread_def_main, NULL);  a = osKernelStart();  exit(a);}#endif