現在准備的簡單程序LED燈的工程目錄中增加freertos文件夾:
在 source目錄下的portable目錄下只留下下面的文件夾:
為什么呢?
把對應文件移植在工程中之后,添加頭文件路徑如下圖:
編譯之后,報錯如下:
提示少了配置文件,那么我們可以在官方demo文件目錄下復制一個到我們工程中來。
這個時候需要觀察一下這個config.h文件,
這里更改一點代碼:
那個條件編譯最后就是為了定義CLOCK_HZ的,cpu的頻率根據硬件平台的不同,要做適當處理,所以我們直接把這個宏定義出來,180M系統時鍾。
這個時候再編譯,還是報錯:
再編譯:
沒有報錯了,但是我們有必要貼出這個config.h文件來說明我們采取不更改啟動文件用宏實現port.c的中斷服務函數和啟動文件相連接:
/* FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd. All rights reserved VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. This file is part of the FreeRTOS distribution. FreeRTOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (version 2) as published by the Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception. *************************************************************************** >>! NOTE: The modification to the GPL is included to allow you to !<< >>! distribute a combined work that includes FreeRTOS without being !<< >>! obliged to provide the source code for proprietary components !<< >>! outside of the FreeRTOS kernel. !<< *************************************************************************** FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Full license text is available on the following link: http://www.freertos.org/a00114.html *************************************************************************** * * * FreeRTOS provides completely free yet professionally developed, * * robust, strictly quality controlled, supported, and cross * * platform software that is more than just the market leader, it * * is the industry's de facto standard. * * * * Help yourself get started quickly while simultaneously helping * * to support the FreeRTOS project by purchasing a FreeRTOS * * tutorial book, reference manual, or both: * * http://www.FreeRTOS.org/Documentation * * * *************************************************************************** http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading the FAQ page "My application does not run, what could be wrong?". Have you defined configASSERT()? http://www.FreeRTOS.org/support - In return for receiving this top quality embedded software for free we request you assist our global community by participating in the support forum. http://www.FreeRTOS.org/training - Investing in training allows your team to be as productive as possible as early as possible. Now you can receive FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers Ltd, and the world's leading authority on the world's leading RTOS. http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, including FreeRTOS+Trace - an indispensable productivity tool, a DOS compatible FAT file system, and our tiny thread aware UDP/IP stack. http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS licenses offer ticketed support, indemnification and commercial middleware. http://www.SafeRTOS.com - High Integrity Systems also provide a safety engineered and independently SIL3 certified version for use in safety and mission critical applications that require provable dependability. 1 tab == 4 spaces! */ /* *=================================== 中文注解 ======================================= * * 作者:秉火 Fire * 論壇:www.firebbs.cn * 淘寶:www.fire-stm32.taobao.com * * FreeRTOSConfig.h這個頭文件用來配置FreeRTOS的功能,但是並不全面,剩下的其他功能可以 * 在FreeRTOS.h這個頭文件配置,比如使能互斥信號量,使能遞歸信號量,使能事件標志組這些 * 內核對象的功能時,是在FreeRTOS.h這個頭文件里面配置的。但是,為了方便配置,我們可以 * 統一在FreeRTOSConfig.h配置,當需要用到什么功能就把對應的宏在FreeRTOSConfig.h中使能。 *==================================================================================== */ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H /*----------------------------------------------------------- * Application specific definitions. * * These definitions should be adjusted for your particular hardware and * application requirements. * * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. * * See http://www.freertos.org/a00110.html. *----------------------------------------------------------*/ #define configCPU_CLOCK_HZ ( ( unsigned long ) 180000000 ) /* 系統時鍾,單位為HZ */ #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) /* SysTick中斷周期,單位為HZ,1000HZ即1ms中斷一次 */ /*================================================================================================================================================================ ********************************************************************* FreeRTOS功能配置開始 ********************************************************************** * * 這些宏都可以在FreeRTOS.h這個頭文件里面開啟,但是這個頭文件里面的宏非常多,找起來很麻煩,為了方便,我們可以統一在FreeRTOSConfig.h這個頭文件里面配置。 * 目前只包含了常用的配置,剩下的其他功能等需要用的時候再配置即可。 * *===============================================================================================================================================================*/ #define configUSE_PREEMPTION 1 /* 使能搶占式調度,否則用合作式調度,默認我們都是用搶占式 */ #define configUSE_IDLE_HOOK 0 /* 空閑任務鈎子函數,如果配置為1,這個鈎子函數需要用戶自己編寫 */ #define configUSE_TICK_HOOK 0 /* 時基任務鈎子函數,如果配置為1,這個鈎子函數需要用戶自己編寫*/ #define configMAX_PRIORITIES ( 5 ) /* 任務能使用最大優先級個數,數字越大優先級越高,范圍為:0~configMAX_PRIORITIES-1 最低的0由系統分配給空閑任務,每個任務的優先級可以相同 */ #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 75 * 1024 ) ) /* 堆空間大小,內核在創建各種對象時需要用到,單位為字節 */ #define configMAX_TASK_NAME_LEN ( 16 ) /* 任務名稱的長度,即字符串的長度 */ #define configUSE_TRACE_FACILITY 0 #define configUSE_16_BIT_TICKS 0 /* SysTick Counter的寬度,0表示32bit,1表示16bit,STM32用的是32bit */ #define configIDLE_SHOULD_YIELD 1 /* 上下文切換強制使能,即當前任務執行完畢之后還有剩余的時間片,可以強制自己放棄 剩余的時間片,然后執行上下文切換去執行其他的任務*/ /* * 合作式調度配置 * 合作式調度是為性能低,資源少的處理器設計的,非常非常少用到,在STM32這種高性能,資源多的處理器上是不會使用的。 * 合作式調度在FreeRTOS-V9.0.0版本之后不會被刪除,但是也不會更新,就是這么留着。 */ #define configUSE_CO_ROUTINES 0 #define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /* 遞歸互斥信號量配置 */ #define configUSE_RECURSIVE_MUTEXES 0 /* 互斥信號量配置 */ #define configUSE_MUTEXES 0 /* 計數信號量配置 */ #define configUSE_COUNTING_SEMAPHORES 0 /* 軟件定時器配置 */ #define configUSE_TIMERS 1 #define configTIMER_TASK_PRIORITY ( 2 ) #define configTIMER_QUEUE_LENGTH 10 #define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) /* 任務通知配置 * 即任務信號量和任務消息 ,是任務的自有的屬性 * 在任務的控制塊TCB里面有一個32bit的變量來傳遞消息 */ #define configUSE_TASK_NOTIFICATIONS 1 /* 多個內核對象配置 */ #define configUSE_QUEUE_SETS 0 /* * 1:使能函數 * 0:失能函數 */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 #define INCLUDE_vTaskCleanUpResources 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 /* vTaskDelay 為阻塞延時函數,常用,單位為ms */ /*================================================================================================================================================================ ********************************************************************* FreeRTOS功能配置結束 ********************************************************************** *===============================================================================================================================================================*/ /*======================================== STM32使用了多少bit來表達優先級 ========================================*/ /* * Cortex-M內核使用8bit來配置優先級,但是STM32只使用了高4bit,數值越小,優先級越高。 * 在往寄存器里面寫數值配置的時候,是按照8bit來寫的,所以真正寫的時候需要經過轉換,公式為: * ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我們配置的真正的優先級 */ #ifdef __NVIC_PRIO_BITS /* __NVIC_PRIO_BITS 已經在stm32f4xx.h里面定義為4 */ #define configPRIO_BITS __NVIC_PRIO_BITS #else #define configPRIO_BITS 4 #endif /*============================================== SysTick中斷優先級配置 ============================================*/ /* * 在往寄存器里面寫數值配置的時候,是按照8bit來寫的,所以真正寫的時候需要經過轉換,公式為: * ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我們配置的真正的優先級。經過這個公式之后得到的是 * 下面的這個宏:configKERNEL_INTERRUPT_PRIORITY * SysTick的優先級我們一般配置為最低,即0xf 。這樣可以提高系統的實時響應能力,即其他的外部中斷可以及時的得到響應。 */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /*===========================================可屏蔽的中斷優先級配置====================================================*/ /* * 用於配置STM32的特殊寄存器basepri寄存器的值,用於屏蔽中斷,當大於basepri值的優先級的中斷將被全部屏蔽。basepri只有4bit有效, * 默認只為0,即全部中斷都沒有被屏蔽。configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY配置為:5,意思就是中斷優先級大於5的中斷都被屏蔽。 * 當把配置好的優先級寫到寄存器的時候,是按照8bit來寫的,所以真正寫的時候需要經過轉換,公式為: * ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff),其中的priority就是我們配置的真正的優先級。經過這個公式之后得到的是下面的這個宏: * configMAX_SYSCALL_INTERRUPT_PRIORITY * * 在FreeRTOS中,關中斷是通過配置basepri寄存器來實現的,關掉的中斷由配置的basepri的值決定,小於basepri值的 * 中斷FreeRTOS是關不掉的,這樣做的好處是可以系統設計者可以人為的控制那些非常重要的中斷不能被關閉,在緊要的關頭必須被響應。 * 而在UCOS中,關中斷是通過控制PRIMASK來實現的,PRIMASK是一個單1的二進制位,寫1則除能除了NMI和硬 fault的所有中斷。當UCOS關閉 * 中斷之后,即使是你在系統中設計的非常緊急的中斷來了都不能馬上響應,這加大了中斷延遲的時間,如果是性命攸關的場合,那后果估計挺嚴重。 * 相比UCOS的關中斷的設計,FreeRTOS的設計則顯得人性化很多。 * */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* * 斷言配置,一般調試的時候用,發布的時候不用 */ #define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); } /*=================================== SVC,PendSV 和 SysTick 中斷服務函數的配置 ========================================*/ /* * 在移植FreeRTOS的時候,需要用到STM32的三個中斷,分別是SVC,PendSV和SysTick,這三個中斷在向量表 * 里面的名字分別是:SVC_Handler,PendSV_Handler和SysTick_Handler(在啟動文件:startup_stm32f10x_hd.s中) * * 而在port.c里面寫的這三個中斷的服務函數的名稱跟向量表里面的名稱不一樣,為了中斷響應之后能正確的執行port.c * 里面寫好的中斷服務函數,我們需要統一向量表和中斷服務函數的名字。 * * 為了實現這個目的,可以有兩種方法: * 1:把啟動文件里面的向量表里面的名字改成跟port.c里面的中斷服務函數名一樣。 * 2:把port.c里面的中斷服務函數名改成跟啟動文件里面的中斷向量表里面的名字一樣。 * * 這里為了保持啟動文件的完整性,我們統一修改port.c里面的中斷函數名,即添加下面三個宏定義即可。 * 如果你在stm32f10x_it.c這里面實現了這三個中斷服務函數的定義的話,那么為了避免跟port.c里面的重復定義,應該 * 把stm32f4xx_it.c里面的注釋掉。 */ #define vPortSVCHandler SVC_Handler #define xPortPendSVHandler PendSV_Handler #define xPortSysTickHandler SysTick_Handler #endif /* FREERTOS_CONFIG_H */
至此,移植准備工作完成,只需要用實驗來測試了。
Best practice:
我知道第一次移植的時候有很多不懂,很多疑惑,但是現在先知道這樣做,后面隨着熟練程度增加,就會懂得更多了。比如,我們剛學C語言的時候,第一個hello world!程序,我們也只是知道需要包含stdio.h,就可以printf輸出到屏幕,但是如果我們一開始學習C語言就去糾結為什么printf可以輸出到屏幕,這樣不是一來就讓人放棄了嗎?所以,剛開始的時候,帶着疑問,繼續學習,學得越多,有些基礎的疑惑總會越少的。
以上轉載自野火和正點原子PDF資料。