移植FreeRTOS到STM32
- 1、前言
- 2、獲取 STM32 的裸機工程模板
- 3、下載 FreeRTOS V9.0.0 源碼
- 4、FreeRTOS文件夾內容簡介
- 5、移植FreeRTOS
- 5.1 更改STM32工程模板文件夾名字
- 5.2 提取FreeRTOS最簡源碼
- 5.3 拷貝 FreeRTOSConfig.h 文件到 user 文件夾
- 5.4 添加 FreeRTOS 源碼到工程組文件夾
- 5.5 指定 FreeRTOS 頭文件的路徑
- 5.6 修改FreeRTOSConfig.h文件
- 5.7 修改main函數
- 6、倉庫地址
- 6、總結
1、前言
記錄一下移植FreeRTOS到STM32的過程,方便自己日后回顧,也可以給有需要的人提供幫助。每個目錄都是知識點,大家可以按照目錄逐步瀏覽,也可以點擊目錄跳轉到所需部分。 |
2、獲取 STM32 的裸機工程模板
我是直接使用野火 STM32 開發板配套的固件庫例程中的GPIO 輸出—使用固件庫點亮 LED工程模板,有需要可以私信我,我也會把這個工程放到倉庫里,,也可以去倉庫里下載 |
3、下載 FreeRTOS V9.0.0 源碼
可以通過官網和代碼托管網站下載,也可以下載我倉庫里面的,下載V9.0.0版本就可以,下面的圖片是代碼托管網站的下載步驟 |
官網
代碼托管網站
點擊進去后下載zip文件 |
4、FreeRTOS文件夾內容簡介
解壓zip文件后,有下列的文件,FreeRTOS-Plus文件夾是一些第三方的產品 |
FreeRTOS文件夾下有下列文件夾 |
Source文件夾:存放內核源碼,最重要的文件夾Demo文件夾:各種開發平臺的完整Demo,開發者可以方便的以此搭建出自己的項目,甚至直接使用。License文件夾:這里面只有一個許可文件“license.txt”,用FreeRTOS做產品的話就需要看看這個文件。
點擊進去Source文件夾 |
include文件夾:FreeRTOS 的通用的頭文件portable文件夾:與編譯器相關的文件,keil編譯環境,使用RVDS文件夾
5、移植FreeRTOS
5.1 更改STM32工程模板文件夾名字
把固件庫點燈那個文件夾名字改為移植FreeRTOS模板 |
5.2 提取FreeRTOS最簡源碼
在移植FreeRTOS模板文件夾下新建一個FreeRTOS文件夾,再在FreeRTOS文件夾下創建一個src文件夾,用于存放源碼。 |
把FreeRTOS文件夾下的所有.c文件到src文件夾下 |
再新建一個port文件夾,把源碼中的RVDS和MemMang文件夾放到port文件夾下 |
再把FreeRTOS源碼下的include文件夾復制到模板文件夾下 |
5.3 拷貝 FreeRTOSConfig.h 文件到 user 文件夾
打開 FreeRTOSv9.0.0 源碼,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夾下面找到 “ CORTEX_STM32F103_Keil ” 這 個 文 件 夾 , 雙 擊 打 開 , 在 其 根 目 錄 下 找 到 這 個 “FreeRTOSConfig.h”文件,然后拷貝到我們工程的 user 文件夾下即可 |
5.4 添加 FreeRTOS 源碼到工程組文件夾
打開工程,創建建 FreeRTOS/src 和 FreeRTOS/port 兩個組文件夾,再把相關文件添加進去 |
注:port\RVDS\ARM_CM文件夾,根據自己的開發板選擇相應的文件夾,比如我的是STM32F103VET6,就選擇port\RVDS\ARM_CM3
把FreeRTOSConfig.h添加到USER分組下 |
5.5 指定 FreeRTOS 頭文件的路徑
將FreeRTOS\include 和FreeRTOS\port\RVDS\ARM_CM3路徑添加到開發環境中 |
5.6 修改FreeRTOSConfig.h文件
用野火的指南者FreeRTOSConfig.h文件替換掉源碼的FreeRTOSConfig.h文件 |
野火指南著FreeRTOSConfig.h文件代碼
/*FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.All rights reservedVISIT 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 underthe terms of the GNU General Public License (version 2) as published by theFree 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 ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE. Full license text is available on the followinglink: 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 readingthe FAQ page "My application does not run, what could be wrong?". Have youdefined configASSERT()?http://www.FreeRTOS.org/support - In return for receiving this top qualityembedded software for free we request you assist our global community byparticipating in the support forum.http://www.FreeRTOS.org/training - Investing in training allows your team tobe as productive as possible as early as possible. Now you can receiveFreeRTOS training directly from Richard Barry, CEO of Real Time EngineersLtd, 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 DOScompatible 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 HighIntegrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOSlicenses offer ticketed support, indemnification and commercial middleware.http://www.SafeRTOS.com - High Integrity Systems also provide a safetyengineered and independently SIL3 certified version for use in safety andmission critical applications that require provable dependability.*/#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H#include "stm32f10x.h"
#include "bsp_usart.h"//針對不同的編譯器調用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif//斷言
#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)/************************************************************************* FreeRTOS基礎配置配置選項 *********************************************************************/
/* 置1:RTOS使用搶占式調度器;置0:RTOS使用協作式調度器(時間片)* * 注:在多任務管理機制上,操作系統可以分為搶占式和協作式兩種。* 協作式操作系統是任務主動釋放CPU后,切換到下一個任務。* 任務切換的時機完全取決于正在運行的任務。*/
#define configUSE_PREEMPTION 1//1使能時間片調度(默認式使能的)
#define configUSE_TIME_SLICING 1 /* 某些運行FreeRTOS的硬件有兩種方法選擇下一個要執行的任務:* 通用方法和特定于硬件的方法(以下簡稱“特殊方法”)。* * 通用方法:* 1.configUSE_PORT_OPTIMISED_TASK_SELECTION 為 0 或者硬件不支持這種特殊方法。* 2.可以用于所有FreeRTOS支持的硬件* 3.完全用C實現,效率略低于特殊方法。* 4.不強制要求限制最大可用優先級數目* 特殊方法:* 1.必須將configUSE_PORT_OPTIMISED_TASK_SELECTION設置為1。* 2.依賴一個或多個特定架構的匯編指令(一般是類似計算前導零[CLZ]指令)。* 3.比通用方法更高效* 4.一般強制限定最大可用優先級數目為32* 一般是硬件計算前導零指令,如果所使用的,MCU沒有這些硬件指令的話此宏應該設置為0!*/
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 /* 置1:使能低功耗tickless模式;置0:保持系統節拍(tick)中斷一直運行* 假設開啟低功耗的話可能會導致下載出現問題,因為程序在睡眠中,可用以下辦法解決* * 下載方法:* 1.將開發版正常連接好* 2.按住復位按鍵,點擊下載瞬間松開復位按鍵* * 1.通過跳線帽將 BOOT 0 接高電平(3.3V)* 2.重新上電,下載* * 1.使用FlyMcu擦除一下芯片,然后進行下載* STMISP -> 清除芯片(z)*/
#define configUSE_TICKLESS_IDLE 0 /** 寫入實際的CPU內核時鐘頻率,也就是CPU指令執行頻率,通常稱為Fclk* Fclk為供給CPU內核的時鐘信號,我們所說的cpu主頻為 XX MHz,* 就是指的這個時鐘信號,相應的,1/Fclk即為cpu時鐘周期;*/
#define configCPU_CLOCK_HZ (SystemCoreClock)//RTOS系統節拍中斷的頻率。即一秒中斷的次數,每次中斷RTOS都會進行任務調度
#define configTICK_RATE_HZ (( TickType_t )1000)//可使用的最大優先級
#define configMAX_PRIORITIES (32)//空閑任務使用的堆棧大小
#define configMINIMAL_STACK_SIZE ((unsigned short)128)//任務名字字符串長度
#define configMAX_TASK_NAME_LEN (16)//系統節拍計數器變量數據類型,1表示為16位無符號整形,0表示為32位無符號整形
#define configUSE_16_BIT_TICKS 0 //空閑任務放棄CPU使用權給其他同優先級的用戶任務
#define configIDLE_SHOULD_YIELD 1 //啟用隊列
#define configUSE_QUEUE_SETS 0 //開啟任務通知功能,默認開啟
#define configUSE_TASK_NOTIFICATIONS 1 //使用互斥信號量
#define configUSE_MUTEXES 0 //使用遞歸互斥信號量
#define configUSE_RECURSIVE_MUTEXES 0 //為1時使用計數信號量
#define configUSE_COUNTING_SEMAPHORES 0/* 設置可以注冊的信號量和消息隊列個數 */
#define configQUEUE_REGISTRY_SIZE 10 #define configUSE_APPLICATION_TASK_TAG 0 /*****************************************************************FreeRTOS與內存申請有關配置選項
*****************************************************************/
//支持動態內存申請
#define configSUPPORT_DYNAMIC_ALLOCATION 1
//支持靜態內存
#define configSUPPORT_STATIC_ALLOCATION 0
//系統所有總的堆大小
#define configTOTAL_HEAP_SIZE ((size_t)(36*1024)) /***************************************************************FreeRTOS與鉤子函數有關的配置選項
**************************************************************/
/* 置1:使用空閑鉤子(Idle Hook類似于回調函數);置0:忽略空閑鉤子* * 空閑任務鉤子是一個函數,這個函數由用戶來實現,* FreeRTOS規定了函數的名字和參數:void vApplicationIdleHook(void ),* 這個函數在每個空閑任務周期都會被調用* 對于已經刪除的RTOS任務,空閑任務可以釋放分配給它們的堆棧內存。* 因此必須保證空閑任務可以被CPU執行* 使用空閑鉤子函數設置CPU進入省電模式是很常見的* 不可以調用會引起空閑任務阻塞的API函數*/
#define configUSE_IDLE_HOOK 0 /* 置1:使用時間片鉤子(Tick Hook);置0:忽略時間片鉤子* * * 時間片鉤子是一個函數,這個函數由用戶來實現,* FreeRTOS規定了函數的名字和參數:void vApplicationTickHook(void )* 時間片中斷可以周期性的調用* 函數必須非常短小,不能大量使用堆棧,* 不能調用以”FromISR" 或 "FROM_ISR”結尾的API函數*//*xTaskIncrementTick函數是在xPortSysTickHandler中斷函數中被調用的。因此,vApplicationTickHook()函數執行的時間必須很短才行*/
#define configUSE_TICK_HOOK 0 //使用內存申請失敗鉤子函數
#define configUSE_MALLOC_FAILED_HOOK 0 /** 大于0時啟用堆棧溢出檢測功能,如果使用此功能 * 用戶必須提供一個棧溢出鉤子函數,如果使用的話* 此值可以為1或者2,因為有兩種棧溢出檢測方法 */
#define configCHECK_FOR_STACK_OVERFLOW 0 /********************************************************************FreeRTOS與運行時間和任務狀態收集有關的配置選項
**********************************************************************/
//啟用運行時間統計功能
#define configGENERATE_RUN_TIME_STATS 0 //啟用可視化跟蹤調試
#define configUSE_TRACE_FACILITY 0
/* 與宏configUSE_TRACE_FACILITY同時為1時會編譯下面3個函數* prvWriteNameToBuffer()* vTaskList(),* vTaskGetRunTimeStats()
*/
#define configUSE_STATS_FORMATTING_FUNCTIONS 1 /********************************************************************FreeRTOS與協程有關的配置選項
*********************************************************************/
//啟用協程,啟用協程以后必須添加文件croutine.c
#define configUSE_CO_ROUTINES 0
//協程的有效優先級數目
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) /***********************************************************************FreeRTOS與軟件定時器有關的配置選項
**********************************************************************///啟用軟件定時器
#define configUSE_TIMERS 0
//軟件定時器優先級
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1)
//軟件定時器隊列長度
#define configTIMER_QUEUE_LENGTH 10
//軟件定時器任務堆棧大小
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2) /************************************************************FreeRTOS可選函數配置選項
************************************************************/
#define INCLUDE_xTaskGetSchedulerState 1
#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
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xTimerPendFunctionCall 0
//#define INCLUDE_xTaskGetCurrentTaskHandle 1
//#define INCLUDE_uxTaskGetStackHighWaterMark 0
//#define INCLUDE_xTaskGetIdleTaskHandle 0/******************************************************************FreeRTOS與中斷有關的配置選項
******************************************************************/
#ifdef __NVIC_PRIO_BITS#define configPRIO_BITS __NVIC_PRIO_BITS
#else#define configPRIO_BITS 4
#endif
//中斷最低優先級
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //系統可管理的最高中斷優先級
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )/****************************************************************FreeRTOS與中斷服務函數有關的配置選項
****************************************************************/
#define xPortPendSVHandler PendSV_Handler
#define vPortSVCHandler SVC_Handler/* 以下為使用Percepio Tracealyzer需要的東西,不需要時將 configUSE_TRACE_FACILITY 定義為 0 */
#if ( configUSE_TRACE_FACILITY == 1 )
#include "trcRecorder.h"
#define INCLUDE_xTaskGetCurrentTaskHandle 1 // 啟用一個可選函數(該函數被 Trace源碼使用,默認該值為0 表示不用)
#endif#endif /* FREERTOS_CONFIG_H */
缺少usart文件,找到野火標準庫的串口文件夾 |
按照下面這個目錄找到usart這兩個文件 |
在工程模板下的User文件夾下創建個usart文件夾,再把這兩個文件復制到usart文件夾下 |
把usart文件添加到工程下 |
再把usart文件夾目錄添加進去 |
在 port.c 文件中已經實現 xPortPendSVHandler()與 vPortSVCHandler() 函數,防止我們自己實現不了,那么在 stm32f10x_it.c 中就需要我們注釋掉 PendSV_Handler()與 SVC_Handler()這兩個函數了 |
編譯后0錯誤0警告,移植成功 |
修改stm32f10x_it.c文件下的SysTick_Handler()函數 |
void xPortSysTickHandler( void );void SysTick_Handler(void)
{#if (INCLUDE_xTaskGetSchedulerState == 1 )if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){#endif /* INCLUDE_xTaskGetSchedulerState */ xPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState == 1 )}#endif /* INCLUDE_xTaskGetSchedulerState */
}
把#include "FreeRTOS.h"和#include "task.h"這兩個頭文件添加到stm32f10x_it.c文件下 |
5.7 修改main函數
把這兩個頭文件也添加到main文件下 |
mian()函數里面的東西都刪掉,剩個main就行 |
6、倉庫地址
倉庫地址
6、總結
以上就是移植FreeRTOS到STM32的整個過程了,相關的文件我會放到倉庫中,瀏覽過程中,如若發現錯誤,歡迎大家指正,有問題的歡迎評論區留言或者私信。最后,如果大家覺得有所幫助,可以點一下贊,謝謝大家!祝大家天天開心,順遂無虞! |