<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

FreeRTOS介紹與基礎任務創建

碼農愛學習 ? 來源:碼農愛學習 ? 作者:碼農愛學習 ? 2022-09-26 09:00 ? 次閱讀

FreeRTOS簡介

FreeRTOS,全稱Free Real Time Operating System,即免費的實時操作系統。相比于計算機中用到的Windows,MacOS,Linux等操作系統,實時操作系統(RTOS)是一種輕量級的操作系統,適用于嵌入式硬件中,用于解決單片機類裸機輪詢方式在處理多個任務時的實時性不高的問題。

目前的實時操作系統有好多種,除FreeRTOS外,還有μCOS、RT-Thread、RTX、Alios Things、Huawei LiteOS等。

什么是RTOS?

實時操作系統(RTOS)的主要特點是可以實現多任務,與多任務系統相對的是裸機系統。

裸機系統

裸機系統就是最初我們學習單片機編程時接觸的那種編程方式,main函數中一個while大循環依次處理各個模塊的任務,對于需要及時檢測的事件會使用中斷。這種使用大循環的程序運行方式也叫輪詢系統,加上中斷處理函數后又稱前后臺系統,中斷處理稱作前臺,無限循環稱作后臺。

多任務系統

多任務系統是將各個處理模塊編寫為單獨的任務,每個任務本身是個無限循環,程序運行初期會創建各個子任務,通過任務調度的方式,利用各任務的阻塞時刻不斷切換運行各個任務,達到一種看起來是多個任務在同時運行的一種效果。并且,通過中斷標志以及任務間通信的相關機制,可以實現任務之間的快速響應。

FreeRTOS特點

使用免費!

系統簡單小巧、文件數量少、通常情況下內核占用4~9k字節空間

搶占式內核

代碼主要由C編寫,可移植性高,已實現在30多種架構的芯片上移植

任務與任務,任務與中斷間的通信方式包括:信號量、消息隊列、事件標志組、任務通知

具有優先級繼承特性的互斥信號令,避免優先級反轉問題

高效的軟件定時器

FreeRTOS源碼目錄結構

這里以FreeRTOS v9.0.0版本為例,代碼包含FreeRTOS和FreeRTOS-Plus文件夾,后者是一些補充文件,初學者用不到,可以先忽略。在FreeRTOS文件夾中主要關注source文件夾,這里是FreeRTOS的全部源碼,包括6個c文件和include文件夾下的多個h文件。另外,在portable文件夾下,是針對不同硬件平臺的單獨區分使用的代碼,目前考慮使用Keil開發STM32F407,所以portable文件夾只需使用RVDS的ARM_CM4F以及MemMang。

關于各個c文件的主要用途:

port.c : 針對不同硬件平臺的接口

heap_4.c : 內存管理相關

croutine.c : 協程相關

event_groups.c : 事件標志組相關

list.c : 列表,FreeRTOS的一種基礎數據結構

queue.c : 隊列相關

tasks.c : 任務創建、掛起、恢復、調度相關

timers.c : 軟件定時器相關

另外在Demo文件夾下還需要用到一個FreeRTOSConfig.h,該文件中通過各種宏定義的方式來配置FreeRTOS需要使用哪些資源。

?

poYBAGMwYBWASii5AAHkTVYjmyU506.png

任務相關API函數

任務創建 xTaskCreate()

函數原型(tasks.c中):

BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
                       const char * const pcName,
                       const uint16_t usStackDepth,
                       void * const pvParameters,
                       UBaseType_t uxPriority,
                       TaskHandle_t * const pxCreatedTask ) 

參數

pxTaskCode:自己創建的任務函數的函數名

pcName:任務的名字,隨意起,字符串型

usStackDepth:任務堆棧大小(實際上申請到的是這里的4倍),設的太小任務可能無法運行!

pvParameters:任務函數的參數,不需要傳參設為NULL即可

uxPriority:任務優先級,0~(configMAX_PRIORITIES-1)

pxCreatedTask:任務句柄,實際是一個指針,也是任務的任務堆棧

返回值:

pdPASS:數值1,任務創建成功,且添加到就緒列表

錯誤代碼:負數,任務創建識別

這里的返回值是BaseType_t,實際它是long類型,可以在portmacro.h文件中看到其定義:

typedef long BaseType_t;

另外,任務句柄的類型為TaskHandle_t,實際它是void *類型,可以在task.h文件中看到其定義:

typedef void * TaskHandle_t;

注:xTaskCreate()是一種動態創建任務的方式,系統通過heap_4.c的配置為任務自動分配相關內存,還有一種靜態創建任務的方式xTaskCreateStatic(),這里先不介紹。

任務刪除 vTaskDelete()

函數原型(tasks.c中):

void vTaskDelete( TaskHandle_t xTaskToDelete )

參數:

xTaskToDelete:要刪除的任務的任務句柄

注:通過 xTaskCreate()動態創建的任務,在使用vTaskDelete()刪除后,該任務創建時申請的堆棧和內存會在系統的空閑任務中被釋放掉。

任務調度 vTaskStartScheduler()

函數原型(tasks.c中):

void vTaskStartScheduler( void )

不需要參數,開啟后就由FreeRTOS開始任務調度工作。

程序設計

主函數

主函數還是我們熟悉的main函數,但FreeRTOS里的main函數不需要自己設計成死循環,只需要創建任務并開啟任務調度,即可使系統持續運行。

任務的創建一般都是先創建一個開始任務,然后開始任務再負責創建其它子任務。

int main(void)
{ 
	//設置系統中斷優先級分組4(FreeRTOS中的默認方式!)
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	//初始化LED端口
	LED_Init();		        			

	//創建開始任務
	xTaskCreate((TaskFunction_t )start_task,            //任務函數
				(const char*    )"start_task",          //任務名稱
				(uint16_t       )START_STK_SIZE,        //任務堆棧大小
				(void*          )NULL,                  //傳遞給任務函數的參數
				(UBaseType_t    )START_TASK_PRIO,       //任務優先級
				(TaskHandle_t*  )&StartTask_Handler);   //任務句柄  
	//開啟任務調度				
	vTaskStartScheduler();          
}

開始任務函數

開始任務函數的功能就是用來創建其它的子任務,創建完之后會把自己刪除掉。

//開始任務任務函數
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //進入臨界區
	
    //創建TASK1任務
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //創建TASK2任務
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
				
    vTaskDelete(StartTask_Handler); //刪除開始任務
				
    taskEXIT_CRITICAL();            //退出臨界區
}

兩個任務函數

每個任務函數都是一個死循環,注意循環中必須添加vTaskDelay()延時函數,用于任務的切換。

//task1任務函數
void task1_task(void *pvParameters)
{
	while(1)
	{
		LEDa_Toggle;
        vTaskDelay(500); //延時500ms
	}
}

//task2任務函數
void task2_task(void *pvParameters)
{
	while(1)
	{
        LEDb_ON;
        vTaskDelay(200); //延時200ms
		LEDb_OFF;
        vTaskDelay(800); //延時800ms
	}
}

main.c所有程序

#include "stm32f4xx.h"
#include "led.h"

#include "FreeRTOS.h"
#include "task.h"

//任務參數--------------------------
//優先級 堆棧大小 任務句柄 任務函數
#define START_TASK_PRIO		1
#define START_STK_SIZE 		128  
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

#define TASK1_TASK_PRIO		2
#define TASK1_STK_SIZE 		128  
TaskHandle_t Task1Task_Handler;
void task1_task(void *pvParameters);

#define TASK2_TASK_PRIO		3	
#define TASK2_STK_SIZE 		128  
TaskHandle_t Task2Task_Handler;
void task2_task(void *pvParameters);


int main(void)
{ 
	//設置系統中斷優先級分組4(FreeRTOS中的默認方式!)
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	//初始化LED端口
	LED_Init();		        			

	//創建開始任務
	xTaskCreate((TaskFunction_t )start_task,            //任務函數
				(const char*    )"start_task",          //任務名稱
				(uint16_t       )START_STK_SIZE,        //任務堆棧大小
				(void*          )NULL,                  //傳遞給任務函數的參數
				(UBaseType_t    )START_TASK_PRIO,       //任務優先級
				(TaskHandle_t*  )&StartTask_Handler);   //任務句柄  
	//開啟任務調度				
	vTaskStartScheduler();          
}

//開始任務任務函數
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //進入臨界區
	
    //創建TASK1任務
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //創建TASK2任務
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
				
    vTaskDelete(StartTask_Handler); //刪除開始任務
				
    taskEXIT_CRITICAL();            //退出臨界區
}

//task1任務函數
void task1_task(void *pvParameters)
{
	while(1)
	{
		LEDa_Toggle;
        vTaskDelay(500); //延時500ms
	}
}

//task2任務函數
void task2_task(void *pvParameters)
{
	while(1)
	{
        LEDb_ON;
        vTaskDelay(200); //延時200ms
		LEDb_OFF;
        vTaskDelay(800); //延時800ms
	}
}

運行結果

運行效果是板子上的兩個LED按照各自任務函數中設定的亮滅時間不斷閃爍。

使用系統的原因就是可以讓兩個任務看起來像是同時運行,試想,如果是裸機系統,雖然也可以實現同樣功能(這兩個LED任務的閃爍規律比較簡單),但需要將兩個任務結合起來管理亮滅時間,兩個任務就糾纏在一起了,如果是兩個更復雜的任務,裸機系統可能就無法實現了。

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • FreeRTOS
    +關注

    關注

    12

    文章

    474

    瀏覽量

    61461
  • 實時操作系統

    關注

    1

    文章

    184

    瀏覽量

    30579
收藏 人收藏

    評論

    相關推薦

    轉:freeRTOS任務創建

    我們曾經在公眾號里給大家推送過關于freeRTOS在NXP kinetis KV4x上的移植,得到了猿友大量的反饋,很多猿友還是感覺對基礎的一些東西不懂,今天我們就從基礎的任務創建講起,任務
    發表于 07-14 14:18

    STM32CUBE的freertos任務創建

    目錄問題說明解決步驟驗證方案總結問題說明STM32CUBE的freertos任務創建十分簡單方便,但卻有一個麻煩:需要我們把要跑的任務具體代碼都寫進
    發表于 08-24 08:26

    FreeRTOS任務創建過程

    FreeRTOS筆記(四):任務創建/刪除,掛起/解掛詳解在第二篇筆記中介紹任務創建的API,
    發表于 02-08 06:10

    FreeRTOS創建任務的流程分享

    從零入門 FreeRTOS 操作系統之創建任務啟動方式在 main() 函數中將硬件和 RTOS 系統先初始化好,然后創建一個啟動任務后就啟
    發表于 02-11 06:59

    FreeRTOS任務的使用

    FreeRTOS學習筆記(二):任務創建/刪除,掛起/解掛上篇文章介紹任務相關的基礎知識,本篇文章對F
    發表于 02-18 07:14

    FreeRTOS任務創建到閃存LED的基本應用程序

    應用程序 : 本代碼是 FreeRTOS 任務的基本應用程序, 用于創建閃存 LED 任務 。 BSP 版本: M480系列 BSP CMSIS V3.04.000 硬件
    發表于 08-22 06:28

    FreeRTOS任務如何創建和刪除?

    FreeRTOS移植到Cortex-M3硬件平臺的文章中,我們已經見過任務創建API,但那篇文章的重點在于如何移植FreeRTOS,本文將重點放在
    的頭像 發表于 03-11 18:08 ?2700次閱讀

    FreeRTOS筆記(四):任務創建/刪除,掛起/解掛詳解

    FreeRTOS筆記(四):任務創建/刪除,掛起/解掛詳解在第二篇筆記中介紹任務創建的API,
    發表于 12-04 19:36 ?15次下載
    <b class='flag-5'>FreeRTOS</b>筆記(四):<b class='flag-5'>任務</b><b class='flag-5'>創建</b>/刪除,掛起/解掛詳解

    從零入門 FreeRTOS 操作系統之創建任務流程

    從零入門 FreeRTOS 操作系統之創建任務啟動方式在 main() 函數中將硬件和 RTOS 系統先初始化好,然后創建一個啟動任務后就啟
    發表于 12-07 18:36 ?7次下載
    從零入門 <b class='flag-5'>FreeRTOS</b> 操作系統之<b class='flag-5'>創建</b><b class='flag-5'>任務</b>流程

    #FreeRTOS學習筆記(二):任務創建/刪除,掛起/解掛

    FreeRTOS學習筆記(二):任務創建/刪除,掛起/解掛上篇文章介紹任務相關的基礎知識,本篇文章對F
    發表于 12-23 19:56 ?2次下載
    #<b class='flag-5'>FreeRTOS</b>學習筆記(二):<b class='flag-5'>任務</b><b class='flag-5'>創建</b>/刪除,掛起/解掛

    FreeRTOS高級篇2---FreeRTOS任務創建分析

    FreeRTOS基礎系列《FreeRTOS系列第10篇---FreeRTOS任務創建和刪除》中介紹
    發表于 01-26 17:42 ?23次下載
    <b class='flag-5'>FreeRTOS</b>高級篇2---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>任務</b><b class='flag-5'>創建</b>分析

    FreeRTOS系列第10篇---FreeRTOS任務創建和刪除

    FreeRTOS移植到Cortex-M3硬件平臺的文章中,我們已經見過任務創建API,但那篇文章的重點在于如何移植FreeRTOS,本文將重點放在
    發表于 01-26 17:56 ?13次下載
    <b class='flag-5'>FreeRTOS</b>系列第10篇---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>任務</b><b class='flag-5'>創建</b>和刪除

    FreeRTOS任務創建與刪除

    FreeRTOS 中,每個執行線程都被稱為”任務”。在嵌入式社區中,對此并沒有一個公允的術語,但我更喜歡用”任務”而不是”線程”,因為從以前的經驗來看,線程具有更多的特定含義。
    的頭像 發表于 02-10 14:43 ?993次閱讀

    RA FreeRTOS任務創建

    ,開發環境e 2 studio完美支持FreeRTOS,無需額外手動移植。以下介紹如何用瑞薩e 2 studio創建RA系列MCU的FreeRTOS工程。 對于不熟悉瑞薩的FSP開發環
    的頭像 發表于 03-10 14:35 ?1011次閱讀

    RA FreeRTOS任務創建

    ,開發環境e2 studio完美支持FreeRTOS,無需額外手動移植。以下介紹如何用瑞薩e2 studio創建RA系列MCU的FreeRTOS工程。
    的頭像 發表于 07-12 10:00 ?275次閱讀
    RA <b class='flag-5'>FreeRTOS</b><b class='flag-5'>任務</b><b class='flag-5'>創建</b>
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>