技能的學(xué)習(xí)首先就要不求甚解,先用起來(lái)再學(xué)習(xí)原理。學(xué)習(xí)RTOS亦是如此,不能一開(kāi)始就埋進(jìn)源碼中。這篇主要講怎么快速在STM32系列單片機(jī)上用起來(lái)FreeRTOS,并順帶著說(shuō)一下自學(xué)的方法及資料查找。
01
說(shuō)在前面
RTOS為了提高任務(wù)調(diào)度效率一般都包含匯編程序,因此移植起來(lái)需要一些匯編知識(shí),就算網(wǎng)上肯定有移植教程,初次搞起來(lái)還是挺費(fèi)勁的。初學(xué)時(shí)對(duì)RTOS代碼不熟悉,一開(kāi)始就打擊了積極性可不好。因此本篇不講怎么移植,介紹使用ST“懶人神器”CubeMX來(lái)快速移植配置FreeRTOS。
02
RTOS介紹
目前嵌入式主流RTOS有uCOS、FreeRTOS,之所以很多第三方庫(kù)都有在FreeRTOS上的應(yīng)用Demo,是因?yàn)镕reeRTOS免費(fèi)。不要錢(qián)是真的厲害呀!然而說(shuō)實(shí)話(huà),論源碼規(guī)范,我還是喜歡uCOS。FreeRTOS的匈牙利命名法真是讓我難受呀~~~
03
配置CubeMX
設(shè)計(jì)實(shí)驗(yàn):配置CubeMX移植FreeRTOS,建立兩個(gè)任務(wù),一個(gè)讓LED0以500ms亮滅,一個(gè)讓LED1以200ms亮滅。
比較本實(shí)驗(yàn)和前面《消除硬延時(shí)函數(shù)Delay》的編程方式,體會(huì)引入操作系統(tǒng)后軟件編程架構(gòu)的變化。
第一步
首先如1處勾選使用FreeRTOS的enable。然后將HAL庫(kù)的1ms定時(shí)中斷采用的定時(shí)器改為T(mén)IM1,因?yàn)镾ystick要用作FreeRTOS的時(shí)基定時(shí)。第三步配置IO口。忘記怎么配置的溫故《STM32CubeMX入門(mén)教程(一)》。
第二步
配置FreeRTOS。點(diǎn)擊FREERTOS按鈕。
配置界面如下,通過(guò)配置界面可以實(shí)現(xiàn)操作系統(tǒng)的配置、任務(wù)的配置、隊(duì)列、信號(hào)量及內(nèi)存管理的配置。
ConfigParameters:配置操作系統(tǒng)功能,就像手動(dòng)移植時(shí)修改Config文件一樣,基本上可以按默認(rèn)值。具體每個(gè)配置的功能,可以點(diǎn)擊該條目,底部會(huì)有相關(guān)介紹。
IncludeParameters:配置操作系統(tǒng)API,一些API不常用可以不使能編譯,減小系統(tǒng)大小。這個(gè)也對(duì)應(yīng)與移植時(shí)的Config文件。例如刪除任務(wù)函數(shù)vTaskDelete()是否使能就在此配置。具體如下圖:
UserConstants:添加一些用戶(hù)使用的常量,很少用。
TaskAndQueues:任務(wù)及隊(duì)列的配置。首先說(shuō)任務(wù)配置,點(diǎn)擊ADD,彈出配置對(duì)話(huà)框。TaskName是任務(wù)名稱(chēng),一個(gè)字符串而已。下面是優(yōu)先級(jí)配置,再往下是任務(wù)堆棧大小。EntryFunction是任務(wù)函數(shù)名。CodeGenerationOption是選擇自動(dòng)生成代碼是否聲明成weak。Allocation是配置內(nèi)存是否動(dòng)態(tài)分配,此處CUbeMX默認(rèn)動(dòng)態(tài)分配不給更改。
之后再看一下隊(duì)列的創(chuàng)建。如下圖,點(diǎn)擊ADD,彈出配置對(duì)話(huà)框。首先是隊(duì)列名稱(chēng)。QueueSize是隊(duì)列長(zhǎng)度,即包含的隊(duì)列項(xiàng)個(gè)數(shù)。ItemSIze是隊(duì)列項(xiàng)類(lèi)型。
TimersAndSemaphores:即軟件定時(shí)器及信號(hào)量的配置,界面如下圖。Timer處的ADD按鈕不能點(diǎn)擊,因?yàn)槲覀冊(cè)谂渲脮r(shí)未使能軟件定時(shí)器功能。從上到下依次是:軟件定時(shí)器、互斥信號(hào)量、遞歸信號(hào)量、二值信號(hào)量、計(jì)數(shù)信號(hào)量。
最后看一下堆棧及內(nèi)存管理。
FreeRTOS Heap Usage:界面如下,這里會(huì)根據(jù)前面配置顯示出動(dòng)態(tài)內(nèi)存使用情況。用戶(hù)可配置內(nèi)存管理大小,但不能比已配置使用了的小。所謂操作系統(tǒng)的內(nèi)存管理,就是它自己先定義一個(gè)超大的數(shù)組,把內(nèi)存坑全占了。你在應(yīng)用開(kāi)發(fā)時(shí)要拉屎,你要用哪個(gè)坑你說(shuō)的不算,你告訴操作系統(tǒng),“我這邊四個(gè)哥們,給我來(lái)四個(gè)坑”,操作系統(tǒng)會(huì)找到一個(gè)連續(xù)的四個(gè)坑,并把首地址以指針的方式告訴你,如果沒(méi)坑了,就反饋申請(qǐng)內(nèi)存失敗。當(dāng)然,拉完要釋放內(nèi)存~之所以用FreeRTOS內(nèi)存管理,是因?yàn)樵摬僮飨到y(tǒng)提供5種內(nèi)存管理方案,有內(nèi)存碎片回收功能,很強(qiáng)大。
04
編程
配置完后生成代碼,打開(kāi)freertos.c文件,編寫(xiě)任務(wù)函數(shù)代碼。
osDelay()函數(shù)并不是FreeRTOS的原版API函數(shù),而是加上了CMSIS-RTOS封裝后的函數(shù)。
05
CMSIS-RTOS
我們知道,大多數(shù)RTOS的原理都差不多的,都是任務(wù)調(diào)度、延時(shí)函數(shù)、信號(hào)量、隊(duì)列等等東西。Keil有自己的RTX操作系統(tǒng)。后來(lái)ARM收購(gòu)了Keil。CMSIS-RTOS相當(dāng)于將不同廠(chǎng)家的RTOS封裝一下,形成了一個(gè)標(biāo)準(zhǔn)的API函數(shù)庫(kù)。FreeRTOS的匈牙利命名法實(shí)在讓我難受,我更喜歡用這個(gè)封裝庫(kù)。有時(shí)候想輸入一個(gè)函數(shù),知道是Task的API,就因?yàn)橄氩黄饋?lái)前面匈牙利縮寫(xiě)是什么,硬是敲不出來(lái),編輯器也不提醒,因?yàn)楹瘮?shù)開(kāi)頭就不知道是啥~~~~~
06
授之以魚(yú)不如授之以漁
最后說(shuō)一下自學(xué)方法。
通過(guò)本篇,你至少可以寫(xiě)出個(gè)非同步LED閃爍程序了吧。體驗(yàn)一下就好了。
然后,學(xué)習(xí)CMSIS-RTOS有哪些API,以及怎么用這些API。官網(wǎng)http://www.keil.com/pack/doc/cmsis/RTOS/html/index.html 。每個(gè)API函數(shù),都有在線(xiàn)例程代碼,看起來(lái)非常爽。當(dāng)然你如果喜歡原版API,這步就算了。
最后,當(dāng)用熟了之后再去學(xué)習(xí)源碼。
最后的最后,有了操作系統(tǒng),你就會(huì)知道項(xiàng)目怎么劃分任務(wù)了?你就可以做到全局變量不滿(mǎn)天飛了?你就能編寫(xiě)出好看的代碼了?
聯(lián)系客服