<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          FreeRTOS系列第10篇---FreeRTOS任務(wù)控制

          共 3302字,需瀏覽 7分鐘

           ·

          2020-09-02 01:05


          關(guān)注、星標(biāo)公眾號(hào),直達(dá)精彩內(nèi)容

          ID:技術(shù)讓夢(mèng)想更偉大

          作者:李肖遙

          ?

          好多讀者說(shuō)找不到前一篇,今天匯總一下前9篇,這個(gè)系列會(huì)很長(zhǎng),以后每發(fā)一篇會(huì)把之前一篇的鏈接放在開頭,方便查找,傳送門:

          ?

          FreeRTOS系列第1篇---為什么選擇FreeRTOS?

          FreeRTOS系列第2篇---FreeRTOS入門指南

          FreeRTOS系列第3篇---FreeRTOS移植指南

          FreeRTOS系列第4篇---FreeRTOS編碼標(biāo)準(zhǔn)及風(fēng)格指南

          FreeRTOS系列第5篇---FreeRTOS在Cortex-M3上的移植

          FreeRTOS系列第6篇---FreeRTOS內(nèi)核配置說(shuō)明

          FreeRTOS系列第7篇---Cortex-M內(nèi)核使用FreeRTOS特別注意事項(xiàng)

          FreeRTOS系列第8篇---FreeRTOS內(nèi)存管理

          FreeRTOS系列第9篇---FreeRTOS任務(wù)概述基礎(chǔ)篇

          FreeRTOS任務(wù)控制API函數(shù)主要實(shí)現(xiàn)任務(wù)延時(shí)、任務(wù)掛起、解除任務(wù)掛起、任務(wù)優(yōu)先級(jí)獲取和設(shè)置等功能。

          1.相對(duì)延時(shí)

          1.1函數(shù)描述

          void?vTaskDelay(?portTickTypexTicksToDelay?)

          調(diào)用vTaskDelay()函數(shù)后,任務(wù)會(huì)進(jìn)入阻塞狀態(tài),持續(xù)時(shí)間由vTaskDelay()函數(shù)的參數(shù)xTicksToDelay指定,單位是系統(tǒng)節(jié)拍時(shí)鐘周期。

          常量portTICK_RATE_MS 用來(lái)輔助計(jì)算真實(shí)時(shí)間,此值是系統(tǒng)節(jié)拍時(shí)鐘中斷的周期,單位是毫秒。

          在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskDelay 必須設(shè)置成1,此函數(shù)才能有效。

          vTaskDelay()指定的延時(shí)時(shí)間是從調(diào)用vTaskDelay()后開始計(jì)算的相對(duì)時(shí)間。

          比如vTaskDelay(100),那么從調(diào)用vTaskDelay()后,任務(wù)進(jìn)入阻塞狀態(tài),經(jīng)過(guò)100個(gè)系統(tǒng)時(shí)鐘節(jié)拍周期,任務(wù)解除阻塞。因此,vTaskDelay()并不適用于周期性執(zhí)行任務(wù)的場(chǎng)合。

          此外,其它任務(wù)和中斷活動(dòng),會(huì)影響到vTaskDelay()的調(diào)用(比如調(diào)用前高優(yōu)先級(jí)任務(wù)搶占了當(dāng)前任務(wù)),因此會(huì)影響任務(wù)下一次執(zhí)行的時(shí)間。

          API函數(shù)vTaskDelayUntil()可用于固定頻率的延時(shí),它用來(lái)延時(shí)一個(gè)絕對(duì)時(shí)間。

          1.2參數(shù)描述

          • 「xTicksToDelay」:延時(shí)時(shí)間總數(shù),單位是系統(tǒng)時(shí)鐘節(jié)拍周期。

          1.3用法舉例

          voidvTaskFunction(?void?*?pvParameters?)
          {
          ???/*?阻塞500ms.?*/
          ???constportTickType?xDelay?=?500?/?portTICK_RATE_MS;

          ???for(?;;?)
          ???{
          ???????/*?每隔500ms觸發(fā)一次LED,?觸發(fā)后進(jìn)入阻塞狀態(tài)?*/
          ???????vToggleLED();
          ???????vTaskDelay(?xDelay?);
          ???}
          }

          2.絕對(duì)延時(shí)

          2.1函數(shù)描述

          void?vTaskDelayUntil(?TickType_t?*pxPreviousWakeTime,

          const?TickType_txTimeIncrement?);

          任務(wù)延時(shí)一個(gè)指定的時(shí)間。周期性任務(wù)可以使用此函數(shù),以確保一個(gè)恒定的頻率執(zhí)行。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskDelayUntil 必須設(shè)置成1,此函數(shù)才有效。

          這個(gè)函數(shù)不同于vTaskDelay()函數(shù)的一個(gè)重要之處在于:vTaskDelay()指定的延時(shí)時(shí)間是從調(diào)用vTaskDelay()之后(執(zhí)行完該函數(shù))開始算起的,但是vTaskDelayUntil()指定的延時(shí)時(shí)間是一個(gè)絕對(duì)時(shí)間。

          調(diào)用vTaskDelay()函數(shù)后,任務(wù)會(huì)進(jìn)入阻塞狀態(tài),持續(xù)時(shí)間由vTaskDelay()函數(shù)的參數(shù)指定,單位是系統(tǒng)節(jié)拍時(shí)鐘周期。

          因此vTaskDelay()并不適用于周期性執(zhí)行任務(wù)的場(chǎng)合。因?yàn)檎{(diào)用vTaskDelay()到任務(wù)解除阻塞的時(shí)間不總是固定的,并且該任務(wù)下一次調(diào)用vTaskDelay()函數(shù)的時(shí)間也不總是固定的(兩次執(zhí)行同一任務(wù)的時(shí)間間隔本身就不固定,中斷或高優(yōu)先級(jí)任務(wù)搶占也可能會(huì)改變每一次執(zhí)行時(shí)間)。

          vTaskDelay()指定一個(gè)從調(diào)用vTaskDelay()函數(shù)后開始計(jì)時(shí),到任務(wù)解除阻塞為止的相對(duì)時(shí)間,而vTaskDelayUntil()指定一個(gè)絕對(duì)時(shí)間,每當(dāng)時(shí)間到達(dá),則解除任務(wù)阻塞。

          應(yīng)當(dāng)指出的是,如果指定的喚醒時(shí)間已經(jīng)達(dá)到,vTaskDelayUntil()立刻返回(不會(huì)有阻塞)。

          因此,使用vTaskDelayUntil()周期性執(zhí)行的任務(wù),無(wú)論任何原因(比如,任務(wù)臨時(shí)進(jìn)入掛起狀態(tài))停止了周期性執(zhí)行,使得任務(wù)少運(yùn)行了一個(gè)或多個(gè)執(zhí)行周期,那么需要重新計(jì)算所需要的喚醒時(shí)間。

          這可以通過(guò)傳遞給函數(shù)的指針參數(shù)pxPreviousWake指向的值與當(dāng)前系統(tǒng)時(shí)鐘計(jì)數(shù)值比較來(lái)檢測(cè),在大多數(shù)情況下,這并不是必須的。

          常量portTICK_RATE_MS 用來(lái)輔助計(jì)算真實(shí)時(shí)間,此值是系統(tǒng)節(jié)拍時(shí)鐘中斷的周期,單位是毫秒。

          當(dāng)調(diào)用vTaskSuspendAll()函數(shù)掛起RTOS調(diào)度器時(shí),不可以使用此函數(shù)。

          2.2參數(shù)描述

          • 「pxPreviousWakeTime」:指針,指向一個(gè)變量,該變量保存任務(wù)最后一次解除阻塞的時(shí)間第一次使用前,該變量必須初始化為當(dāng)前時(shí)間。之后這個(gè)變量會(huì)在vTaskDelayUntil()函數(shù)內(nèi)自動(dòng)更新。
          • 「xTimeIncrement」:周期循環(huán)時(shí)間。當(dāng)時(shí)間等于*pxPreviousWakeTime + xTimeIncrement時(shí),任務(wù)解除阻塞。如果不改變參數(shù)xTimeIncrement的值,調(diào)用該函數(shù)的任務(wù)會(huì)按照固定頻率執(zhí)行。

          2.3用法舉例

          //每10次系統(tǒng)節(jié)拍執(zhí)行一次
          void?vTaskFunction(?void?*?pvParameters?)
          {
          ???static?portTickType?xLastWakeTime;
          ???const?portTickType?xFrequency?=?10;

          ???//?使用當(dāng)前時(shí)間初始化變量xLastWakeTime
          ???xLastWakeTime?=?xTaskGetTickCount();

          ???for(?;;?)
          ???{
          ???????//等待下一個(gè)周期
          ???????vTaskDelayUntil(?&xLastWakeTime,xFrequency?);

          ???????//?需要周期性執(zhí)行代碼放在這里
          ???}
          }

          3.獲取任務(wù)優(yōu)先級(jí)

          3.1函數(shù)描述

          UBaseType_t?uxTaskPriorityGet(TaskHandle_t?xTask?);

          獲取指定任務(wù)的優(yōu)先級(jí)。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskPriorityGet必須設(shè)置成1,此函數(shù)才有效。

          3.2參數(shù)描述

          • 「xTask」:任務(wù)句柄。NULL表示獲取當(dāng)前任務(wù)的優(yōu)先級(jí)。

          3.3返回值

          返回指定任務(wù)的優(yōu)先級(jí)。

          3.4用法舉例

          voidvAFunction(?void?)
          {
          ???xTaskHandlexHandle;
          ???//?創(chuàng)建任務(wù),保存任務(wù)句柄
          ???xTaskCreate(?vTaskCode,?"NAME",STACK_SIZE,?NULL,?tskIDLE_PRIORITY,?&xHandle?);
          ???//?...
          ???//?使用句柄獲取創(chuàng)建的任務(wù)的優(yōu)先級(jí)
          ???if(?uxTaskPriorityGet(?xHandle?)?!=tskIDLE_PRIORITY?)
          ???{
          ???????//?任務(wù)可以改變自己的優(yōu)先級(jí)
          ???}
          ???//?...
          ???//?當(dāng)前任務(wù)優(yōu)先級(jí)比創(chuàng)建的任務(wù)優(yōu)先級(jí)高?
          ???if(?uxTaskPriorityGet(?xHandle?)????{
          ???????//?當(dāng)前優(yōu)先級(jí)較高
          ???}
          }

          4.設(shè)置任務(wù)優(yōu)先級(jí)

          4.1函數(shù)描述

          void?vTaskPrioritySet(?TaskHandle_txTask,

          UBaseType_tuxNewPriority?);

          設(shè)置指定任務(wù)的優(yōu)先級(jí)。如果設(shè)置的優(yōu)先級(jí)高于當(dāng)前運(yùn)行的任務(wù),在函數(shù)返回前會(huì)進(jìn)行一次上下文切換。

          在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskPrioritySet必須設(shè)置成1,此函數(shù)才有效。

          4.2參數(shù)描述

          • 「xTask」:要設(shè)置優(yōu)先級(jí)任務(wù)的句柄,為NULL表示設(shè)置當(dāng)前運(yùn)行的任務(wù)。
          • 「uxNewPriority」:要設(shè)置的新優(yōu)先級(jí)。

          4.3用法舉例

          voidvAFunction(?void?)
          {
          ???xTaskHandlexHandle;
          ???//?創(chuàng)建任務(wù),保存任務(wù)句柄。
          ???xTaskCreate(?vTaskCode,?"NAME",STACK_SIZE,?NULL,?tskIDLE_PRIORITY,?&xHandle?);
          ???//?...
          ???//?使用句柄來(lái)提高創(chuàng)建任務(wù)的優(yōu)先級(jí)
          ???vTaskPrioritySet(?xHandle,tskIDLE_PRIORITY?+?1?);
          ???//?...
          ???//?使用NULL參數(shù)來(lái)提高當(dāng)前任務(wù)的優(yōu)先級(jí),設(shè)置成和創(chuàng)建的任務(wù)相同。
          ???vTaskPrioritySet(?NULL,?tskIDLE_PRIORITY?+1?);
          }

          5.任務(wù)掛起

          5.1函數(shù)描述

          void?vTaskSuspend(?TaskHandle_txTaskToSuspend?);

          掛起指定任務(wù)。被掛起的任務(wù)絕不會(huì)得到處理器時(shí)間,不管該任務(wù)具有什么優(yōu)先級(jí)。

          調(diào)用vTaskSuspend函數(shù)是不會(huì)累計(jì)的:即使多次調(diào)用vTaskSuspend ()函數(shù)將一個(gè)任務(wù)掛起,也只需調(diào)用一次vTaskResume ()函數(shù)就能使掛起的任務(wù)解除掛起狀態(tài)。

          在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必須設(shè)置成1,此函數(shù)才有效。

          5.2參數(shù)描述

          • 「xTaskToSuspend」:要掛起的任務(wù)句柄。為NULL表示掛起當(dāng)前任務(wù)。

          5.3用法舉例

          voidvAFunction(?void?)
          {
          ???xTaskHandlexHandle;
          ???//?創(chuàng)建任務(wù),保存任務(wù)句柄.
          ???xTaskCreate(?vTaskCode,?"NAME",STACK_SIZE,?NULL,?tskIDLE_PRIORITY,?&xHandle?);
          ???//?...
          ???//?使用句柄掛起創(chuàng)建的任務(wù).
          ???vTaskSuspend(?xHandle?);
          ???//?...
          ???//?任務(wù)不再運(yùn)行,除非其它任務(wù)調(diào)用了vTaskResume(xHandle?)
          ???//...
          ???//?掛起本任務(wù).
          ???vTaskSuspend(?NULL?);
          ???//?除非另一個(gè)任務(wù)使用handle調(diào)用了vTaskResume,否則永遠(yuǎn)不會(huì)執(zhí)行到這里
          }

          6.恢復(fù)掛起的任務(wù)

          6.1函數(shù)描述

          void?vTaskResume(?TaskHandle_txTaskToResume?);

          恢復(fù)掛起的任務(wù)。

          通過(guò)調(diào)用一次或多次vTaskSuspend()掛起的任務(wù),可以調(diào)用一次vTaskResume ()函數(shù)來(lái)再次恢復(fù)運(yùn)行。

          在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspend必須置1,此函數(shù)才有效。

          6.2參數(shù)描述

          • 「xTaskToResume」:要恢復(fù)運(yùn)行的任務(wù)句柄。

          6.3用法舉例

          voidvAFunction(?void?)
          {
          ???????xTaskHandle?xHandle;
          ???//?創(chuàng)建任務(wù),保存任務(wù)句柄
          ???xTaskCreate(?vTaskCode,?"NAME",STACK_SIZE,?NULL,?tskIDLE_PRIORITY,?&xHandle?);
          ???//?...
          ???//?使用句柄掛起創(chuàng)建的任務(wù)
          ???vTaskSuspend(?xHandle?);
          ???//?...
          ???//任務(wù)不再運(yùn)行,除非其它任務(wù)調(diào)用了vTaskResume(xHandle?)????
          ????????//...
          ???//?恢復(fù)掛起的任務(wù).
          ???vTaskResume(?xHandle?);
          ???//?任務(wù)再一次得到處理器時(shí)間
          ???//?任務(wù)優(yōu)先級(jí)與之前相同
          }

          7.恢復(fù)掛起的任務(wù)(在中斷服務(wù)函數(shù)中使用)

          7.1函數(shù)描述

          BaseType_t?xTaskResumeFromISR(TaskHandle_t?xTaskToResume?);

          用于恢復(fù)一個(gè)掛起的任務(wù),用在ISR中。

          通過(guò)調(diào)用一次或多次vTaskSuspend()函數(shù)而掛起的任務(wù),只需調(diào)用一次xTaskResumeFromISR()函數(shù)即可恢復(fù)運(yùn)行。

          xTaskResumeFromISR()不可用于任務(wù)和中斷間的同步,如果中斷恰巧在任務(wù)被掛起之前到達(dá),這就會(huì)導(dǎo)致一次中斷丟失(任務(wù)還沒有掛起,調(diào)用xTaskResumeFromISR()函數(shù)是沒有意義的,只能等下一次中斷)。

          這種情況下,可以使用信號(hào)量作為同步機(jī)制。在文件FreeRTOSConfig.h中,宏INCLUDE_vTaskSuspendINCLUDE_xTaskResumeFromISR 必須設(shè)置成1,此函數(shù)才有效。

          7.2參數(shù)描述

          • 「xTaskToResume」:要恢復(fù)運(yùn)行的任務(wù)句柄。

          7.3返回值

          如果恢復(fù)任務(wù)后需要上下文切換返回pdTRUE,否則返回pdFALSE。由ISR確定是否需要上下文切換。

          7.4用法舉例

          xTaskHandlexHandle;?????????//注意這是一個(gè)全局變量
          ?
          void?vAFunction(?void?)
          {
          ???//?創(chuàng)建任務(wù)并保存任務(wù)句柄
          ???xTaskCreate(?vTaskCode,?"NAME",STACK_SIZE,?NULL,?tskIDLE_PRIORITY,?&xHandle?);

          ???//?...?剩余代碼.
          }

          void?vTaskCode(?void?*pvParameters?)
          {
          ???for(?;;?)
          ???{
          ???????//?...?在這里執(zhí)行一些其它功能

          ???????//?掛起自己
          ???????vTaskSuspend(?NULL?);

          ???????//直到ISR恢復(fù)它之前,任務(wù)會(huì)一直掛起
          ???}
          }

          void?vAnExampleISR(?void?)
          {
          ???portBASE_TYPExYieldRequired;

          ???//?恢復(fù)被掛起的任務(wù)
          ???xYieldRequired?=?xTaskResumeFromISR(xHandle?);

          ???if(?xYieldRequired?==?pdTRUE?)
          ???{
          ???????//?我們應(yīng)該進(jìn)行一次上下文切換
          ???????//?注:??如何做取決于你具體使用,可查看說(shuō)明文檔和例程
          ???????portYIELD_FROM_ISR();
          ???}
          }
          推薦閱讀:


          嵌入式編程專輯

          Linux 學(xué)習(xí)專輯

          C/C++編程專輯

          關(guān)注微信公眾號(hào)『技術(shù)讓夢(mèng)想更偉大』,后臺(tái)回復(fù)“m”查看更多內(nèi)容,回復(fù)“加群”加入技術(shù)交流群。

          長(zhǎng)按前往圖中包含的公眾號(hào)關(guān)注

          瀏覽 69
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本欧美视频 | 激情五月婷婷五月 | 亚洲成人中文字幕影院 | 欧美高清中文字幕第一页 | 欧美一级片在线播放视频 |