天天看點

RTX v5學習

https://arm-software.github.io/CMSIS_5/RTOS2/html/rtx5_impl.html

RTX v5熟悉

1.RTX5 工程建立

2. RTX5特性:啟動方法、記憶體管理、排程、中斷等。

3.新特性整理

1)keil rtx調試方法:system and thread viewer、Event Viewer

2)rtx配置項說明:System Configuration、Thread Configuration、Timer Configuration等

3)SVC:當os需要操作硬體時,可使用svc産生軟中斷操作。

4)特權與非特權:任務支援特權通路,通過配置CONTOL,核心外設MPU,NVIC, SCB 和 STK,具體檢視權威手冊,确定是否需要特權模式下才能通路。

5)os不提供臨界段和中斷鎖

6)Tick-less Low-Power Operation(低功耗機制):滴答時鐘不使能,osKernelSuspend擷取空閑時間,控制rtc喚醒時間,然後通過osKernelResume校準恢複。

7)零中斷延時,ISR的中斷相應時間和沒有使用RTX系統一樣(RTX核心庫無關閉中斷的操作,見第5點)。

8)Freertos的中斷優先級必須在freertos的優先級定義範圍内才可以使用安全函數,RTX無此限制。

9)注意事項:

1、任務棧空間必須 8 位元組對齊, 可以将任務棧數組定義成 uint64_t 類型即可

2、使用者線程不要操作NVIC,一定要改變可通過SVC方式操作。

http://www.keil.com/pack/doc/CMSIS/RTOS2/html/rtx5_impl.html

https://blog.csdn.net/qq_29350001/article/details/81630311 systick實作us延時

調試方法

RTX v5學習

system and thread viewer

RTX v5學習

Timer Number: 0 表示使用晶片的滴答定時器, 1 表示使用外設定時器。

Tick Timer: RTX 的時鐘節拍周期。

Roud Robin Timeout:時間片溢出時間, 即時間片排程時任務配置設定的時間片大小。

Stack Size:任務棧大小,機關位元組。

Stack Overflow Check: 設定是否支援棧溢出檢測。

Tack Usage: 任務建立情況, Available 表示可以建立的最大任務數, Used 表示實際建立的。

User Timers:軟體定時器個數,Available 表示可以建立的最大任個數,Used 表示實際建立的個數。

下面是任務部分功能介紹:

ID:任務的 ID 标示。

Name:任務的函數名。

Priority: 任務優先級。

State:任務狀态。

Delay: 任務延遲時間。

Event Value: 任務目前的事件标志數值。

Event Mask: 任務等待的事件标志數值。

Event Viewer

硬體需要SWO引腳支援

RTX v5學習

RTX配置

RTX_Config.h

RTX v5學習

System Configuration

RTX v5學習
Name #define Description
Global Dynamic Memory size [bytes] OS_DYNAMIC_MEM_SIZE Defines the combined global dynamic memory size for the Global Memory Pool. Default value is 4096. Value range is [0-1073741824] bytes, in multiples of 8 bytes.
Kernel Tick Frequency (Hz) OS_TICK_FREQ Defines base time unit for delays and timeouts in Hz. Default: 1000Hz = 1ms period.
Round-Robin Thread switching OS_ROBIN_ENABLE Enables Round-Robin Thread switching. 選擇是否使能時間片排程,選上單選框表示使能時間片排程,取消單選框表示不使用時間片排程
Round-Robin Timeout OS_ROBIN_TIMEOUT Defines how long a thread will execute before a thread switch. Default value is 5. Value range is [1-1000]. 表示時間片的大小, 機關是系統時鐘節拍個數
ISR FIFO Queue OS_ISR_FIFO_QUEUE RTOS Functions called from ISR store requests to this buffer. Default value is 16 entries. Value range is [4-256] entries in multiples of 4. 表示 ISR FIFO 隊列大小。 中斷服務程式中調用以 isr_ 開頭的函數時,會将請求類型存到此緩沖中 ,以便在中斷處理程式退出後稍後進行處理。
Object Memory usage counters OS_OBJ_MEM_USAGE Enables object memory usage counters to evaluate the maximum memory pool requirements individually for each RTOS object type. 使能對象記憶體使用情況計數器,分别評估每種RTOS對象類型的最大記憶體池要求。

Thread Configuration

RTX v5學習
Option #define Description
Object specific Memory allocation OS_THREAD_OBJ_MEM Enables object specific memory allocation. See Object-specific Memory Pools.
Number of user Threads OS_THREAD_NUM Defines maximum number of user threads that can be active at the same time. Applies to user threads with system provided memory for control blocks. Default value is 1. Value range is [1-1000].
Number of user Threads with default Stack size OS_THREAD_DEF_STACK_NUM Defines maximum number of user threads with default stack size and applies to user threads with 0 stack size specified. Value range is [0-1000].
Total Stack size [bytes] for user Threads with user-provided Stack size OS_THREAD_USER_STACK_SIZE Defines the combined stack size for user threads with user-provided stack size. Default value is 0. Value range is [0-1073741824] Bytes, in multiples of 8.
Default Thread Stack size [bytes] OS_STACK_SIZE Defines stack size for threads with zero stack size specified. Default value is 200. Value range is [96-1073741824] Bytes, in multiples of 8.
Idle Thread Stack size [bytes] OS_IDLE_THREAD_STACK_SIZE Defines stack size for Idle thread. Default value is 200. Value range is [72-1073741824] bytes, in multiples of 8.
Idle Thread TrustZone Module ID OS_IDLE_THREAD_TZ_MOD_ID Defines the TrustZone Module ID the Idle Thread shall use. This needs to be set to a non-zero value if the Idle Thread need to call secure functions. Default value is 0. 定義空閑線程将使用的TrustZone子產品ID。 如果空閑線程需要調用安全功能,則需要将其設定為非零值。 預設值為0。
Stack overrun checking OS_STACK_CHECK Enable stack overrun checks at thread switch.
Stack usage watermark OS_STACK_WATERMARK Initialize thread stack with watermark pattern for analyzing stack usage. Enabling this option increases significantly the execution time of thread creation. 建立線程時,RTX5用水印圖案(0xCC)初始化線程堆棧。 這使調試器可以确定每個線程的最大堆棧使用率,通常在開發期間使用。 啟用此選項會大大增加osThreadNew的執行時間(取決于線程堆棧的大小)。
Processor mode for Thread execution OS_PRIVILEGE_MODE Controls the processor mode. Default value is Privileged mode. Value range is [0=Unprivileged; 1=Privileged] mode. RTX5允許以非特權或特權處理器模式執行線程。 在非特權處理器模式下,應用程式軟體: 對MSR和MRS指令的通路受到限制,并且不能使用CPS指令。 無法通路system timer, NVIC, or system control block.。 可能限制了對記憶體或外圍裝置的通路權限。 在特權處理器模式下,應用程式軟體可以使用所有指令,并可以通路所有資源。

OS_THREAD_NUM = 6

OS_THREAD_DEF_STACK_NUM = 0

表示所有6個線程使用的堆棧空間大小為OS_THREAD_USER_STACK_SIZE。

OS_THREAD_NUM = 6

OS_THREAD_DEF_STACK_NUM = 1

表示所有5個線程使用的堆棧空間大小為OS_THREAD_USER_STACK_SIZE,1個線程使用的堆棧空間大小為OS_STACK_SIZE。

Timer Configuration

RTX v5學習
Name #define Description
Object specific Memory allocation OS_TIMER_OBJ_MEM Enables object specific memory allocation.
Number of Timer objects OS_TIMER_NUM Defines maximum number of objects that can be active at the same time. Applies to objects with system provided memory for control blocks. Value range is [1-1000].
Timer Thread Priority OS_TIMER_THREAD_PRIO Defines priority for timer thread. Default value is 40. Value range is [8-48], in multiples of 8. The numbers have the following priority correlation: 8=Low; 16=Below Normal; 24=Normal; 32=Above Normal; 40=High; 48=Realtime
Timer Thread Stack size [bytes] OS_TIMER_THREAD_STACK_SIZE Defines stack size for Timer thread. May be set to 0 when timers are not used. Default value is 200. Value range is [0-1073741824], in multiples of 8.
Timer Thread TrustZone Module ID OS_TIMER_THREAD_TZ_MOD_ID Defines the TrustZone Module ID the Timer Thread shall use. This needs to be set to a non-zero value if any Timer Callbacks need to call secure functions. Default value is 0.
Timer Callback Queue entries OS_TIMER_CB_QUEUE Number of concurrent active timer callback functions. May be set to 0 when timers are not used. Default value is 4. Value range is [0-256].

Event Flags Configuration

中斷可以使用的系統函數

osKernelGetInfo, osKernelGetState, osKernelGetTickCount, osKernelGetTickFreq, osKernelGetSysTimerCount, osKernelGetSysTimerFreq      
osThreadGetId, osThreadFlagsSet      
osEventFlagsSet, osEventFlagsClear, osEventFlagsGet, osEventFlagsWait      
osSemaphoreAcquire, osSemaphoreRelease, osSemaphoreGetCount      
osMemoryPoolAlloc, osMemoryPoolFree, osMemoryPoolGetCapacity, osMemoryPoolGetBlockSize, osMemoryPoolGetCount, osMemoryPoolGetSpace      
osMessageQueuePut, osMessageQueueGet, osMessageQueueGetCapacity, osMessageQueueGetMsgSize, osMessageQueueGetCount, osMessageQueueGetSpace      

記憶體管理

  • Global Memory Pool uses a single global memory pool for all objects. It is easy to configure, but may have the disadvantage for memory fragmentation when objects with different sizes are created and destroyed.
  • Object-specific Memory Pools uses a fixed-size memory pool for each object type. The method is time deterministic and avoids memory fragmentation.每個object使用
  • Static Object Memory reserves memory during compile time and completely avoids that a system can be out of memory. This is typically a required for some safety critical systems.

SVC

當os需要操作硬體時,使用svc産生軟中斷,防止使用者程式直接通路硬體。

SVC在Arm Cortex-M核心的特權處理程式模式下運作。 SVC函數接受參數并可以傳回值。這些功能的使用方式與其他功能相同;但是,它們是通過SVC指令間接執行的。執行SVC指令時,控制器将切換到特權處理程式模式。

在此模式下不禁止中斷。為了保護SVC函數免受中斷影響,需要在代碼中包含禁用/啟用内部函數__disable_irq()和__enable_irq()

使用SVC功能通路受保護的外圍裝置,例如,配置NVIC和中斷。

注意事項:

1、任務棧空間必須 8 位元組對齊, 可以将任務棧數組定義成 uint64_t 類型即可

2、NVIC在任務啟動後,不要修改。

3、任務棧是8位元組對齊。

差別:

支援任務特權通路,了解特權與非特權通路機制(contorl),系統架構更加安全和健壯,MSP 、PSP

無臨界斷:比如此時某個任務正在調用系統 API 函數,而且此時中斷正好關閉了,也就是進入到了臨界區中,這個時候如果有一個緊急的中斷事件被觸發,這個中斷就不能得到及時執行,必須等到中斷開啟才可以得到執行,如果關中斷時間超過了緊急中斷能夠容忍的限度,危害是可想而知的。 像 uCOS-II, uCOS-III 和 FreeRTOS 的源碼中都是有臨界段的

無中段鎖:作業系統未提供開關中斷函數,按照裸機方式操作

任務鎖:防止目前執行的任務被高優先級的任務打斷,有兩種方法,給排程器加鎖或者關閉RTOS核心定時器,RTX通過關閉核心定時器方式實作的

Tick-less Low-Power Operation:無滴答時鐘時的低功耗模式,osKernelSuspend和osKernelResume,比如通過rtc控制喚醒。

RTX5提供了無滴答操作的擴充,這對于使用廣泛的低功耗模式(同時也禁用了SysTick計時器)的應用很有用。為了在這種省電模式下提供時間間隔,喚醒定時器用于導出定時器間隔。 CMSIS-RTOS2函數osKernelSuspend和osKernelResume控制無滴答操作。

使用此功能,RTX5線程排程程式可以停止定期的核心滴答中斷。當所有活動線程都挂起時,系統進入掉電狀态并計算在此掉電模式下可以停留多長時間。在掉電模式下,可以關閉處理器和外圍裝置。隻有喚醒定時器必須保持通電,因為該定時器負責在掉電時間到期後喚醒系統。

無滴答操作由osRtxIdleThread線程控制。喚醒逾時值是在系統進入掉電模式之前設定的。函數osKernelSuspend計算以RTX計時器計時為機關的喚醒逾時。此值用于設定在系統掉電模式下運作的喚醒定時器。

一旦系統恢複操作(通過喚醒逾時或其他中斷),則RTX5線程排程程式将使用osKernelResume函數啟動。參數sleep_time指定系統處于掉電模式的時間(以RTX計時器為機關)。

#include "msp.h"                        // Device header      
/*----------------------------------------------------------------------------      
*      MSP432 Low-Power Extension Functions      
*---------------------------------------------------------------------------*/      
static void 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);        
}      
static volatile unsigned int tc;      
static volatile 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;      
void osRtxIdleThread (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();      
__WFE();      
}      
/* Adjust the kernel ticks with the amount of ticks slept */      
osKernelResume (tc);      
}      
}      

參考

安富萊RTX教程

繼續閱讀