1.FreeRTOS簡介
Free 即免費(fèi)的,RTOS 全稱是 Real Time Operating System,中文就是實(shí)時(shí)操作系統(tǒng)。注意,RTOS 不是指某一個(gè)確定的系統(tǒng),而是指一類系統(tǒng)。比如 uC/OS,F(xiàn)reeRTOS,RTX,RT-Thread 等這些都是 RTOS 類操作系統(tǒng)。
FreeRTOS 是 RTOS 系統(tǒng)的一種,F(xiàn)reeRTOS 十分的小巧,可以在資源有限的微控制器中運(yùn)行,當(dāng)然,F(xiàn)reeRTOS 不僅局限于在微控制器中使用。但從文件數(shù)量上來看 FreeRTOS 要比uC/OSII 和 uC/OSIII 小的多。
FreeRTOS特點(diǎn)
- FreeRTOS 的內(nèi)核支持搶占式,合作式和時(shí)間片調(diào)度。
- 提供了一個(gè)用于低功耗的 Tickless 模式。
- 系統(tǒng)的組件在創(chuàng)建時(shí)可以選擇動(dòng)態(tài)或者靜態(tài)的 RAM,比如任務(wù)、消息隊(duì)列、信號量、軟件定時(shí)器等等。
- FreeRTOS 系統(tǒng)簡單、小巧、易用,通常情況下內(nèi)核占用 4k-9k 字節(jié)的空間。
- 高可移植性,代碼主要 C 語言編寫。
- 高效的軟件定時(shí)器、強(qiáng)大的跟蹤執(zhí)行功能、堆棧溢出檢測功能。
- 任務(wù)數(shù)量不限。
FreeRTOS源碼下載:FreeTOS源碼下載地址
2.FreeRTOS移植
1.打開下載好的FreeRTOS文件夾,我們發(fā)現(xiàn)會(huì)有兩個(gè)FreeRTOS的文件夾,我們這里以最基本的源碼作為移植示例。
2.打開FreeRTOS/Source,此文件夾中保存的即為FreeRTOS源碼,接下來我們找一個(gè)簡潔的工程移植FreeRTOS系統(tǒng)。將Source復(fù)制到我們要移植的工程中。
3.在要移植的工程中創(chuàng)建FreeRTOS文件夾。
4.將源碼復(fù)位到該文件夾中。
5.刪除不需要的文件:在portable中只保留下面兩個(gè)文件夾即可。
RVDS中只保留ARM_CM3文件
6.打開工程,添加.c文件到工程中,添加頭文件路徑。
在官方的參考例程里面我們發(fā)現(xiàn)有這個(gè),將這個(gè)文件拷貝到我們要移植的工程下。
存放路徑可以隨便選擇,只要在KEIL中添加好相應(yīng)路徑即可。重新編譯工程。
7.提供系統(tǒng)心跳值函數(shù)。
#include "FreeRTOS.h" //FreeRTOS使用
#include "task.h"
extern void xPortSysTickHandler(void);
/*****************滴答定時(shí)器初始化******************/
void SysTick_Init(void)
{
SysTick->CTRL&=~(1<<2);//外部時(shí)鐘源9MHZ
SysTick->CTRL|=1<<1;//開中斷
SysTick->VAL=0;
SysTick->LOAD=9000*configTICK_RATE_HZ;//1s
SysTick->CTRL|=1<<0;//使能定時(shí)器
}
/*滴答定時(shí)器中斷,為FreeRTOS提供節(jié)拍數(shù)*/
void SysTick_Handler(void)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
xPortSysTickHandler();
}
}
在FreeRTOSconfig.h中設(shè)置相應(yīng)的宏
/*FreeRTOS與軟件定時(shí)器相關(guān)配置*/
#define configUSE_TIMERS 1 //為1時(shí)啟用軟件定時(shí)器
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1) //軟件定時(shí)器優(yōu)先級
#define configTIMER_QUEUE_LENGTH 5 //軟件定時(shí)器隊(duì)列長度
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) //軟件定時(shí)器任務(wù)堆棧大小
#define INCLUDE_xTaskGetSchedulerState 1
8.延時(shí)函數(shù)修改
(1)可以直接調(diào)用FreeRTOS中提供的延時(shí)函數(shù),不過調(diào)用該函數(shù)會(huì)在延時(shí)時(shí)會(huì)進(jìn)行任務(wù)切換,若不想在延時(shí)中進(jìn)行任務(wù)切換,則可調(diào)用下面的模擬延時(shí)函數(shù)。通過設(shè)置宏FreeRTOS_OS。
/**************微妙延時(shí)函數(shù)*************/
void Delay_Us(int time)
{
#ifdef FreeRTOS_OS
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD; //LOAD的值
ticks=time*9; //需要的節(jié)拍數(shù)
told=SysTick->VAL; //剛進(jìn)入時(shí)的計(jì)數(shù)器值
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow=ticks)break; //時(shí)間超過/等于要延遲的時(shí)間,則退出.
}
}
#else
int i,j;
for(i=0;i
(2)微妙延時(shí)函數(shù)
/**************微妙延時(shí)函數(shù)*************/
void Delay_Us(int time)
{
#ifdef FreeRTOS_OS
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD; //LOAD的值
ticks=time*9; //需要的節(jié)拍數(shù)
told=SysTick->VAL; //剛進(jìn)入時(shí)的計(jì)數(shù)器值
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow=ticks)break; //時(shí)間超過/等于要延遲的時(shí)間,則退出.
}
}
#else
int i,j;
for(i=0;i
9.任務(wù)設(shè)置模板
#define START_TASK_PRIO 1 //任務(wù)優(yōu)先級
#define START_STK_SIZE 128 //任務(wù)堆棧大小
TaskHandle_t StartTask_Handler; //任務(wù)句柄
void start_task(void *pvParameters);//任務(wù)函數(shù)
#define LED0_TASK_PRIO 3 //任務(wù)優(yōu)先級
#define LED0_STK_SIZE 50 //任務(wù)堆棧大小
TaskHandle_t LED0Task_Handler; //任務(wù)句柄
void LED0_task(void); //任務(wù)函數(shù)
#define key_TASK_PRIO 2 //任務(wù)優(yōu)先級
#define key_STK_SIZE 50 //任務(wù)堆棧大小
TaskHandle_t keyTask_Handler; //任務(wù)句柄
void key_task(void); //任務(wù)函數(shù)
int main()
{
SysTick_Init();
Beep_Init();
Led_Init();
Key_Init();
Usartx_Init(USART1,115200,72);
TIMx_Init(TIM2,72,20*1000);
printf("USART1初始化完成\r\n");
//創(chuàng)建任務(wù)
xTaskCreate( (TaskFunction_t)start_task,//任務(wù)函數(shù)
(const char *)"start_task",//任務(wù)名稱
(uint16_t)START_STK_SIZE,//堆棧大小
NULL, //傳遞給任務(wù)函數(shù)的參數(shù)
(UBaseType_t)START_TASK_PRIO,//任務(wù)優(yōu)先級
(TaskHandle_t *)&StartTask_Handler);//任務(wù)句柄
vTaskStartScheduler(); //開啟任務(wù)調(diào)度
}
10.任務(wù)函數(shù)
/*開始任務(wù)函數(shù)*/
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //進(jìn)入臨界區(qū)
//創(chuàng)建LED0任務(wù)
xTaskCreate( (TaskFunction_t )LED0_task,//任務(wù)函數(shù)
(const char *)"start_task",//任務(wù)名稱
(uint16_t)LED0_STK_SIZE,//堆棧大小
NULL, //傳遞給任務(wù)函數(shù)的參數(shù)
(UBaseType_t )LED0_TASK_PRIO,//任務(wù)優(yōu)先級
(TaskHandle_t *)&LED0Task_Handler);//任務(wù)句柄
xTaskCreate( (TaskFunction_t )key_task,//任務(wù)函數(shù)
(const char *)"KEYt_task",//任務(wù)名稱
(uint16_t )key_STK_SIZE,//堆棧大小
NULL, //傳遞給任務(wù)函數(shù)的參數(shù)
(UBaseType_t )key_TASK_PRIO,//任務(wù)優(yōu)先級
(TaskHandle_t *)&keyTask_Handler);//任務(wù)句柄
vTaskDelete(StartTask_Handler); //刪除開始任務(wù)
taskEXIT_CRITICAL(); //退出臨界區(qū)
}
11.任務(wù)執(zhí)行
void LED0_task(void)
{
while(1)
{
LED1=!LED1;
vTaskDelay(500);
}
}
void key_task(void)//任務(wù)函數(shù)
{
u8 key=0;
while(1)
{
key=Key_Scan();
if(key)
{
printf("key=%d\n",key);
}
vTaskDelay(10);
}
}
-
STM32
+關(guān)注
關(guān)注
2272文章
10925瀏覽量
357732 -
RTOS
+關(guān)注
關(guān)注
22文章
819瀏覽量
119905 -
FreeRTOS
+關(guān)注
關(guān)注
12文章
484瀏覽量
62411 -
實(shí)時(shí)操作系統(tǒng)
+關(guān)注
關(guān)注
1文章
199瀏覽量
30833
發(fā)布評論請先 登錄
相關(guān)推薦
評論