簡 介
Azure RTOS ThreadX 是 Microsoft 提供的高級工業級實時操作系統 (RTOS)。它是專門為深度嵌入式實時 IoT 應用程序設計的。Azure RTOS ThreadX 提供高級計劃、通信、同步、計時器、內存管理和中斷管理功能。此外,Azure RTOS ThreadX 具有許多高級功能,包括 picokernel 體系結構、preemption-threshold 計劃、event-chaining、執行分析、性能指標和系統事件跟蹤。Azure RTOS ThreadX 非常易于使用,適用于要求極其苛刻的嵌入式應用程序。Azure RTOS ThreadX 在各種產品(包括消費者設備、醫療電子設備和工業控制設備)上的部署次數已達數十億次。
在前文描述移植基本內核的基礎上,該應用手冊描述了MM32F3270系列MCU結合Azure RTOS ThreadX定時器組的使用,引導用戶理解Azure RTOS ThreadX應用程序計時器功能。
表 1 適用系列型號
系列 | 芯片型號 | 開發板 |
MM32F3270 | MM32F3273G9P | EVB-F3270 |
1移植應用的準備
1.1 硬件開發板的準備
該移植過程中應用的開發板為MM32的EVB-F3270,板載MM32F3273G9P。
EVB-F3270 (MM32F3273G9P) 的簡要參數:
Arm Cortex-M3 內核
板載 MM32F3273G9P(LQFP144)
4 x Key、4 x LED
I2S Speaker
TF-Card
Ethernet PHY
1.2 軟件的準備
庫函數和例程(Lib Samples)
該移植過程中應用的 Firmware 分別為 MM32F3270 庫函數和例程。
? ??
Azure RTOS ThreadX(源碼)
ThreadX 的源代碼已經開放,我們可以從 ThreadX 公共源代碼存儲庫獲取 Azure RTOS ThreadX,網址為:
https://github.com/azure-rtos/threadx/
Azure RTOS 何時需要許可證?
Microsoft 將 Azure RTOS 源代碼發布到 GitHub。安裝和使用該軟件進行內部開發、測試和評估無需許可證。分發或銷售組件和設備需要許可證,除非使用 Azure RTOS 許可的硬件。
ThreadX 安裝
可以通過將 GitHub 存儲庫克隆到本地計算機來安裝 ThreadX。下面是用于在 PC 上創建 ThreadX 存儲庫的克隆的典型語法。
shell復制
git clone https://github.com/azure-rtos/threadx
或者,也可以使用 GitHub 主頁上的“下載”按鈕來下載存儲庫的副本。
下載后的倉庫代碼目錄列表如下:
? ?
Azure RTOS ThreadX(源碼)支持的開發環境
ThreadX 內核提供好了各種主流硬件平臺和軟件平臺的移植文件,以Cortex_M3為例,可以支持以下六種開發環境:
本次移植過程使用Azure RTOS原有的sample_threadx.c文件為例,稍作修改,演示定時器組功能。
2ThreadX定時器組的應用
該章節介紹動態內存管理相關知識,演示程序可在MM32F3273G9P的EVB-F3270上運行。此示例在文件 main_timer_demo.c 中實現,旨在說明如何在嵌入式多線程環境中使用定時器組功能。
2.1 定時器組
2.1.1 應用程序計時器
快速響應異步外部事件是嵌入式實時應用程序中最重要的功能。但是,其中的許多應用程序還必須按預定的時間間隔執行某些活動。
借助 ThreadX 應用程序計時器,應用程序能夠按特定的時間間隔執行應用程序 C 函數。應用程序計時器也可能只過期一次。這種類型的計時器稱為“單次計時器”,而重復間隔計時器稱為“定期計時器”。
每個應用程序計時器都是一個公用資源。ThreadX 對如何使用應用程序計時器沒有任何限制。
2.1.2 計時器間隔
在 ThreadX 中,時間間隔通過定期計時器中斷來測量。每個計時器中斷稱為計時器時鐘周期。計時器時鐘周期之間的實際時間由應用程序指定,但 10 毫秒是大多數實現的標準時間。定期計時器設置通常位于 tx_initialize_low_level 程序集文件中。
值得一提的是,基礎硬件必須能夠生成定期中斷,應用程序計時器才會正常運行。在某些情況下,處理器具有內置的定期中斷功能。如果處理器沒有此功能,用戶的主板必須包含可生成定期中斷的外圍設備。
即使沒有定期中斷源,ThreadX 仍可正常工作。但隨后會禁用所有與計時器相關的處理。這包括時間切片、掛起超時和計時器服務。
2.1.3 計時器準確性
計時器過期時間根據時鐘周期指定。達到每個計時器時鐘周期時,指定到期值將減一。由于應用程序計時器可在計時器中斷(或計時器時鐘周期)之前啟用,因此,實際過期時間可能會提前一個時鐘周期。
如果計時器時鐘周期速率為 10 毫秒,應用程序計時器可能會提前 10 毫秒過期。與 1 秒計時器相比,這對 10 毫秒計時器更重要。當然,增加計時器中斷頻率會減少此誤差范圍。
2.1.4 計時器執行
應用程序計時器按照其激活的順序執行。例如,如果創建了三個具有相同過期值的計時器并已激活,這些計時器對應的過期函數將保證按它們激活的順序執行。
2.1.5 創建應用程序計時器
應用程序計時器由應用程序線程在初始化期間或運行時創建。應用程序中應用程序計時器的數量沒有限制。
2.1.6 運行時應用程序計時器性能信息
ThreadX 提供可選的運行時應用程序計時器性能信息。如果 ThreadX 庫和應用程序是在定義 TX_TIMER_ENABLE_PERFORMANCE_INFO 的情況下生成的,ThreadX 會累積以下信息。
整個系統的總數:
激活數
停用數
重新激活(定期計時器)
expirations
過期調整數
每個應用程序計時器的總數:
激活數
停用數
重新激活(定期計時器)
expirations
過期調整數
此信息在運行時通過 tx_timer_performance_info_get 和 tx_timer_performance_system_info_get 服務提供。應用程序計時器性能信息在確定應用程序是否正常運行時非常有用。此信息對于優化應用程序也很有用。
2.1.7 應用程序計時器控制塊 TX_TIMER
每個應用程序計時器的特征都可在其控制塊中找到。該控制塊包含諸如 32 位過期標識值等有用信息。此結構在 tx_api.h 文件中定義。
應用程序計時器控制塊可以位于內存中的任意位置,但最常見的是通過在任何函數的作用域外部定義該控件塊來使其成為全局結構。
2.1.8 計時器過多
默認情況下,應用程序計時器在優先級為 0 時運行的隱藏系統線程中執行,該線程的優先級通常比任何應用程序線程都高。因此,在應用程序計時器內進行處理應保持最小值。
如果可能,還應盡可能避免使用在每個時鐘周期過期的計時器。這種情況可能導致應用程序的開銷過大。
如前所述,應用程序計時器在隱藏的系統線程中執行。因此,請不要在應用程序計時器的過期函數內執行任何 ThreadX 服務調用時選擇掛起。
2.1.9 相對時間
除了前面所述的應用程序計時器,ThreadX 還提供單個連續遞增的 32 位時鐘周期計數器。每次發生計時器中斷時,時鐘周期計數器或時間就會加一。
應用程序可以通過分別調用 tx_time_get 和 tx_time_set 來讀取或設置此 32 位計數器。此時鐘周期計數器的使用完全由應用程序確定。ThreadX 不在內部使用此計時器。
2.2 Azure ThreadX 定時器組的相關函數
tx_timer_create 創建應用程序計時器
UINTtx_timer_create( TX_TIMER*timer_ptr, CHAR*name_ptr, VOID(*expiration_function)(ULONG), ULONGexpiration_input, ULONGinitial_ticks, ULONGreschedule_ticks, UINTauto_activate);
說明
此服務創建具有指定過期函數和定期的應用程序計時器。
參數
timer_ptr:
指向計時器控制塊的指針。
name_ptr:
指向計時器名稱的指針。
expiration_function:
在計時器過期時要調用的應用程序函數。
expiration_input:
在計時器過期時要傳遞到過期函數的輸入。
initial_ticks:
指定計時器過期的初始時鐘周期數。合法值的范圍為 1 至 0xFFFFFFFF。
reschedule_ticks:
指定第一個計時器過期后所有計時器過期的時鐘周期數。如果此參數為 0,則計時器是一次性的。否則,對于周期性計時器,合法值的范圍為 1 至 0xFFFFFFFF。
備注
一次性計時器過期后,必須通過 tx_timer_change 將其重置,然后才能再次激活。
auto_activate:
確定創建期間是否自動激活計時器。如果此值為 TX_AUTO_ACTIVATE (0x01),則激活計時器。否則,如果選擇了值 TX_NO_ACTIVATE (0x00),則所創建的計時器處于非活動狀態。在這種情況下,隨后需要調用 tx_timer_activate 服務來實際啟動計時器。
返回值
TX_SUCCESS:
(0X00) 成功創建應用程序計時器。
TX_TIMER_ERROR:
(0X15) 應用程序計時器指針無效。指針為 NULL 或已創建計時器。
TX_TICK_ERROR:
(0x16) 為初始時鐘周期提供的值無效(零)。
TX_ACTIVATE_ERROR:
(0x17) 選擇的激活無效。
NX_CALLER_ERROR:
(0x13) 此服務的調用方無效。
示例
TX_TIMERmy_timer; UINTstatus; /*Createanapplicationtimerthatexecutes "my_timer_function"after100ticksinitiallyandthen afterevery25ticks.Thistimerisspecifiedtostart immediately!*/ status=tx_timer_create(&my_timer,"my_timer_name", my_timer_function,0x1234,100,25, TX_AUTO_ACTIVATE); /*IfstatusequalsTX_SUCCESS,my_timer_functionwill becalled100timertickslaterandthencalledevery 25timerticks.Notethatthevalue0x1234ispassedto my_timer_functioneverytimeitiscalled.*/
另請參閱
tx_timer_activate
tx_timer_change
tx_timer_deactivate
tx_timer_delete
tx_timer_info_get
tx_timer_performance_info_get
tx_timer_performance_system_info_get
2.3 定時器組的應用演示
2.3.1 工程目錄的建立
打開目標工程文件夾“MM32F3270Project”:
移除原有樣例.c 文件sample_threadx.c:
參考sample_threadx.c建立main_timer_demo.c文件,并添加hardware目錄中的led.c、key.c到工程項目中。
3ThreadX的定時器組應用
3.1 代碼實現
下載調試默認會運行到main()函數,如下為全部實現的代碼。
Demo演示代碼
/*Thisisasmalldemoofthehigh-performanceThreadXkernel.Itincludesexamplesofsix threadsofdifferentpriorities,usingamessagequeue,semaphore,andaneventflagsgroup.*/ #include"tx_api.h" #include"delay.h" #include"led.h" #include"key.h" #include"uart.h" #defineDEMO_STACK_SIZE1024 #defineTHREAD0_PRIORITY1 #defineTHREAD0_PREEMPTION_THRESHOLD1 /*DefinetheThreadXobjectcontrolblocks...*/ TX_THREADthread_0; TX_TIMERMyTimer; /*Definethecountersusedinthedemoapplication...*/ ULONGthread_0_counter; /*Definethethreadstacks.*/ UCHARthread_0_stack[DEMO_STACK_SIZE]; /*Definethreadprototypes.*/ voidthread_0_entry(ULONGthread_input); volatileunsignedintbootloop; voidSystem_Init(void); voidAppThreadCreate(void); voidAppModuleCreate(void); /*Definemainentrypoint.*/ intmain() { System_Init(); /*EntertheThreadXkernel.*/ tx_kernel_enter(); } /*Definewhattheinitialsystemlookslike.*/ voidtx_application_define(void*first_unused_memory) { AppThreadCreate(); AppModuleCreate(); } voidSystem_Init(void) { DELAY_Init();//cannotusesystick LED_Init(); KEY_Init(); CONSOLE_Init(115200); printf("!!!Start!!! "); } voidAppThreadCreate(void) { /*Createthread0.*/ tx_thread_create( &thread_0, "thread0", thread_0_entry, 0, thread_0_stack, DEMO_STACK_SIZE, THREAD0_PRIORITY, THREAD0_PREEMPTION_THRESHOLD, TX_NO_TIME_SLICE, TX_AUTO_START); } voidAppModuleCreate(void) { /*Createatimergroup.*/ tx_timer_create(&MyTimer, "MyTimer", TimerCallback, 0,/*Theparameterspassed*/ 100,/*Settheinitialdelayfortimertimeoverflow*/ 1000,/*Setthetimerrunperiodaftertheinitialdelay*/ TX_AUTO_ACTIVATE);/*Activatethetimer*/ } /*Thecallbackfunctionforthetimergroup.*/ voidTimerCallback(ULONGthread_input) { LED2_TOGGLE(); } /*Definethetestthreads.*/ voidthread_0_entry(ULONGthread_input) { /*ThisthreadsimplycontrolsLEDflashingtoindicatethatthesystemisrunning*/ while(1) { /*Incrementthethreadcounter.*/ thread_0_counter++; LED1_TOGGLE(); /*Sleepfor300ticks.*/ tx_thread_sleep(300); } }
3.2 下載與調試
運行程序,板載LED1閃爍,表示當前系統正在運行。
觀察LED2間隔1s閃爍。
程序中創建定時器組,設置溢出周期為1000ms,在定時器回調函數中配置LED2引腳翻轉,激活定時器。當計時周期到時,LED2引腳翻轉,運行現象是LED2間隔1s閃爍,Demo演示成功。
4小結
Azure RTOS ThreadX提供定時器組能夠使應用程序按照特定的時間間隔執行,結合MM32F3270的強大性能,可以實現Azure RTOS廣泛的應用場景。
審核編輯:湯梓紅
-
threadx
+關注
關注
0文章
17瀏覽量
13984 -
定時器
+關注
關注
23文章
3274瀏覽量
116878 -
RTOS
+關注
關注
24文章
837瀏覽量
120628 -
開發板
+關注
關注
25文章
5432瀏覽量
101224 -
Azure
+關注
關注
1文章
125瀏覽量
13149
原文標題:靈動微課堂 (第242講)|使用MM32F3270基于Azure RTOS定時器組的應用
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
MM32F3270系列32位MCU的特點有哪些
使用MM32F3270基于Azure RTOS定時器組的應用
靈動微電子MM32F3270系列MCU的特點介紹
MM32F3270控制器的主要特點
基于MM32F3270 以太網 Client使用

評論