簡 介
Azure RTOS ThreadX 是 Microsoft 提供的高級工業(yè)級實時操作系統(tǒng) (RTOS)。它是專門為深度嵌入式實時 IoT 應(yīng)用程序設(shè)計的。Azure RTOS ThreadX 提供高級計劃、通信、同步、計時器、內(nèi)存管理和中斷管理功能。此外,Azure RTOS ThreadX 具有許多高級功能,包括 picokernel 體系結(jié)構(gòu)、preemption-threshold 計劃、event-chaining、執(zhí)行分析、性能指標(biāo)和系統(tǒng)事件跟蹤。Azure RTOS ThreadX 非常易于使用,適用于要求極其苛刻的嵌入式應(yīng)用程序。Azure RTOS ThreadX 在各種產(chǎn)品(包括消費者設(shè)備、醫(yī)療電子設(shè)備和工業(yè)控制設(shè)備)上的部署次數(shù)已達數(shù)十億次。
在前文描述移植基本內(nèi)核的基礎(chǔ)上,該應(yīng)用手冊描述了MM32F3270系列MCU結(jié)合Azure RTOS ThreadX定時器組的使用,引導(dǎo)用戶理解Azure RTOS ThreadX應(yīng)用程序計時器功能。
表 1 適用系列型號
系列 | 芯片型號 | 開發(fā)板 |
MM32F3270 | MM32F3273G9P | EVB-F3270 |
1移植應(yīng)用的準(zhǔn)備
1.1 硬件開發(fā)板的準(zhǔn)備
該移植過程中應(yīng)用的開發(fā)板為MM32的EVB-F3270,板載MM32F3273G9P。
EVB-F3270 (MM32F3273G9P) 的簡要參數(shù):
Arm Cortex-M3 內(nèi)核
板載 MM32F3273G9P(LQFP144)
4 x Key、4 x LED
I2S Speaker
TF-Card
Ethernet PHY
1.2 軟件的準(zhǔn)備
庫函數(shù)和例程(Lib Samples)
該移植過程中應(yīng)用的 Firmware 分別為 MM32F3270 庫函數(shù)和例程。
? ??
Azure RTOS ThreadX(源碼)
ThreadX 的源代碼已經(jīng)開放,我們可以從 ThreadX 公共源代碼存儲庫獲取 Azure RTOS ThreadX,網(wǎng)址為:
https://github.com/azure-rtos/threadx/
Azure RTOS 何時需要許可證?
Microsoft 將 Azure RTOS 源代碼發(fā)布到 GitHub。安裝和使用該軟件進行內(nèi)部開發(fā)、測試和評估無需許可證。分發(fā)或銷售組件和設(shè)備需要許可證,除非使用 Azure RTOS 許可的硬件。
ThreadX 安裝
可以通過將 GitHub 存儲庫克隆到本地計算機來安裝 ThreadX。下面是用于在 PC 上創(chuàng)建 ThreadX 存儲庫的克隆的典型語法。
shell復(fù)制
git clone https://github.com/azure-rtos/threadx
或者,也可以使用 GitHub 主頁上的“下載”按鈕來下載存儲庫的副本。
下載后的倉庫代碼目錄列表如下:
? ?
Azure RTOS ThreadX(源碼)支持的開發(fā)環(huán)境
ThreadX 內(nèi)核提供好了各種主流硬件平臺和軟件平臺的移植文件,以Cortex_M3為例,可以支持以下六種開發(fā)環(huán)境:
本次移植過程使用Azure RTOS原有的sample_threadx.c文件為例,稍作修改,演示定時器組功能。
2ThreadX定時器組的應(yīng)用
該章節(jié)介紹動態(tài)內(nèi)存管理相關(guān)知識,演示程序可在MM32F3273G9P的EVB-F3270上運行。此示例在文件 main_timer_demo.c 中實現(xiàn),旨在說明如何在嵌入式多線程環(huán)境中使用定時器組功能。
2.1 定時器組
2.1.1 應(yīng)用程序計時器
快速響應(yīng)異步外部事件是嵌入式實時應(yīng)用程序中最重要的功能。但是,其中的許多應(yīng)用程序還必須按預(yù)定的時間間隔執(zhí)行某些活動。
借助 ThreadX 應(yīng)用程序計時器,應(yīng)用程序能夠按特定的時間間隔執(zhí)行應(yīng)用程序 C 函數(shù)。應(yīng)用程序計時器也可能只過期一次。這種類型的計時器稱為“單次計時器”,而重復(fù)間隔計時器稱為“定期計時器”。
每個應(yīng)用程序計時器都是一個公用資源。ThreadX 對如何使用應(yīng)用程序計時器沒有任何限制。
2.1.2 計時器間隔
在 ThreadX 中,時間間隔通過定期計時器中斷來測量。每個計時器中斷稱為計時器時鐘周期。計時器時鐘周期之間的實際時間由應(yīng)用程序指定,但 10 毫秒是大多數(shù)實現(xiàn)的標(biāo)準(zhǔn)時間。定期計時器設(shè)置通常位于 tx_initialize_low_level 程序集文件中。
值得一提的是,基礎(chǔ)硬件必須能夠生成定期中斷,應(yīng)用程序計時器才會正常運行。在某些情況下,處理器具有內(nèi)置的定期中斷功能。如果處理器沒有此功能,用戶的主板必須包含可生成定期中斷的外圍設(shè)備。
即使沒有定期中斷源,ThreadX 仍可正常工作。但隨后會禁用所有與計時器相關(guān)的處理。這包括時間切片、掛起超時和計時器服務(wù)。
2.1.3 計時器準(zhǔn)確性
計時器過期時間根據(jù)時鐘周期指定。達到每個計時器時鐘周期時,指定到期值將減一。由于應(yīng)用程序計時器可在計時器中斷(或計時器時鐘周期)之前啟用,因此,實際過期時間可能會提前一個時鐘周期。
如果計時器時鐘周期速率為 10 毫秒,應(yīng)用程序計時器可能會提前 10 毫秒過期。與 1 秒計時器相比,這對 10 毫秒計時器更重要。當(dāng)然,增加計時器中斷頻率會減少此誤差范圍。
2.1.4 計時器執(zhí)行
應(yīng)用程序計時器按照其激活的順序執(zhí)行。例如,如果創(chuàng)建了三個具有相同過期值的計時器并已激活,這些計時器對應(yīng)的過期函數(shù)將保證按它們激活的順序執(zhí)行。
2.1.5 創(chuàng)建應(yīng)用程序計時器
應(yīng)用程序計時器由應(yīng)用程序線程在初始化期間或運行時創(chuàng)建。應(yīng)用程序中應(yīng)用程序計時器的數(shù)量沒有限制。
2.1.6 運行時應(yīng)用程序計時器性能信息
ThreadX 提供可選的運行時應(yīng)用程序計時器性能信息。如果 ThreadX 庫和應(yīng)用程序是在定義 TX_TIMER_ENABLE_PERFORMANCE_INFO 的情況下生成的,ThreadX 會累積以下信息。
整個系統(tǒng)的總數(shù):
激活數(shù)
停用數(shù)
重新激活(定期計時器)
expirations
過期調(diào)整數(shù)
每個應(yīng)用程序計時器的總數(shù):
激活數(shù)
停用數(shù)
重新激活(定期計時器)
expirations
過期調(diào)整數(shù)
此信息在運行時通過 tx_timer_performance_info_get 和 tx_timer_performance_system_info_get 服務(wù)提供。應(yīng)用程序計時器性能信息在確定應(yīng)用程序是否正常運行時非常有用。此信息對于優(yōu)化應(yīng)用程序也很有用。
2.1.7 應(yīng)用程序計時器控制塊 TX_TIMER
每個應(yīng)用程序計時器的特征都可在其控制塊中找到。該控制塊包含諸如 32 位過期標(biāo)識值等有用信息。此結(jié)構(gòu)在 tx_api.h 文件中定義。
應(yīng)用程序計時器控制塊可以位于內(nèi)存中的任意位置,但最常見的是通過在任何函數(shù)的作用域外部定義該控件塊來使其成為全局結(jié)構(gòu)。
2.1.8 計時器過多
默認情況下,應(yīng)用程序計時器在優(yōu)先級為 0 時運行的隱藏系統(tǒng)線程中執(zhí)行,該線程的優(yōu)先級通常比任何應(yīng)用程序線程都高。因此,在應(yīng)用程序計時器內(nèi)進行處理應(yīng)保持最小值。
如果可能,還應(yīng)盡可能避免使用在每個時鐘周期過期的計時器。這種情況可能導(dǎo)致應(yīng)用程序的開銷過大。
如前所述,應(yīng)用程序計時器在隱藏的系統(tǒng)線程中執(zhí)行。因此,請不要在應(yīng)用程序計時器的過期函數(shù)內(nèi)執(zhí)行任何 ThreadX 服務(wù)調(diào)用時選擇掛起。
2.1.9 相對時間
除了前面所述的應(yīng)用程序計時器,ThreadX 還提供單個連續(xù)遞增的 32 位時鐘周期計數(shù)器。每次發(fā)生計時器中斷時,時鐘周期計數(shù)器或時間就會加一。
應(yīng)用程序可以通過分別調(diào)用 tx_time_get 和 tx_time_set 來讀取或設(shè)置此 32 位計數(shù)器。此時鐘周期計數(shù)器的使用完全由應(yīng)用程序確定。ThreadX 不在內(nèi)部使用此計時器。
2.2 Azure ThreadX 定時器組的相關(guān)函數(shù)
tx_timer_create 創(chuàng)建應(yīng)用程序計時器
UINTtx_timer_create( TX_TIMER*timer_ptr, CHAR*name_ptr, VOID(*expiration_function)(ULONG), ULONGexpiration_input, ULONGinitial_ticks, ULONGreschedule_ticks, UINTauto_activate);
說明
此服務(wù)創(chuàng)建具有指定過期函數(shù)和定期的應(yīng)用程序計時器。
參數(shù)
timer_ptr:
指向計時器控制塊的指針。
name_ptr:
指向計時器名稱的指針。
expiration_function:
在計時器過期時要調(diào)用的應(yīng)用程序函數(shù)。
expiration_input:
在計時器過期時要傳遞到過期函數(shù)的輸入。
initial_ticks:
指定計時器過期的初始時鐘周期數(shù)。合法值的范圍為 1 至 0xFFFFFFFF。
reschedule_ticks:
指定第一個計時器過期后所有計時器過期的時鐘周期數(shù)。如果此參數(shù)為 0,則計時器是一次性的。否則,對于周期性計時器,合法值的范圍為 1 至 0xFFFFFFFF。
備注
一次性計時器過期后,必須通過 tx_timer_change 將其重置,然后才能再次激活。
auto_activate:
確定創(chuàng)建期間是否自動激活計時器。如果此值為 TX_AUTO_ACTIVATE (0x01),則激活計時器。否則,如果選擇了值 TX_NO_ACTIVATE (0x00),則所創(chuàng)建的計時器處于非活動狀態(tài)。在這種情況下,隨后需要調(diào)用 tx_timer_activate 服務(wù)來實際啟動計時器。
返回值
TX_SUCCESS:
(0X00) 成功創(chuàng)建應(yīng)用程序計時器。
TX_TIMER_ERROR:
(0X15) 應(yīng)用程序計時器指針無效。指針為 NULL 或已創(chuàng)建計時器。
TX_TICK_ERROR:
(0x16) 為初始時鐘周期提供的值無效(零)。
TX_ACTIVATE_ERROR:
(0x17) 選擇的激活無效。
NX_CALLER_ERROR:
(0x13) 此服務(wù)的調(diào)用方無效。
示例
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 定時器組的應(yīng)用演示
2.3.1 工程目錄的建立
打開目標(biāo)工程文件夾“MM32F3270Project”:
移除原有樣例.c 文件sample_threadx.c:
參考sample_threadx.c建立main_timer_demo.c文件,并添加hardware目錄中的led.c、key.c到工程項目中。
3ThreadX的定時器組應(yīng)用
3.1 代碼實現(xiàn)
下載調(diào)試默認會運行到main()函數(shù),如下為全部實現(xiàn)的代碼。
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 下載與調(diào)試
運行程序,板載LED1閃爍,表示當(dāng)前系統(tǒng)正在運行。
觀察LED2間隔1s閃爍。
程序中創(chuàng)建定時器組,設(shè)置溢出周期為1000ms,在定時器回調(diào)函數(shù)中配置LED2引腳翻轉(zhuǎn),激活定時器。當(dāng)計時周期到時,LED2引腳翻轉(zhuǎn),運行現(xiàn)象是LED2間隔1s閃爍,Demo演示成功。
4小結(jié)
Azure RTOS ThreadX提供定時器組能夠使應(yīng)用程序按照特定的時間間隔執(zhí)行,結(jié)合MM32F3270的強大性能,可以實現(xiàn)Azure RTOS廣泛的應(yīng)用場景。
審核編輯:湯梓紅
-
threadx
+關(guān)注
關(guān)注
0文章
15瀏覽量
13864 -
定時器
+關(guān)注
關(guān)注
23文章
3255瀏覽量
115368 -
RTOS
+關(guān)注
關(guān)注
22文章
819瀏覽量
119885 -
開發(fā)板
+關(guān)注
關(guān)注
25文章
5121瀏覽量
98191 -
Azure
+關(guān)注
關(guān)注
1文章
124瀏覽量
12809
原文標(biāo)題:靈動微課堂 (第242講)|使用MM32F3270基于Azure RTOS定時器組的應(yīng)用
文章出處:【微信號:MindMotion-MMCU,微信公眾號:靈動MM32MCU】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論