您的应用程序的main()应至少按照给定的顺序执行以下操作:
硬件的初始化和配置,包括外设,内存,引脚,时钟和中断系统。使用相应的CMSIS-CORE功能更新系统内核时钟。使用osKernelInitialize初始化CMSIS-RTOS内核。(可选)创建一个新线程app_main,该线程用作使用osThreadNew的主线程。 或者,可以直接在main()中创建线程。使用osKernelStart启动RTOS调度程序。 在执行成功的情况下,此函数不返回。 osKernelStart之后的任何应用程序代码将不被执行,除非osKernelStart失败。注意
内核使用的中断(例如SVC)在osKernelInitialize中初始化。 如果NVIC中的优先级和分组在上述顺序之后被应用程序改变,则可能需要再次调用osKernelInitialize。
内存分配
RTX5对象(线程,互斥体,信号量,定时器,消息队列,线程和事件标志以及内存池)都需要专用的RAM内存。 可以使用osobjectNew()调用创建对象,并使用osobjectDelete()调用进行删除。 相关对象内存需要在对象的生命周期内可用。
RTX5为对象提供了三种不同的内存分配方法:
全局内存池为所有对象使用单个全局内存池。 容易配置,但是当创建和销毁具有不同大小的对象时,可能存在内存碎片的缺点。对象特定的内存池对于每个对象类型使用固定大小的内存池。 该方法是时间确定性的,避免了内存碎片。静态对象内存在编译期间保留内存,完全避免了系统内存不足。 这通常是一些安全关键系统所必需的。可以在同一应用程序中混合所有的内存分配方法。
全局内存池 全局内存池从内存区域分配所有对象。 这种内存分配方式是RTX5的默认配置设置。
全局内存池为所有对象
当内存池没有提供足够的内存时,对象的创建失败,相关的osobjectNew()函数返回NULL。
在系统配置中启用。
对象特定的内存池
对象特定的内存池通过针对每种对象类型的专用固定大小的内存管理来避免内存碎片。 这种类型的内存池是完全时间确定性的,这意味着对象创建和销毁总是保持相同的固定时间长度。 由于固定大小的内存池特定于对象类型,因此简化了对内存不足情况的处理。
每个对象类型有一个内存池每个对象类型都有选择地启用对象特定的内存池,例如:使用RTX配置文件的mutex或线程:
在线程配置中为线程对象启用。在定时器对象的定时器配置中启用。在事件对象的事件标志配置中启用。在互斥体对象的Mutex配置中启用。在信号量的信号量配置中启用。在内存池的内存池配置中启用。在消息对象的消息队列配置中启用。当内存池没有提供足够的内存时,对象的创建失败,相关的osobjectNew()函数返回NULL。静态对象内存
与动态内存分配相反,静态内存分配需要编译时分配对象内存。
静态分配所有对象的内存 以下代码示例显示如何使用静态内存创建OS对象。
Code Example:
/*---------------------------------------------------------------------------- * CMSIS-RTOS 'main' function template *---------------------------------------------------------------------------*/ #include "RTE_Components.h" #include CMSIS_device_header #include "cmsis_os2.h" //include rtx_os.h for types of RTX objects #include "rtx_os.h" //The thread function instanced in this example void worker(void *arg) { while(1) { //work osDelay(10000); } } // Define objects that are statically allocated for worker thread 1 osRtxThread_t worker_thread_tcb_1; // Reserve two areas for the stacks of worker thread 1 // uint64_t makes sure the memory alignment is 8 uint64_t worker_thread_stk_1[64]; // Define the attributes which are used for thread creation // Optional const saves RAM memory and includes the values in periodic ROM tests constosThreadAttr_t worker_attr_1 = { "wrk1", osThreadJoinable, &worker_thread_tcb_1, sizeof(worker_thread_tcb_1), &worker_thread_stk_1[0], sizeof(worker_thread_stk_1), osPriorityAboveNormal, 0 }; // Define ID object for thread osThreadId_t th1; /*---------------------------------------------------------------------------- * Application main thread *---------------------------------------------------------------------------*/ void app_main (void *argument) { uint32_t param = NULL; // Create an instance of the worker thread with static resources (TCB and stack) th1 = osThreadNew(worker, ¶m, &worker_attr_1); for (;;) {} } int main (void) { // System Initialization SystemCoreClockUpdate(); // ... osKernelInitialize();// Initialize CMSIS-RTOS osThreadNew(app_main, NULL, NULL); // Create application main thread osKernelStart();// Start thread execution for (;;) {} }
线程堆栈管理
对于没有浮点单元的Cortex-M处理器,线程上下文在本地堆栈上需要64个字节。
注意
对于具有FP的Cortex-M4 / M7,线程上下文在本地堆栈上需要200字节。 对于这些设备,默认堆栈空间应增加至少300个字节。
每个线程都提供一个单独的堆栈,它保存线程上下文和堆栈空间,用于自动变量和函数调用嵌套的返回地址。 RTX线程的堆栈大小可灵活配置,如"线程配置"部分所述。 RTX提供了对堆栈溢出和堆栈利用率的可配置检查。
低功耗操作
系统线程osRtxIdleThread可用于将系统切换到低功耗模式。 进入低功耗模式的最简单的形式是执行__WFE功能,使处理器进入等待事件的睡眠模式。
Code Example:
#include "RTE_Components.h" #include CMSIS_device_header/* Device definitions */ voidosRtxIdleThread (void) { /* The idle demon is a system thread, running when no other thread is */ /* ready to run. */ for (;;) { __WFE(); /* Enter sleep mode */ } } 注意 每个Cortex-M实现中__WFE()都不可用。 检查设备手册的可用性。
RTX内核定时器Tick
默认情况下,RTX5使用Cortex-M SysTick定时器为RTX内核定时器tick生成周期性中断。 CMSIS-RTOS提供定时器管理功能,多个CMSIS-RTOS功能具有超时参数。 这个周期性的RTX内核定时器中断是用来导出所需的时间间隔。 RTX5还提供了替代计时器和无勾选操作的配置选项。
为了处理线程的超时和时间延迟,RTX5线程管理由RTX内核定时器刻度中断控制。 线程上下文包含所有CPU寄存器(R0 - R12),返回地址(LR),程序计数器(PC)和处理器状态寄存器(xPSR)。 对于Cortex-M4 / M7 FPU,浮点状态和寄存器(S0 - S32,FPSCR)也是线程上下文的一部分。
发生线程切换时:
当前运行的线程的线程上下文存储在该线程的本地堆栈上。
堆栈指针被切换到下一个正在运行的线程。
这个下一个运行的线程的线程上下文被还原,并且这个线程开始运行。
超时值
超时值是几个osXxx函数的一个参数,以便能够解决请求的时间。 超时值为0意味着即使没有资源可用,RTOS也不会等待功能立即返回。 osWaitForever的超时值意味着RTOS无限等待直到资源变为可用。
超时值指定到时间延迟过去之前的定时器滴答数。 该值是上限,取决于自上次计时器计时以来经过的实际时间。
例子:
超时值0:系统不等待,即使没有资源可用,RTOS功能立即返回。
超时值1:系统等待直到下一个计时器出现; 取决于之前的计时器滴答,它可能是非常短的等待时间。
超时值2:实际等待时间在1到2个定时器之间。
超时值osWaitForever:系统等待无限直到资源变为可用。
使用osDelay()的超时举例
来自中断服务程序的调用
可以从线程和中断服务程序(ISR)调用以下CMSIS-RTOS2函数,
osKernelGetSysTimerCount, osKernelGetSysTimerFreqosThreadFlagsSetosEventFlagsSet, osEventFlagsClear, osEventFlagsGet, osEventFlagsWaitosSemaphoreAcquire, osSemaphoreRelease, osSemaphoreGetCountosMemoryPoolAlloc, osMemoryPoolFree, osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize, osMemoryPoolGetCount, osMemoryPoolGetSpaceosMessageQueuePut, osMessageQueueGet, osMessageQueueGetCapacity, osMessageQueueGetMsgSize, osMessageQueueGetCount, osMessageQueueGetSpace不能从ISR调用的函数正在验证中断状态,并返回状态代码osErrorISR,以防它们从ISR上下文中调用。 在某些实现中,可能会使用HARD_FAULT向量来捕获此条件。
RTX5提供了tick-less操作的扩展,对于使用SysTick定时器也被禁用的广泛低功耗模式的应用程序,这是非常有用的。 为了在这种省电模式下提供时间戳,使用唤醒定时器来导出定时器间隔。 CMSIS-RTOS2功能osKernelSuspend和osKernelResume控制tick-less操作。
使用此功能允许RTX5线程调度程序停止周期性内核中断。 当所有活动线程暂停时,系统进入掉电状态,并计算在此掉电模式下可以停留多长时间。 在掉电模式下,处理器和外围设备可以关闭。 只有唤醒定时器必须保持供电,因为该定时器负责在断电时间到期后唤醒系统。
tick-less操作由osRtxIdleThread线程控制。 唤醒超时值在系统进入掉电模式前设置。 函数osKernelSuspend计算在RTX Timer Ticks中测得的唤醒超时时间; 该值用于设置在系统掉电模式下运行的唤醒定时器。
一旦系统恢复运行(通过唤醒超时或其他中断),RTX5线程调度程序将以osKernelResume函数启动。 参数sleep_time指定系统处于掉电模式的时间(在RTX Timer Ticks中)。
Code Example:
#include "msp.h"// Device header /*---------------------------------------------------------------------------- * MSP432 Low-Power Extension Functions *---------------------------------------------------------------------------*/ staticvoid MSP432_LP_Entry(void) { /* Enable PCM rude mode, which allows to device to enter LPM3 without waiting for peripherals */ PCM->CTL1 = PCM_CTL1_KEY_VAL | PCM_CTL1_FORCE_LPM_ENTRY; /* Enable all SRAM bank retentions prior to going to LPM3 */ SYSCTL->SRAM_BANKRET |= SYSCTL_SRAM_BANKRET_BNK7_RET; __enable_interrupt(); NVIC_EnableIRQ(RTC_C_IRQn); /* Do not wake up on exit from ISR */ SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; /* Setting the sleep deep bit */ SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk); } staticvolatile unsigned int tc; staticvolatile unsigned int tc_wakeup; void RTC_C_IRQHandler(void) { if (tc++ > tc_wakeup) { SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; NVIC_DisableIRQ(RTC_C_IRQn); NVIC_ClearPendingIRQ(RTC_C_IRQn); return; } if (RTC_C->PS0CTL & RTC_C_PS0CTL_RT0PSIFG) { RTC_C->CTL0 = RTC_C_KEY_VAL; // Unlock RTC key protected registers RTC_C->PS0CTL &= ~RTC_C_PS0CTL_RT0PSIFG; RTC_C->CTL0 = 0; SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk); } } uint32_t g_enable_sleep = 0; voidosRtxIdleThread (void) { for (;;) { tc_wakeup = osKernelSuspend(); /* Is there some time to sleep? */ if (tc_wakeup > 0) { tc = 0; /* Enter the low power state */ MSP432_LP_Entry(); __WFI(); } /* Adjust the kernel ticks with the amount of ticks slept */ osKernelResume (tc); } }注意 每个ARM Cortex-M实现中__WFI()不可用。 检查设备手册的可用性。
RTX5头文件
CMSIS-RTOS2 API的每个实现都可以带来自己的附加功能。 RTX5增加了一些空闲功能,用于错误通知和特殊的系统定时器功能。 它也是使用宏控制块和内存大小。
如果您在应用程序代码中需要一些RTX特定功能,#包含头文件rtx_os.h
/* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * ----------------------------------------------------------------------------- * * Project: CMSIS-RTOS RTX * Title: RTX OS definitions * * ----------------------------------------------------------------------------- */ #ifndef RTX_OS_H_ #define RTX_OS_H_ #include <stdint.h> #include <stddef.h> #include "cmsis_os2.h" #ifdef __cplusplus extern"C" { #endif /// Kernel Information #define osRtxVersionAPI 20010000///< API version (2.1.0) #define osRtxVersionKernel 50010000///< Kernel version (5.1.0) #define osRtxKernelId "RTX V5.1.0"///< Kernel identification string // ==== Common definitions ==== /// Object Identifier definitions #define osRtxIdInvalid 0x00U #define osRtxIdThread 0x01U #define osRtxIdTimer 0x02U #define osRtxIdEventFlags 0x03U #define osRtxIdMutex 0x04U #define osRtxIdSemaphore 0x05U #define osRtxIdMemoryPool 0x06U #define osRtxIdMessage 0x07U #define osRtxIdMessageQueue 0x08U /// Object State definitions (except for Threads and Timers) #define osRtxObjectInactive 0x00U #define osRtxObjectActive 0x01U /// Object Flags definitions #define osRtxFlagSystemObject 0x01U #define osRtxFlagSystemMemory 0x02U // ==== Kernel definitions ==== /// Kernel State definitions #define osRtxKernelInactive ((uint8_t)osKernelInactive) #define osRtxKernelReady ((uint8_t)osKernelReady) #define osRtxKernelRunning ((uint8_t)osKernelRunning) #define osRtxKernelLocked ((uint8_t)osKernelLocked) #define osRtxKernelSuspended ((uint8_t)osKernelSuspended) // ==== Thread definitions ==== /// Thread State definitions (extending osThreadState) #define osRtxThreadStateMask 0x0FU #define osRtxThreadInactive ((uint8_t)osThreadInactive) #define osRtxThreadReady ((uint8_t)osThreadReady) #define osRtxThreadRunning ((uint8_t)osThreadRunning) #define osRtxThreadBlocked ((uint8_t)osThreadBlocked) #define osRtxThreadTerminated ((uint8_t)osThreadTerminated) #define osRtxThreadWaitingDelay (osRtxThreadBlocked | 0x10U) #define osRtxThreadWaitingJoin (osRtxThreadBlocked | 0x20U) #define osRtxThreadWaitingThreadFlags (osRtxThreadBlocked | 0x30U) #define osRtxThreadWaitingEventFlags (osRtxThreadBlocked | 0x40U) #define osRtxThreadWaitingMutex (osRtxThreadBlocked | 0x50U) #define osRtxThreadWaitingSemaphore (osRtxThreadBlocked | 0x60U) #define osRtxThreadWaitingMemoryPool (osRtxThreadBlocked | 0x70U) #define osRtxThreadWaitingMessageGet (osRtxThreadBlocked | 0x80U) #define osRtxThreadWaitingMessagePut (osRtxThreadBlocked | 0x90U) /// Thread Flags definitions #define osRtxThreadFlagDefStack 0x10U///< Default Stack flag /// Stack Marker definitions #define osRtxStackMagicWord 0xE25A2EA5U///< Stack Magic Word (Stack Base) #define osRtxStackFillPattern 0xCCCCCCCCU///< Stack Fill Pattern /// Thread Control Block typedefstruct osRtxThread_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t attr;///< Object Attributes constchar *name; ///< Object Name structosRtxThread_s *thread_next; ///< Link pointer to next Thread in Object list structosRtxThread_s *thread_prev; ///< Link pointer to previous Thread in Object list structosRtxThread_s *delay_next; ///< Link pointer to next Thread in Delay list structosRtxThread_s *delay_prev; ///< Link pointer to previous Thread in Delay list structosRtxThread_s *thread_join; ///< Thread waiting to Join uint32_t delay;///< Delay Time int8_t priority;///< Thread Priority int8_t priority_base;///< Base Priority uint8_t stack_frame;///< Stack Frame (EXC_RETURN[7..0]) uint8_t flags_options;///< Thread/Event Flags Options uint32_t wait_flags;///< Waiting Thread/Event Flags uint32_t thread_flags;///< Thread Flags structosRtxMutex_s *mutex_list; ///< Link pointer to list of owned Mutexes void *stack_mem;///< Stack Memory uint32_t stack_size;///< Stack Size uint32_t sp;///< Current Stack Pointer uint32_t thread_addr;///< Thread entry address uint32_t tz_memory;///< TrustZone Memory Identifier }osRtxThread_t; // ==== Timer definitions ==== /// Timer State definitions #define osRtxTimerInactive 0x00U///< Timer Inactive #define osRtxTimerStopped 0x01U///< Timer Stopped #define osRtxTimerRunning 0x02U///< Timer Running /// Timer Type definitions #define osRtxTimerPeriodic ((uint8_t)osTimerPeriodic) /// Timer Function Information typedefstruct { void *fp;///< Function Pointer void *arg;///< Function Argument }osRtxTimerFinfo_t; /// Timer Control Block typedefstruct osRtxTimer_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t type;///< Timer Type (Periodic/One-shot) constchar *name; ///< Object Name structosRtxTimer_s *prev; ///< Pointer to previous active Timer structosRtxTimer_s *next; ///< Pointer to next active Timer uint32_t tick;///< Timer current Tick uint32_t load;///< Timer Load value osRtxTimerFinfo_t finfo; ///< Timer Function Info }osRtxTimer_t; // ==== Event Flags definitions ==== /// Event Flags Control Block typedefstruct osRtxEventFlags_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t reserved; constchar *name; ///< Object Name osRtxThread_t *thread_list; ///< Waiting Threads List uint32_t event_flags;///< Event Flags }osRtxEventFlags_t; // ==== Mutex definitions ==== /// Mutex Control Block typedefstruct osRtxMutex_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t attr;///< Object Attributes constchar *name; ///< Object Name osRtxThread_t *thread_list; ///< Waiting Threads List osRtxThread_t *owner_thread; ///< Owner Thread structosRtxMutex_s *owner_prev; ///< Pointer to previous owned Mutex structosRtxMutex_s *owner_next; ///< Pointer to next owned Mutex uint8_t lock;///< Lock counter uint8_t padding[3]; } osRtxMutex_t; // ==== Semaphore definitions ==== /// Semaphore Control Block typedefstruct osRtxSemaphore_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t reserved; constchar *name; ///< Object Name osRtxThread_t *thread_list; ///< Waiting Threads List uint16_t tokens;///< Current number of tokens uint16_t max_tokens;///< Maximum number of tokens }osRtxSemaphore_t; // ==== Memory Pool definitions ==== /// Memory Pool Information typedefstruct osRtxMpInfo_s { uint32_t max_blocks; ///< Maximum number of Blocks uint32_t used_blocks;///< Number of used Blocks uint32_t block_size;///< Block Size void *block_base;///< Block Memory Base Address void *block_lim;///< Block Memory Limit Address void *block_free;///< First free Block Address }osRtxMpInfo_t; /// Memory Pool Control Block typedefstruct osRtxMemoryPool_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t reserved; constchar *name; ///< Object Name osRtxThread_t *thread_list; ///< Waiting Threads List osRtxMpInfo_t mp_info; ///< Memory Pool Info }osRtxMemoryPool_t; // ==== Message Queue definitions ==== /// Message Control Block typedefstruct osRtxMessage_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t priority;///< Message Priority structosRtxMessage_s *prev; ///< Pointer to previous Message structosRtxMessage_s *next; ///< Pointer to next Message }osRtxMessage_t; /// Message Queue Control Block typedefstruct osRtxMessageQueue_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t reserved; constchar *name; ///< Object Name osRtxThread_t *thread_list; ///< Waiting Threads List osRtxMpInfo_t mp_info; ///< Memory Pool Info uint32_t msg_size;///< Message Size uint32_t msg_count;///< Number of queued Messages osRtxMessage_t *msg_first; ///< Pointer to first Message osRtxMessage_t *msg_last; ///< Pointer to last Message }osRtxMessageQueue_t; // ==== Generic Object definitions ==== /// Generic Object Control Block typedefstruct osRtxObject_s { uint8_t id; ///< Object Identifier uint8_t state;///< Object State uint8_t flags;///< Object Flags uint8_t reserved; constchar *name; ///< Object Name osRtxThread_t *thread_list; ///< Threads List }osRtxObject_t; // ==== OS Runtime Information definitions ==== /// OS Runtime Information structure typedefstruct { constchar *os_id; ///< OS Identification uint32_t version;///< OS Version struct{ ///< Kernel Info uint8_t state;///< State volatile uint8_t blocked;///< Blocked uint8_t pendISR;///< Pending ISR (SV and SysTick) uint8_t pendSV;///< Pending SV uint32_t sys_freq;///< System Frequency uint64_t tick;///< Tick counter } kernel; int32_t tick_irqn; ///< Tick Timer IRQ Number struct{ ///< Thread Info struct{ ///< Thread Run Info osRtxThread_t *curr; ///< Current running Thread osRtxThread_t *next; ///< Next Thread to Run } run; volatileosRtxObject_t ready; ///< Ready List Object osRtxThread_t *idle; ///< Idle Thread osRtxThread_t *delay_list; ///< Delay List osRtxThread_t *wait_list; ///< Wait List (no Timeout) osRtxThread_t *terminate_list; ///< Terminate Thread List struct{ ///< Thread Round Robin Info osRtxThread_t *thread; ///< Round Robin Thread uint32_t tick;///< Round Robin Time Tick uint32_t timeout;///< Round Robin Timeout } robin; } thread; struct{ ///< Timer Info osRtxTimer_t *list; ///< Active Timer List osRtxThread_t *thread; ///< Timer Thread osRtxMessageQueue_t *mq; ///< Timer Message Queue } timer; struct{ ///< ISR Post Processing Queue uint16_t max;///< Maximum Items uint16_t cnt;///< Item Count uint16_t in;///< Incoming Item Index uint16_t out;///< Outgoing Item Index void **data;///< Queue Data } isr_queue; struct{ ///< ISR Post Processing functions void (*thread)(osRtxThread_t*);///< Thread Post Processing function void (*event_flags)(osRtxEventFlags_t*);///< Event Flags Post Processing function void (*semaphore)(osRtxSemaphore_t*);///< Semaphore Post Processing function void (*memory_pool)(osRtxMemoryPool_t*);///< Memory Pool Post Processing function void (*message_queue)(osRtxMessage_t*);///< Message Queue Post Processing function } post_process; struct{ ///< Memory Pools (Variable Block Size) void *stack;///< Stack Memory void *mp_data;///< Memory Pool Data Memory void *mq_data;///< Message Queue Data Memory void *common;///< Common Memory } mem; struct{ ///< Memory Pools (Fixed Block Size) osRtxMpInfo_t *stack; ///< Stack for Threads osRtxMpInfo_t *thread; ///< Thread Control Blocks osRtxMpInfo_t *timer; ///< Timer Control Blocks osRtxMpInfo_t *event_flags; ///< Event Flags Control Blocks osRtxMpInfo_t *mutex; ///< Mutex Control Blocks osRtxMpInfo_t *semaphore; ///< Semaphore Control Blocks osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks } mpi; } osRtxInfo_t; externosRtxInfo_t osRtxInfo; ///< OS Runtime Information // ==== OS API definitions ==== /// Object Limits definitions #define osRtxThreadFlagsLimit 31U///< number of Thread Flags available per thread #define osRtxEventFlagsLimit 31U///< number of Event Flags available per object #define osRtxMutexLockLimit 255U///< maximum number of recursive mutex locks #define osRtxSemaphoreTokenLimit 65535U///< maximum number of tokens per semaphore /// Control Block sizes #define osRtxThreadCbSize sizeof(osRtxThread_t) #define osRtxTimerCbSize sizeof(osRtxTimer_t) #define osRtxEventFlagsCbSize sizeof(osRtxEventFlags_t) #define osRtxMutexCbSize sizeof(osRtxMutex_t) #define osRtxSemaphoreCbSize sizeof(osRtxSemaphore_t) #define osRtxMemoryPoolCbSize sizeof(osRtxMemoryPool_t) #define osRtxMessageQueueCbSize sizeof(osRtxMessageQueue_t) /// Memory size in bytes for Memory Pool storage. /// \param block_count maximum number of memory blocks in memory pool. /// \param block_size memory block size in bytes. #define osRtxMemoryPoolMemSize(block_count, block_size) \ (4*(block_count)*(((block_size)+3)/4)) /// Memory size in bytes for Message Queue storage. /// \param msg_count maximum number of messages in queue. /// \param msg_size maximum message size in bytes. #define osRtxMessageQueueMemSize(msg_count, msg_size) \ (4*(msg_count)*(3+(((msg_size)+3)/4))) // ==== OS External Functions ==== /// OS Error Codes #define osRtxErrorStackUnderflow 1U #define osRtxErrorISRQueueOverflow 2U #define osRtxErrorTimerQueueOverflow 3U #define osRtxErrorClibSpace 4U #define osRtxErrorClibMutex 5U /// OS Error Callback function extern uint32_tosRtxErrorNotify (uint32_t code, void *object_id); /// OS Idle Thread externvoid osRtxIdleThread (void *argument); /// OS Exception handlers externvoid SVC_Handler (void); externvoid PendSV_Handler (void); externvoid SysTick_Handler (void); /// OS System Timer functions (default implementation uses SysTick) /// Setup System Timer. /// \return system timer IRQ number. extern int32_tosRtxSysTimerSetup (void); /// Enable System Timer. externvoid osRtxSysTimerEnable (void); /// Disable System Timer. externvoid osRtxSysTimerDisable (void); /// Acknowledge System Timer IRQ. externvoid osRtxSysTimerAckIRQ (void); /// Get System Timer count. /// \return system timer count. extern uint32_tosRtxSysTimerGetCount (void); /// Get System Timer frequency. /// \return system timer frequency. extern uint32_tosRtxSysTimerGetFreq (void); // ==== OS External Configuration ==== /// OS Configuration flags #define osRtxConfigPrivilegedMode (1UL<<0)///< Threads in Privileged mode #define osRtxConfigStackCheck (1UL<<1)///< Stack overrun checking #define osRtxConfigStackWatermark (1UL<<2)///< Stack usage Watermark /// OS Configuration structure typedefstruct { uint32_t flags; ///< OS Configuration Flags uint32_t tick_freq;///< Kernel Tick Frequency uint32_t robin_timeout;///< Round Robin Timeout Tick struct{ ///< ISR Post Processing Queue void **data;///< Queue Data uint16_t max;///< Maximum Items uint16_t padding; } isr_queue; struct{ ///< Memory Pools (Variable Block Size) void *stack_addr;///< Stack Memory Address uint32_t stack_size;///< Stack Memory Size void *mp_data_addr;///< Memory Pool Memory Address uint32_t mp_data_size;///< Memory Pool Memory Size void *mq_data_addr;///< Message Queue Data Memory Address uint32_t mq_data_size;///< Message Queue Data Memory Size void *common_addr;///< Common Memory Address uint32_t common_size;///< Common Memory Size } mem; struct{ ///< Memory Pools (Fixed Block Size) osRtxMpInfo_t *stack; ///< Stack for Threads osRtxMpInfo_t *thread; ///< Thread Control Blocks osRtxMpInfo_t *timer; ///< Timer Control Blocks osRtxMpInfo_t *event_flags; ///< Event Flags Control Blocks osRtxMpInfo_t *mutex; ///< Mutex Control Blocks osRtxMpInfo_t *semaphore; ///< Semaphore Control Blocks osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks } mpi; uint32_t thread_stack_size; ///< Default Thread Stack Size const osThreadAttr_t *idle_thread_attr; ///< Idle Thread Attributes const osThreadAttr_t *timer_thread_attr; ///< Timer Thread Attributes const osMessageQueueAttr_t *timer_mq_attr; ///< Timer Message Queue Attributes uint32_t timer_mq_mcnt;///< Timer Message Queue maximum Messages }osRtxConfig_t; externconst osRtxConfig_t osRtxConfig; ///< OS Configuration #ifdef __cplusplus } #endif #endif // RTX_OS_H_