“RTX_Config.h”文件。定义了CMSIS-RTOS RTX的配置参数,每一个使用CMSIS-RTOS RTX内核的项目的都必须有这个文件。下面几节将详细解释各个配置选项。
“RTX_Config文件”。包含空闲任务(osRtxIdleThread) 和异常报告函数(osRtxErrorNotify) 的默认实现。他们可以在用户代码中被重新定义。
配置文件使用 配置向导(Configuration Wizard Annotations)。窗口下方的注释让图形化界面操作更加友好。下图显示了在MDK5.29里打开的配置向导界面:
System Configuration
系统配置包括全局动态内存池、时钟节拍、ISR事件缓冲区和使能循环调度的任务调度算法 的系统层面的配置。
Name | #define | Description |
---|---|---|
Global Dynamic Memory size [bytes] | OS_DYNAMIC_MEM_SIZE | 为 全局内存池(Global Memory Pool) 定义全局动态内存大小。默认值是4096。值范围为[0-1073741824]字节,为8字节的倍数 |
Kernel Tick Frequency (Hz) | OS_TICK_FREQ | 系统节拍 的频率,决定了 时间片 的最小计量单元,单位HZ。1000Hz = 1ms的周期。 |
Round-Robin Thread switching | OS_ROBIN_ENABLE | 选择是否使能 循环调度。 |
Round-Robin Timeout | OS_ROBIN_TIMEOUT | 表示时间片的大小,单位是系统时钟节拍个数。默认值是5。取值范围为[1-1000]。 |
ISR FIFO Queue | OS_ISR_FIFO_QUEUE | 表示 ISR FIFO 队列大小。中断服务程序中调用以isr_ 开头的函数时,会将请求类型存到此缓冲中。默认值是16个条目(entries)。值范围是[4-256],4的倍数。 |
Object Memory usage counters | OS_OBJ_MEM_USAGE | 使能 对象内存使用计数器,用于单独计算每个RTOS对象类型的最大内存池需求。 |
时钟节拍: CPU以一定的频率进行中断,可以看成操作系统的心跳。利用时间节拍可以做到一些任务的时间管理,延时、定时、超时检测、时间片轮转调度。即时钟节拍的周期是系统总线周期的若干倍。时钟节拍频率越高,对系统的负担就越大。
时间片: 循环调度时,线程获得一个时间片的运行时间。也就是在同一优先级下,每个任务运行的时间,这个时间是 时钟节拍 的倍数。时间片过长,线程切换不及时,会造成资源利用率低;时间片过短,会造成频繁的任务切换,导致系统开销变大。
Round-Robin Thread Switching
RTX5 可以使用 循环(Round-Robin)调度算法 来处理多任务切换。Round-Robin 可以让多个 相同优先级 的线程 近似同时(quasi-parallel) 执行。
线程并不是同时执行的,而是将可用的 CPU 时间轴划分为时间片,一个时间片内只运行一种用户线程(不发生高优先级抢占的情况下)。因为时间片通常很短(只有几毫秒),所以看起来好像线程是同时执行的。
循环调度流程如下:
换句话说就是,一个线程在一个时间片内执行。当前时间片结束时,RTX切换到下一个 优先级相同 且 处于就绪状态 的线程。如果没有其他具有相同优先级的线程准备运行,则继续执行当前运行的线程。
请注意:
当切换到高优先级线程时,计数值(tick) 将被重置为 循环超时值(timeout value)。
是否开启 循环调度 由 #define OS_ROBIN_ENABLE 控制。时间片长度 可在“RTX_Config.h”中使用 #define OS_ROBIN_TIMEOUT 配置
ISR FIFO Queue
ISR(Interrupt Service Routines),中断服务函数。
IRQ(Interrupt Request),中断请求
当在中断中调用RTX函数时,系统会把请求类型和可选参数存储到 ISR FIFO 队列缓冲区中,以便在退出中断后进行处理。
当IRQ中断处理(IRQ handler)完成了处理存储在FIFO队列缓冲区中的消息之后,将立即激活调度器。这个缓冲区所需的大小取决于在中断服务函数中调用的函数的数量。osRtxErrorNotify将使用错误代码osRtxErrorISRQueueOverflow来捕获不足的队列大小。
Object Memory Usage Counters
对象内存使用计数器有助于评估每种对象类型的最大内存池需求,就像堆栈水印用于线程一样。初始化设置从全局内存池开始。
在启用 对象内存使用计数器 的情况下连续运行应用程序,有助于为每种对象类型引入 对象特定的内存池 。通常,这对于需要功能性安全认证的应用程序是必需的,因为在这种情况下不允许使用全局内存池
Thread Configuration
RTX5提供了几个参数来配置线程管理功能。
Option | #define | Description |
---|---|---|
Object specific Memory allocation | OS_THREAD_OBJ_MEM | 是否启用对象特定内存分配。 |
Number of user Threads | OS_THREAD_NUM | 定义可以同时运行的最大用户线程数。适用于系统为控制块提供内存的用户线程。默认值是1。值范围是[1-1000] |
Number of user Threads with default Stack size | OS_THREAD_DEF_STACK_NUM | 定义使用默认堆栈大小的线程数,取0则表示所有线程都不使用默认大小而使用自定义堆栈大小。取值范围为[0-1000]。 |
Total Stack size [bytes] for user Threads with user-provided Stack size | OS_THREAD_USER_STACK_SIZE | 用户自定义堆栈大小的用户线程的总堆栈大小[字节]。默认值为0。值范围为[0-1073741824]字节,为8的倍数。 |
Default Thread Stack size [bytes] | OS_STACK_SIZE | 默认线程堆栈的大小,用户未提供堆栈大小时使用此参数。默认值是200。值范围为[96-1073741824]字节,为8的倍数。 |
Idle Thread Stack size [bytes] | OS_IDLE_THREAD_STACK_SIZE | 定义空闲线程的堆栈大小。默认值是200。值范围为[72-1073741824]字节,以8为倍数。 |
Idle Thread TrustZone Module ID | OS_IDLE_THREAD_TZ_MOD_ID | 定义空闲线程应该使用的 TrustZone Module ID。如果空闲线程需要调用安全函数,则需要将该值设置为非零值。默认值为0。 |
Stack overrun checking | OS_STACK_CHECK | 启用线程切换处的堆栈溢出检查。 |
Stack usage watermark | OS_STACK_WATERMARK | 使用水印模式初始化线程堆栈,以分析堆栈使用情况。启用此选项会显著增加线程创建的执行时间。 |
Processor mode for Thread execution | OS_PRIVILEGE_MODE | 选择处理器模式。默认值是特权模式。取值范围为[0=无特权;1 =特权)模式。 |
Configuration of Thread Count and Stack Space
RTX5内核为每个线程使用一个单独的堆栈空间,并提供了两种定义堆栈需求的方法:
osThreadAttr_t 是 osThreadNew() 的一个参数。
Stack Overflow Checking
RTX5实现了一个软件堆栈溢出检查(software stack overflow checking),可以捕获堆栈溢出。堆栈(Stack),是用于暂存返回地址和自动变量的空间。堆栈配置不合理可能导致堆栈溢出。是否开启软件堆栈溢出检查由宏定义 OS_STACK_CHECK 决定。
如果检测到堆栈溢出,系统将调用函数 osRtxErrorNotify() ,函数参数为错误代码 osRtxErrorStackUnderflow 。默认情况下,这个函数被实现为一个无限循环,会终止代码执行。
Stack Usage Watermark
RTX5在创建线程时使用水印模式(0xCC)初始化线程堆栈。这允许调试器确定每个线程的最大堆栈使用量。它通常在开发期间使用,然后在最终程序中删除。是否开启堆栈水印由宏定义OS_STACK_WATERMARK 决定。
启用此选项将显著增加 osThreadNew() 的执行时间(取决于线程堆栈大小)。
Processor Mode for Thread Execution
RTX5允许以非特权或特权处理器模式执行线程。处理器模式由 OS_PRIVILEGE_MODE 决定。
在非特权处理模式下,应用软件:
在特权处理器模式下,应用程序软件可以使用所有指令并访问所有资源。
Timer Configuration
Name | #define | Description |
---|---|---|
Object specific Memory allocation | OS_TIMER_OBJ_MEM | 使能 对象特定内存分配(Object specific Memory allocation) |
Number of Timer objects | OS_TIMER_NUM | 代表可以同时运行的最大用户定时器数。适用于系统为控制块提供内存的用户定时器。默认值是 1 。值范围是 [1-1000]。 |
Timer Thread Priority | OS_TIMER_THREAD_PRIO | 表示定时器线程的优先级。默认值是 40。取值范围为 [8-48],取 8的倍数。这些数字的优先级相关如下: 8=低;16 =低于正常;24 =正常;32 =高于正常;40 =高;48 =实时 |
Timer Thread Stack size [bytes] | OS_TIMER_THREAD_STACK_SIZE | 定义计时器线程的堆栈大小。当不使用计时器时,可以将其设置为 0。默认值是 200。取值范围为 [0-1073741824],取 8的倍数。 |
Timer Callback Queue entries | OS_TIMER_CB_QUEUE | 定时器回调函数可以同时运行的最大数目。当不使用计时器时,可以将其设置为 0。默认值是 4。取值范围为 [0-256]。 |
Timer Thread TrustZone Module ID | OS_TIMER_THREAD_TZ_MOD_ID | 定义空闲线程应该使用的 TrustZone Module ID。如果空闲线程需要调用安全函数,则需要将该值设置为非零值。默认值为0。 |
User Timer Thread
当一个时间片结束时,函数osRtxTimerThread执行回调函数。完整RTOS系统中的计时器子系统的优先级继承自 osRtxTimerThread 的优先级。这是由 OS_TIMER_THREAD_PRIO 配置的。回调函数的堆栈由 osRtxTimerThread 提供。OS_TIMER_THREAD_STACK_SIZE必须满足具有最高堆栈使用率的回调函数的堆栈要求。
Event Flags Configuration
RTX5提供了几个参数来配置 事件标志(Event Flags) 功能。
Name | #define | Description |
---|---|---|
Object specific Memory allocation | OS_EVFLAGS_OBJ_MEM | 启用对象特定的内存分配。 |
Number of Event Flags objects | OS_EVFLAGS_NUM | 定义同时活跃的最大事件标记数。适用于系统为控制块提供内存的控制块。取值范围为[1-1000]。 |
Object-specific memory allocation
当使用对象特定内存时,所有 事件标记对象(Event object) 的内存池大小由OS_EVFLAGS_NUM指定。
Mutex Configuration
Name | #define | Description |
---|---|---|
Object specific | Memory allocation | OS_MUTEX_OBJ_MEM |
Number of Mutex objects | OS_MUTEX_NUM | 定义可以同时活动的最大对象数。应用于系统为控制块提供内存的对象。取值范围为 [1-1000]。 |
Object-specific Memory Allocation
当使用对象特定内存时,所有 互斥量对象(Mutex object) 的内存池大小由 OS_MUTEX_NUM 指定。
Name | #define | Description |
---|---|---|
Object specific Memory allocation | OS_SEMAPHORE_OBJ_MEM | 启用对象特定的内存分配。 |
Number of Semaphore objects | OS_SEMAPHORE_NUM | 定义可以同时活动的最大信号量数目。应用于系统为控制块提供内存的对象。取值范围为 [1-1000]。 |
Object-specific Memory Allocation
当使用对象特定内存时,所有 信号量对象(Semaphore object) 的内存池大小由 OS_SEMAPHORE_NUM 指定。
Memory Pool Configuration
Name | #define | Description |
---|---|---|
Object specific Memory allocation | OS_MEMPOOL_OBJ_MEM | 启用特定于对象的内存分配。 |
Number of Memory Pool objects | OS_MEMPOOL_NUM | 定义可以同时活动的最大对象数。应用于系统为控制块提供内存的对象。取值范围为 [1-1000]。 |
Data Storage Memory size [bytes] | OS_MEMPOOL_DATA_SIZE | 定义了总体数据存储内存大小。应用于系统为数据存储提供内存的对象。默认值为 0。取值范围为 [0-1073741824],取 8 的倍数。 |
Object-specific memory allocation
当使用 对象特定的内存(object-specific memory) 时,所有 内存池对象(MemoryPool) 的数量由 OS_MEMPOOL_NUM 指定。所有内存池的存储总量大小由 OS_MEMPOOL_DATA_SIZE 中配置。
Message Queue Configuration
Name | #define | Description |
---|---|---|
Object specific Memory allocation | OS_MSGQUEUE_OBJ_MEM | 启用特定对象的内存分配。 |
Number of Message Queue objects | OS_MSGQUEUE_NUM | 定义可以同时活动的最大对象数。应用于系统为控制块提供内存的对象。取值范围为 [1-1000]。 |
Data Storage Memory size [bytes] | OS_MSGQUEUE_DATA_SIZE | 定义了所有信号量的内存容量总大小。应用于系统为数据存储提供内存的对象。默认值为 0。取值范围为 [0-1073741824],取 8 的倍数。 |
Object-specific memory allocation
当使用对象特定的内存时,所有 消息队列对象( Message Queue objects) 的数量由 OS_MSGQUEUE_NUM 指定。所有队列的总存储容量在 OS_MSGQUEUE_DATA_SIZE 中配置。
Event Recorder Configuration