1、FreeRTOS的學習
1.1、FreeRTOS的源碼下載
學習一個操作系統前,首先要下載對應的源碼,用于研究和學習。FreeRTOS的源碼下載鏈接如下:
https://sourceforge.net/projects/freertos/files/FreeRTOS/
頁面圖示如下:
下載之后的文件為:FreeRTOSv202012.00-LTS.exe.qbl
1.2、FreeRTOS在線API指南
FreeRTOS提供了在線的API接口的指南,這對于開發和學習都是非常的友好的,在線API指南的網址為:
http://web.ist.utl.pt/~ist11993/FRTOS-API/index.html
在線指南的示意圖如下:
1.3、在線應用指南
除了在線的API應用指南之外,還有一個在線的開發指導手冊,是非常好用的一份手冊:
https://www.freertos.org/RTOS.html
圖示如下:
2、FreeRTOS移植到MCU上
0.基于STM32F103的移植,其它系列MCU類似。
硬件平臺: STM32F103ZET6 ;
軟件平臺:MDK529
FreeTROS版本:FreeRTOS Kernel V10.4.3
1.在工程目錄下新建FreeRTOS文件夾,該文件夾用于存放FreeRTOS相關的文件。
2.在FreeRTOSv10.2.1FreeRTOSSource路徑下找到FreeRTOS的源碼,將其拷貝到工程中的FreeRTOS文件夾中。
其中頭文件和源碼源文件是全部要用到的,不做任何刪除。
portable文件夾是和硬件平臺,軟件開發環境相關的文件。FreeRTOS為了讓用戶移植簡單,幫用戶做了很多工作。打開portable文件夾如下:
3.打開工程,在工程中添加一個專用來存放FreeRTOS的Group
將FreeRTOS的源文件,內存管理文件,硬件接口文件統統添加到這個FreeRTOS這個Group中
內存管理文件在FreeRTOSportableMemMang文件夾下,FreeRTOS提供了五種內存管理方案,對于移植來說,隨便選一種方案都是可以的。但是heap_4有內存碎片管理的功能,對內存碎片可以自動監控和收集,所以選擇這個內存管理會更好。
port.c文件在FreeRTOSportableRVDS路徑下找到與自己使用的MCU內核的文件夾:
4.添加頭文件路徑,需要添加兩個路徑。
5.編譯
便已完成之后,提示打不開FreeRTOSConfig.h這個文件。這是因為FreeRTOS源碼中并沒有提供這個文件。
這種情況下有兩種辦法:
第一、自己動手寫一個(哈哈,個人覺得這個對一般人來說不現實);
第二、找一個可以直接用的。
仔細找找會發現,其實官方在很多平臺下都移植了FreeRTOS。去官方的demo中找,FreeRTOSv10.2.1FreeRTOSDemo路徑下存放的全是官方移植的demo。在此路徑下找到CORTEX_STM32F103_Keil文件夾,此文件夾是官方基于STM32F103和MDK平臺移植的demo。(其他平臺參考該方式類似的查找)
在此文件夾下找到FreeRTOSConfig.h文件。
將其拷貝到源碼的頭文件中。重新進行編譯。
這種情況下,只要使能一個有關的宏定義為1即可以,在FreeRTOSConfig.h文件中將宏INCLUDE_xTaskGetCurrentTaskHandle定義為1,使能該函數,重新編譯一下,應該就不會報錯了。
6.添加三個宏定義
首先我們需要對FreeRTOS的幾個很重要的問題要有一個認識:
<1> FreeRTOS觸發第一個任務是在SVC_Handler中斷中進行的;
<2> 切換任務是在PendSV_Handler中斷中進行的;
<3> 系統節拍中斷是在SysTick_Handler中進行的。
在我們自己移植的項目中,官方的文件中對3個函數的定義是沒有的,需要我們自己進行一些修改。
在官方的提供的文件中,實現了另外3個相關的函數,名字分別是:
vPortSVCHandler
xPortPendSVHandler
xPortSysTickHandler。
所以,我們只需要根據自己所用的MCU環境進行相應的替換即可以對應上了。在FreeRTOSConfig.h頭文件中做一下宏定義就可以了。注意要將自己的原來3個空函數注釋掉。
這三個宏定義非常重要!!!
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler
#define xPortSysTickHandler SysTick_Handler
其中,xPortSysTickHandler是系統滴答定時器中斷,用于給FreeRTOS提供運行的心跳節拍的,代碼示意如下:
void xPortSysTickHandler( void )
{
/* The SysTick runs at the lowest interrupt priority, so when this interrupt
* executes all interrupts must be unmasked. There is therefore no need to
* save and then restore the interrupt mask value as its value is already
* known - therefore the slightly faster vPortRaiseBASEPRI() function is used
* in place of portSET_INTERRUPT_MASK_FROM_ISR(). */
vPortRaiseBASEPRI();
{
/* Increment the RTOS tick. */
if( xTaskIncrementTick() != pdFALSE )
{
/* A context switch is required. Context switching is performed in
* the PendSV interrupt. Pend the PendSV interrupt. */
portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET_BIT;
}
}
vPortClearBASEPRIFromISR();
}
-
移植
+關注
關注
1文章
379瀏覽量
28129 -
FreeRTOS
+關注
關注
12文章
484瀏覽量
62166 -
內存管理
+關注
關注
0文章
168瀏覽量
14137
發布評論請先 登錄
相關推薦
評論