本文介绍CMSIS-RTOS2。
1.引入
CMSIS-RTOS2在基于Arm Cortex处理器的设备上运行的实时操作系统内核上指定了通用RTOS接口。应用程序和中间件组件可以使用CMSIS-RTOS2 API在各种软件生态系统中实现更好的代码重用和更简单的集成。
CMSIS-RTOS2还指定了RTOS内核使用的标准OS Tick接口。它提供了几个操作系统tick实现,用于将简单的内核移植到不同的Cortex-M和Cortex-A处理器。
CMSIS-RTOS2在软件层次中的位置如下图(浅蓝色部分)。
目前支持的主流RTOS Kernel:
1)RTX(Keil)
2)FreeRTOS
3)Zephyr RTOS
4)Micrium OS
2.主要接口
关于CMSIS-RTOS2的接口(API)可参考网址:CMSIS-RTOS2: API Reference
下面简要介绍CMSIS-RTOS2中常用的接口(API),按如下类别进行划分。
1)线程管理
通常将一个复杂的任务划分为若干个独立的线程,每个独立的线程完成一定的功能。
创建:
osThreadId_t osThreadNew(osThreadFunc_t func,
void *argument,
const osThreadAttr_t *attr
)
切换:
用于同等优先级任务切换。
osStatus_t osThreadYield(void)
挂起:
osStatus_t osThreadSuspend(osThreadId_t thread_id)
恢复:
osStatus_t osThreadResume(osThreadId_t thread_id)
终止:
osStatus_t osThreadTerminate(osThreadId_t thread_id)
2)线程间同步
a)信号量
用于多个任务协作,或访问某一临界资源时。
创建:
osSemaphoreId_t osSemaphoreNew(uint32_t max_count,
uint32_t initial_count,
const osSemaphoreAttr_t *attr
)
获取:
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id,
uint32_t timeout
)
释放:
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
b)互斥量
互斥量相当于单值型信号量,用于临界资源的互斥访问,区别于单值型信号量,其在优先级反转方面有特殊的处理。
创建:
osMutexId_t osMutexNew(const osMutexAttr_t *attr)
请求:
osStatus_t osMutexAcquire(osMutexId_t mutex_id,
uint32_t timeout
)
释放:
osStatus_t osMutexRelease(osMutexId_t mutex_id)
c)事件集
事件集主要用于线程间的同步,与信号量不同,它的特点是可以实现一对多,多对多的同步。即多个事件可以实现“或”或“与”的运算。另外,事件的发送操作在事件未清除前,是不可累计的,而信号量的释放时累计的。
创建:
osEventFlagsId_t osEventFlagsNew(const osEventFlagsAttr_t *attr)
设置:
uint32_t osEventFlagsSet(osEventFlagsId_t ef_id,
uint32_t flags
)
其中,flags为某一位或几位,如:((1 << 2) | (1 << 3)),表示将第2位和第3位置位。
清除:
uint32_t osEventFlagsClear(osEventFlagsId_t ef_id,
uint32_t flags
)
等待:
uint32_t osEventFlagsWait(osEventFlagsId_t ef_id,
uint32_t flags,
uint32_t options,
uint32_t timeout
)
等待的信号被置位后,默认会被自动清零,若想手动清零,可设置“options”参数。
3)线程间通信
线程间通信这里仅有消息队列。
创建:
osMessageQueueId_t osMessageQueueNew(uint32_t msg_count,
uint32_t msg_size,
const osMessageQueueAttr_t *attr
)
发送:
osStatus_t osMessageQueuePut(osMessageQueueId_t mq_id,
const void *msg_ptr,
uint8_t msg_prio,
uint32_t timeout
)
接收:
osStatus_t osMessageQueueGet(osMessageQueueId_t mq_id,
void *msg_ptr,
uint8_t *msg_prio,
uint32_t timeout
)
4)时钟管理
休眠:
让出处理器资源,进入就绪状态,同时进行一次调度,选出当前优先级最高的任务执行。
osStatus_t osDelay(uint32_t ticks)
等绝对时间:
osStatus_t osDelayUntil(uint32_t ticks)
获取系统Tick:
uint32_t osKernelGetTickCount(void)
返回为无符号32位数,注意溢出问题。
获取系统定时器计数:
uint32_t osKernelGetSysTimerCount(void)
返回为无符号32位数,这里是定时器的计数值,相对于“获取系统Tick”更精细一些。
5)中断管理
涉及中断和任务之间的临界资源的访问(注意和互斥量之间的区别)。
若使用FreeRTOS,可用如下宏:
taskENTER_CRITICAL()
taskEXIT_CRITICAL()
taskENTER_CRITICAL_FROM_ISR()
taskEXIT_CRITICAL_FROM_ISR(x)
总结,本文介绍了CMSIS-RTOS2。