CMSIS-RTOS2

发布于 2022-04-12  25 次阅读


通用RTOS接口

CMSIS-RTOS2是一个通用的API,它与底层的RTOS内核无关。 程序员在用户代码中调用CMSIS-RTOS2 API函数,以确保从一个RTOS到另一个RTOS的最大可移植性。 使用CMSIS-RTOS2 API的中间件避免不必要的移植工作。

典型的CMSIS-RTOS2 API实现与现有的实时内核接口。  CMSIS-RTOS2 API提供以下属性和功能:



● 线程管理允许您定义,创建和控制线程。
● 中断服务程序(ISR)可以调用一些CMSIS-RTOS功能。 当不能从ISR上下文调用CMSIS-RTOS函数时,它拒            绝调用并返回错误代码。
● 三种不同的事件类型支持多线程和/或ISR之间的通信:
● 线程标志:可用于指示线程的特定条件。
● 事件标志:可用于向线程或ISR指示事件。
● 消息:可以发送到线程或ISR。 邮件缓冲在队列中。
● 互斥管理和信号量被并入。
● 可以使用以下功能安排CPU时间:
● 许多CMSIS-RTOS功能中并入超时参数,以避免系统锁定。 当指定超时时,系统等待,直到资源可用或                    事件发生。 在等待时,其他线程被安排。
● osDelay和osDelayUntil函数将线程置于WAITING状态一段指定的时间。
● osThreadYield提供合作的线程切换,并将执行传递给同一优先级的另一个线程。
● 定时器管理功能用于触发功能的执行。

CMSIS-RTOS2 API旨在通过Cortex-M存储器保护单元(MPU)可选地并入多处理器系统和/或访问保护。


在一些RTOS实现中,线程可以在不同的处理器上执行,因此消息队列可以驻留在共享存储器资源中。


CMSIS-RTOS2 API鼓励软件行业发展现有的RTOS实现。 对于Cortex-M处理器,RTOS实现可以在不同方面进行不同和优化。 可选功能可能是例如
● 支持Cortex-M存储器保护单元(MPU)。
● 支持多处理器系统。
● 支持DMA控制器。
● 确定性上下文切换。
● 循环上下文切换。
● 防止死锁,例如优先级倒置。
● 通过使用ARMv7-M指令LDREX和STREX来实现零中断延迟。

使用CMSIS-RTOS2实现

CMSIS-RTOS2实现通常作为库提供。 要将RTOS功能添加到现有的基于CMSIS的应用程序,需要添加RTOS库(通常是一个或多个配置文件)。 有一个新的头文件cmsis_os2.h可用。 这是完全便携式应用程序所需的唯一头文件。 在这种情况下,用户提供的控制块存储器,对象数据和线程堆栈不能使用。 或者,您可以包括实现特定的头文件(例如rtx_os.h),它还为资源分配(例如控制块的大小,对象数据和线程堆栈所需的内存)提供定义。 这是可选的,意味着应用程序代码不是完全可移植的。

将文件添加到项目中后,用户可以开始使用CMSIS-RTOS功能。 以下提供代码示例:

/*----------------------------------------------------------------------------
  * CMSIS-RTOS 'main' function template
  *---------------------------------------------------------------------------*/ 
  #include "RTE_Components.h"
  #include CMSIS_device_header
  #include "cmsis_os2.h" 
  /*----------------------------------------------------------------------------
  * Application main thread
  *---------------------------------------------------------------------------*/
  void app_main (void *argument) {
  // ...
  for (;;) {}
 
  }
  int main (void) {
 
  // System Initialization
  SystemCoreClockUpdate();
  #ifdef RTE_Compiler_EventRecorder
  // Initialize and start Event Recorder
  EventRecorderInitialize(EventRecordError, 1U);
  #endif
  // ...
  osKernelInitialize(); // Initialize CMSIS-RTOS
  osThreadNew(app_main, NULL, NULL); // Create application main thread
  osKernelStart(); // Start thread execution
  for (;;) {}
  }

概述在cmsis_os2.h头文件中实现的所有CMSIS-RTOS C API v2函数。

内核信息和控制

  • osKernelGetInfo:获取RTOS内核信息。
  • osKernelGetState:获取当前的RTOS内核状态。
  • osKernelGetSysTimerCount:获取RTOS内核系统定时器计数。
  • osKernelGetSysTimerFreq:获取RTOS内核系统的定时器频率。
  • osKernelInitialize:初始化RTOS内核。
  • osKernelLock:锁定RTOS内核调度程序。
  • osKernelUnlock:解锁RTOS内核调度程序。
  • osKernelRestoreLock:恢复RTOS内核调度器锁定状态。
  • osKernelResume:恢复RTOS内核调度程序。
  • osKernelStart:启动RTOS内核调度程序。
  • osKernelSuspend:挂起RTOS内核调度程序。
  • osKernelGetTickCount:获取RTOS内核计数。
  • osKernelGetTickFreq:获取RTOS内核滴答频率。

线程管理

  • osThreadDetach:分离线程(线程终止时可以回收线程存储)。
  • osThreadEnumerate:枚举活动线程。
  • osThreadExit:终止执行当前正在运行的线程。
  • osThreadGetCount:获取活动线程的数量。
  • osThreadGetId:返回当前正在运行的线程的线程ID。
  • osThreadGetName:获取线程的名称。
  • osThreadGetPriority:获取线程的当前优先级。
  • osThreadGetStackSize:获取线程的堆栈大小。
  • osThreadGetStackSpace:在执行期间基于堆栈水印记录获取线程的可用堆栈空间。
  • osThreadGetState:获取当前线程的线程状态。
  • osThreadJoin:等待指定的线程终止。
  • osThreadNew:创建一个线程并将其添加到Active Threads。
  • osThreadResume:恢复执行线程。
  • osThreadSetPriority:更改线程的优先级。
  • osThreadSuspend:挂起一个线程的执行。
  • osThreadTerminate:终止线程的执行。
  • osThreadYield:将控件传递到状态为READY的下一个线程。

线程标志

  • osThreadFlagsSet:设置线程的指定线程标志。
  • osThreadFlagsClear:清除当前正在运行的线程的指定线程标志。
  • osThreadFlagsGet:获取当前正在运行的线程的当前Thread Flags。
  • osThreadFlagsWait:等待当前正在运行的线程的一个或多个线程标志变为信号。

事件标志

  • osEventFlagsGetName:获取Event Flags对象的名称。
  • osEventFlagsNew:创建并初始化事件标志对象。
  • osEventFlagsDelete:删除事件标志对象。
  • osEventFlagsSet:设置指定的事件标志。
  • osEventFlagsClear:清除指定的事件标志。
  • osEventFlagsGet:获取当前的事件标志。
  • osEventFlagsWait:等待一个或多个事件标志变为信号。

通用等待功能

  • osDelay:等待超时(延时)。
  • osDelayUntil:等到指定的时间。

计时器管理

  • osTimerDelete:删除一个计时器。
  • osTimerGetName:获取计时器的名称。
  • osTimerIsRunning:检查一个计时器是否正在运行。
  • osTimerNew:创建并初始化定时器。
  • osTimerStart:启动或重启定时器。
  • osTimerStop:停止定时器

互斥管理

  • osMutexAcquire:如果被锁定,则获取互斥量或超时。
  • osMutexDelete:删除一个Mutex对象。
  • osMutexGetName:获取Mutex对象的名称。
  • osMutexGetOwner:获取拥有Mutex对象的线程。
  • osMutexNew:创建和初始化一个Mutex对象。
  • osMutexRelease:释放由osMutexAcquire获取的Mutex。

信号量

  • osSemaphoreAcquire:如果没有令牌可用,则获取信号量令牌或超时。
  • osSemaphoreDelete:删除一个信号量对象。
  • osSemaphoreGetCount:获取当前的信号量令牌计数。
  • osSemaphoreGetName:获取信号量对象的名称。
  • osSemaphoreNew:创建和初始化一个信号量对象。
  • osSemaphoreRelease:释放由osSemaphoreAcquire获取的信号量令牌。

内存池

  • osMemoryPoolAlloc:从内存池分配一个内存块。
  • osMemoryPoolDelete:删除内存池对象。
  • osMemoryPoolFree:将分配的内存块返回到内存池。
  • osMemoryPoolGetBlockSize:在内存池中获取内存块大小。
  • osMemoryPoolGetCapacity:获取内存池中的最大内存块数。
  • osMemoryPoolGetCount:获取内存池中使用的内存块数。
  • osMemoryPoolGetName:获取内存池对象的名称。
  • osMemoryPoolGetSpace:获取内存池中可用的内存块数。
  • osMemoryPoolNew:创建和初始化内存池对象。

消息队列

  • osMessageQueueDelete:删除消息队列对象。
  • osMessageQueueGet:如果Queue为空,则从队列获取消息或超时。
  • osMessageQueueGetCapacity:获取消息队列中的最大消息数。
  • osMessageQueueGetCount:获取消息队列中排队消息的数量。
  • osMessageQueueGetMsgSize:在内存池中获取最大消息大小。
  • osMessageQueueGetName:获取消息队列对象的名称。
  • osMessageQueueGetSpace:获取消息队列中消息的可用插槽数。
  • osMessageQueueNew:创建和初始化消息队列对象。
  • osMessageQueuePut:如果队列已满,则将消息放入队列或超时。
  • osMessageQueueReset:将消息队列重置为初始空状态。

RTX5具体API

  • osRtxErrorNotify:操作系统错误回调函数。
  • osRtxIdleThread:操作系统空闲线程。
  • osRtxSysTimerSetup:OS系统定时器功能(默认实现使用SysTick)
  • osRtxSysTimerEnable:启用系统定时器。
  • osRtxSysTimerDisable:禁用系统定时器。
  • osRtxSysTimerAckIRQ:确认系统定时器IRQ。
  • osRtxSysTimerGetCount:获取系统计时器计数。
  • osRtxSysTimerGetFreq:获取系统定时器频率。

可以从线程和中断服务程序(ISR)调用以下CMSIS-RTOS2函数:


一沙一世界,一花一天堂。君掌盛无边,刹那成永恒。