www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式大雜燴
[導(dǎo)讀]關(guān)注「嵌入式大雜燴」,選擇「星標(biāo)公眾號(hào)」一起進(jìn)步!來(lái)源:嵌入式實(shí)驗(yàn)基地前言你是否還在為一大堆任務(wù)放在while中,通過(guò)一個(gè)個(gè)標(biāo)志,做一大堆if...else...switch...case...煩惱,想跑個(gè)freertos或者ucos,發(fā)現(xiàn)芯片空間有限,添加不進(jìn)去了...那本文小...

關(guān)注「嵌入式大雜燴」,選擇「星標(biāo)公眾號(hào)」一起進(jìn)步!

來(lái)源:嵌入式實(shí)驗(yàn)基地

前言

你是否還在為一大堆任務(wù)放在while中,通過(guò)一個(gè)個(gè)標(biāo)志,做一大堆if...else...switch...case...煩惱,想跑個(gè)freertos或者ucos,發(fā)現(xiàn)芯片空間有限,添加不進(jìn)去了...那本文小飛哥推薦你一種裸機(jī)多任務(wù)的實(shí)現(xiàn)方法,讓你告別繁瑣的while(1),有錯(cuò)誤之處,煩請(qǐng)指出,一起交流~

模型分析

剛開始寫代碼的時(shí)候,習(xí)慣這種寫法,這種方法首先是沒(méi)有問(wèn)題的,但是在實(shí)時(shí)性方面可能會(huì)差那么點(diǎn)意思,比如,任務(wù)2是需要頻繁刷新的任務(wù),任務(wù)1不是很緊急,但是執(zhí)行時(shí)間比較長(zhǎng),那么就只能等待任務(wù)1執(zhí)行完才會(huì)去執(zhí)行任務(wù)2,任務(wù)2的數(shù)據(jù)刷新不及時(shí)。

隨著任務(wù)的增多,這種完全等待一個(gè)任務(wù)完成再去執(zhí)行下一個(gè)任務(wù)的弊端會(huì)體現(xiàn)的更加明顯。

??while?(1)
??{
????if?(task_flag1)
????{
??????task_flag1?=?0;
??????task01();//任務(wù)1
????}
????else?if?(task_flag2)
????{
??????task_flag2?=?0;
??????task02();//任務(wù)2
????}
????else?if?()
????{
????}
????...?else...
????{
??????taskn();//任務(wù)n
????}
??}
用過(guò)freertos或者其他系統(tǒng)的小伙伴一定知道,對(duì)于多任務(wù)的處理讓系統(tǒng)運(yùn)行看起來(lái)系統(tǒng)似乎是“并行”的,那么受限于單片機(jī)資源的情況下,能不能實(shí)現(xiàn)類似的功能,答案是肯定的,接下來(lái)就一起來(lái)聊聊如何實(shí)現(xiàn)。

其實(shí),在日常的開發(fā)中我們已經(jīng)有用到過(guò)這種思想,比如我們需要在不影響任務(wù)執(zhí)行的情況下,在while(1)循環(huán)中實(shí)現(xiàn)LED 周期閃爍,提示系統(tǒng)正常運(yùn)行,用定時(shí)器當(dāng)然可以。。。今天不聊定時(shí)器,就用點(diǎn)比較接地氣的來(lái)舉例:

?ledFlashCount ;
??if?(ledFlashCount?%?500?==?0)
??{
????ledFlashCount?=?0;
????HAL_GPIO_TogglePin(LED_GPIO_Port,?led_pin);
??}
??HAL_Delay(1);

如果直接延時(shí)500ms,想想while(1)會(huì)怎么樣,老板看了直接走人~,所以我們采用一種時(shí)間分割的方式,每次執(zhí)行1ms,到500次時(shí),執(zhí)行相應(yīng)功能,這樣雖然還有1ms的阻塞延時(shí),但想比于500ms,顯然是個(gè)巨大的飛躍。

根據(jù)上面的思想,我們也可以采取時(shí)間分割的方式去處理不同的任務(wù),把一個(gè)完整的任務(wù)分割成一段一段時(shí)間片,單次執(zhí)行一段,不斷周期性掃描,如此一來(lái),我們就能夠保證任務(wù)能夠得到較為及時(shí)的刷新,在CSDN上有個(gè)小伙伴描述的挺不錯(cuò)。

一個(gè)任務(wù)的線程:

假設(shè)一個(gè)任務(wù)的執(zhí)行代碼有50步,通常編程只會(huì)一次執(zhí)行完畢,但是我們現(xiàn)在需要想想,因?yàn)槲覀儠?huì)嫌這個(gè)任務(wù)總占用著ALU的時(shí)間而影響其他任務(wù)的執(zhí)行效果,所以就可以對(duì)任務(wù)進(jìn)行劃分,把它分為5份,每份10步,這樣我們每次執(zhí)行其中的一個(gè)程序片–每次正在運(yùn)行的程序片我們稱為線程。

(CSDN博客:https://blog.csdn.net/qq_37272520/article/details/88916568)

代碼實(shí)現(xiàn)

首先定義一個(gè)跟任務(wù)相關(guān)的結(jié)構(gòu)體,Delay正是時(shí)間片執(zhí)行的時(shí)長(zhǎng),Period是任務(wù)的執(zhí)行周期

//?------?Public?data?type?declarations?----------------------------

//?User-defined?type?to?store?required?data?for?each?task
typedef?struct
{
???//?Pointer?to?the?task
???//?(must?be?a?'uint32_t?(void)'?function)
???uint32_t?(*pTask)(void);
???//??void?(*pTask)?(void);

???//?Delay?(ticks)?until?the?task?will?(next)?be?run
???uint32_t?Delay;

???//?Interval?(ticks)?between?subsequent?runs.
???uint32_t?Period;
}?sTask_t;


添加(創(chuàng)建)任務(wù)

//?Add_Task
void?SCH_Add_Task(uint32_t?(*pTask)(),
??????????????????const?uint32_t?DELAY,
??????????????????const?uint32_t?PERIOD)
{
???uint32_t?Task_id?=?0;

???//?Check?pre-conditions?(START)
???//?First?find?a?gap?in?the?array?(if?there?is?one)
???while?((SCH_tasks_g[Task_id].pTask?!=?SCH_NULL_PTR)?
本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉
關(guān)閉