FreeRTOS菜鳥入門(六)·移植FreeRTOS到STM32

目錄

1.? 獲取裸機工程模版

2.??下載 FreeRTOS V9.0.0 源碼

3.? FreeRTOS文件夾內容簡介

3.1? FreeRTOS文件夾

3.1.1? Demo文件夾

3.1.2??License 文件夾

3.1.3??Source 文件夾

3.2? FreeRTOS-Plus 文件夾

4.? 往裸機工程添加 FreeRTOS 源碼

5.??拷貝 FreeRTOSConfig.h 文件到 user 文件夾

6.??添加 FreeRTOS 源碼到工程組文件夾

6.1??新建 FreeRTOS/src 和 FreeRTOS/port 組

6.2??指定 FreeRTOS 頭文件的路徑

7.??修改 FreeRTOSConfig.h

8.? 修改 stm32f10x_it.c


1.? 獲取裸機工程模版

? ? ? ? 這里我使用的是STM32F103ZET6的開發板,找了一個點亮LED的工程模版進行更改,自己隨便找一個模版都行,沒必要一定一樣:

STM32f103ZET6移植工程模版資源-CSDN文庫

2.??下載 FreeRTOS V9.0.0 源碼

????????在移植之前,我們首先要獲取到 FreeRTOS 的官方的源碼包。這里我們提供兩個下載鏈接:

官網鏈接:www.freertos.org

代碼托管網站:sourceforge.net

????????打開網站鏈接之后,我們選擇 FreeRTOS 的最新版本 V9.0.0(2016 年),盡管現在 FreeRTOS 的版本已經更新到 V10.0.1 了,但是我們還是選擇 V9.0.0,因為內核很穩定,并且網上資料很多,因為 V10.0.0 版本之后是亞馬遜收購了 FreeRTOS 之后才出來的版本,主要添加了一些云端組件:

????????點擊 V9.0.0 會跳轉到版本目錄。這里有 zip 和 exe 格式的壓縮包,其實都是 FreeRTOS 的源碼,只是壓縮的格式不一樣,所以大小也不一樣,我們這里選擇 zip 的下載,點擊了就會出現下載的鏈接,下載完成解壓后就可以得到我們想要的 FreeRTOS V9.0.0 版本的源碼了:

有時候網站打不開,所以附帶一個百度網盤的鏈接:

鏈接: https://pan.baidu.com/s/1G4ezuX0Thwy-kUarMqYYFg?pwd=svii

提取碼: svii?

需要注意一點,該文件可能路徑過長電腦自帶的解壓文件可能無法解壓,試驗過360解壓的軟件能解壓,如果是在無法解壓,后續也會附上配置好的文件。

3.? FreeRTOS文件夾內容簡介

3.1? FreeRTOS文件夾

????????FreeRTOS 包含 Demo 例程和內核源碼(比較重要,我們就需要提取該目錄下的大部分文件):

????????FreeRTOS 文件夾下的 Source 文件夾里面包含的是 FreeRTOS 內核的源代碼,我們移植 FreeRTOS 的時候就需要這部分源代碼;FreeRTOS 文件夾下的Demo 文件夾里面包含了FreeRTOS 官方為各個單片機移植好的工程代碼,FreeRTOS 為了推廣自己,會給各種半導體廠商的評估板寫好完整的工程程序,這些程序就放在 Demo 這個目錄下,這部分 Demo 非常有參考價值。我們把 FreeRTOS 到 STM32 的時候,FreeRTOSConfig.h 這個頭文件就是從這里拷貝過來的。

3.1.1? Demo文件夾

????????這個目錄下內容就是 Deme 例程,我們可以直接打開里面的工程文件,各種開發平臺的完整 Demo,開發者可以方便的以此搭建出自己的項目,甚至直接使用。FreeRTOS 當然也為 ST 寫了很多 Demo,其中就有 F1、F4、F7 等工程,這樣子對我們學習 FreeRTOS 是非常方便的,當遇到不懂的直接就可以參考官方的 Demo:

3.1.2??License 文件夾

????????這里面只有一個許可文件“license.txt”,用 FreeRTOS 做產品的話就需要看看這個文件,但是我們是學習 FreeRTOS,所以暫時不需要理會這個文件。

3.1.3??Source 文件夾

????????這里我們再重點分析下 FreeRTOS/ Source 文件夾下的文件,其中include文件和下圖框柱的文件包含的是FreeRTOS 的通用的頭文件和 C 文件這兩部分的文件試用于各種編譯器和處理器,是通用的。

? ? ? ? 而需要移植的頭文件和 C文件放在portblle 這個文件夾:

????????我們打開 portblle 這個文件夾,可以看到里面很多與編譯器相關的文件夾,在不同的編譯器中使用不同的支持文件:

????????KEIL 就是我們就是我們使用的編譯器,當年打開 KEIL 文件夾的時候,你會看到一句話“See-also-the-RVDS-directory.txt”,其實 KEIL里面的內容跟 RVDS 里面的內容一樣,所以,我們只需要編號RVDS 文件夾里面的內容即可。而編號MemMang 文件夾下存放的是跟內存管理相關的。

????????打開 RVDS 文件夾,下面包含了各種處理器相關的文件夾,從文件夾的名字我們就非常熟悉了,我們學習的 STM32 有 M0、M3、M4 等各種系列,FreeRTOS 是一個軟件,單片機是一個硬件,FreeRTOS 要想運行在一個單片機上面,它們就必須關聯在一起,那么怎么關聯?還是得通過寫代碼來關聯,這部分關聯的文件叫接口文件,通常由匯編和 C 聯合編寫。這些接口文件都是跟硬件密切相關的,不同的硬件接口文件是不一樣的,但都大同小異。編寫這些接口文件的過程我們就叫移植,移植的過程通常由 FreeRTOS 和 mcu 原廠的人來負責,移植好的這些接口文件就放在 RVDS 這個文件夾的目錄下:

????????MemMang 文件夾下存放的是跟內存管理相關的,總共有五個 heap 文件以及一個 readme 說明文件,這五個 heap 文件在移植的時候必須使用一個,因為 FreeRTOS 在創建內核對象的時候使用的是動態分配內存,而這些動態內存分配的函數則在這幾個文件里面實現,不同的分配算法會導致不同的效率與結果,后面在內存管理中我們會講解每個文件的區別,由于現在是初學,所以我們選用 heap4.c 即可:

3.2? FreeRTOS-Plus 文件夾

????????FreeRTOS-Plus 文件夾里面包含的是第三方的產品,一般我們不需要使用,FreeRTOSPlus 的預配置演示項目組件(組件大多數都要收費),大多數演示項目都是在 Windows 環境中運行的,使用 FreeRTOS windows 模擬器,所以暫時不需要關注這個文件夾。

4.? 往裸機工程添加 FreeRTOS 源碼

????????首先在我們的STM32 裸機工程模板根目錄下新建一個文件夾,命名 為“FreeRTOS”,并且在 FreeRTOS 文件夾下新建兩個空文件夾,分別命名為“src”與“port”,src 文件夾用于保存 FreeRTOS 中的核心源文件,也就是我們常說的‘.c 文件’,port 文件夾用于保存內存管理以及處理器架構相關代碼,這些代碼FreeRTOS 官方已經提供給我們的,直接使用即可,在前面已經說了,FreeRTOS是軟件,我們的開發版是硬件,軟硬件必須有橋梁來連接,這些與處理器架構相關的代碼,可以稱之為 RTOS 硬件接口層,它們位于 FreeRTOS/Source/Portable 文件夾下。

????????打開 FreeRTOS V9.0.0 源碼,在“FreeRTOSv9.0.0\FreeRTOS\Source”目錄下找到所有的‘.c 文件’:

????????打開 FreeRTOS V9.0.0 源碼,在“FreeRTOSv9.0.0\FreeRTOS\Source\portable”目錄下找到“MemMang”文件夾與“RVDS”文件夾,將它們拷貝到我們新建的 port 文件夾中,具體見:

????????打開 FreeRTOS V9.0.0 源碼,在“FreeRTOSv9.0.0\ FreeRTOS\Source”目錄下找到“include”文件夾,它是我們需要用到 FreeRTOS 的一些頭文件,將它直接拷貝到我們新建的 FreeRTOS 文件夾中,完成這一步之后就可以看到我們新建的 FreeRTOS 文件夾已經有 3 個文件夾,這 3個文件夾就包含 FreeRTOS 的核心文件,至此,FreeRTOS 的源碼就提取完成:

5.??拷貝 FreeRTOSConfig.h 文件到 user 文件夾

????????FreeRTOSConfig.h 文件是 FreeRTOS 的工程配置文件,因為 FreeRTOS 是可以裁剪的實時操作內核,應用于不同的處理器平臺,用戶可以通過修改這個 FreeRTOS 內核的配置頭文件來裁剪 FreeRTOS 的功能,所以我們把它拷貝一份放在 user 這個文件夾下面。

????????打開 FreeRTOSv9.0.0 源碼,在“FreeRTOSv9.0.0\FreeRTOS\Demo”文件夾下面找到“ CORTEX_STM32F103_Keil ” 這個文件夾 ,雙擊打開 , 在其根目錄下找到這個“FreeRTOSConfig.h”文件,然后拷貝到我們工程的 user 文件夾下即可,等下我們需要對這個文件進行修改。user 文件夾,見名知義我們就可以知道里面存放的文件都是用戶自己編寫的。

6.??添加 FreeRTOS 源碼到工程組文件夾

????????在上一步我們只是將 FreeRTOS 的源碼放到了本地工程目錄下,還沒有添加到開發環境里面的組文件夾里面,FreeRTOS 也就沒有移植到我們的工程中去。

6.1??新建 FreeRTOS/src 和 FreeRTOS/port 組

????????接下來我們在開發環境里面新建 FreeRTOS/src 和 FreeRTOS/port 兩個組文件夾:

????????其中FreeRTOS/src 用于存放 src 文件夾的內容:

????????FreeRTOS/port 用于存放 port\MemMang 文件夾與 port\RVDS\ARM_CM3文件夾的內容:

? ? ? ? 添加完成如下:

? ? ? ? 再將FreeRTOSConfig.h文件,放到user文件夾下:

6.2??指定 FreeRTOS 頭文件的路徑

????????FreeRTOS 的源碼已經添加到開發環境的組文件夾下面,編譯的時候需要為這些源文件指定頭文件的路徑,不然編譯會報錯。FreeRTOS 的源碼里面只有 FreeRTOS\include 和 FreeRTOS\port\RVDS\ARM_CM3這兩個文件夾下面有頭文件,只需要將這兩個頭文件的路徑在開發環境里面指定即可。同時我們還將 FreeRTOSConfig.h 這個頭文件拷貝到了工程根目錄下的 user 文件夾下,所以 user 的路徑也要加到開發環境里面:

7.??修改 FreeRTOSConfig.h

????????FreeRTOSConfig.h 是直接從 demo 文件夾下面拷貝過來的,該頭文件對裁剪整個 FreeRTOS 所需的功能的宏均做了定義,有些宏定義被使能,有些宏定義被失能,一開始我們只需要配置最簡單的功能即可。要想隨心所欲的配置 FreeRTOS 的功能,我們必須對這些宏定義的功能有所掌握,下面我們先簡單的介紹下這些宏定義的含義,然后再對這些宏定義進行修改。

/*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 "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 */

部分代碼解析:

//針對不同的編譯器調用不同的stdint.h文件
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif

針對不同的編譯器調用不同的 stdint.h 文件,在 MDK 中,我們默認的是__CC_ARM。


//斷言
#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)
#define configASSERT(x) if((x)==0) vAssertCalled(__FILE__,__LINE__)

????????在使用 C 語言編寫工程代碼時,我們總會對某種假設條件進行檢查,斷言就是用于在代碼中捕捉這些假設,可以將斷言看作是異常處理的一種高級形式。斷言表示為一些布爾表達式,程序員相信在程序中的某個特定表達式值為真。可以在任何時候啟用和禁用斷言驗證,因此可以在測試時啟用斷言,而在發布時禁用斷言。同樣,程序投入運行后,最終用戶在遇到問題時可以重新啟用斷言。它可以快速發現并定位軟件問題,同時對系統錯誤進行自動報警。斷言可以對在系統中隱藏很深,用其它手段極難發現的問題可以用斷言來進行定位,從而縮短軟件問題定位時間,提高系統的可測性。實際應用時,可根據具體情況靈活地設計斷言。這里只是使用宏定義實現了斷言的功能,斷言作用很大,特別是在調試的時候,而 FreeRTOS 中使用了很多斷言接口 configASSERT,所以我們需要實現斷言,把錯誤信息打印出來從而在調試中快速定位,打印信息的內容是xxx 文件 xxx 行(__FILE__,__LINE__)。

? ? ? ? 簡單來說就是查找報錯,打印錯誤。


#define configUSE_PREEMPTION					  1

????????置1:RTOS使用搶占式調度器;置0:RTOS使用協作式調度器(時間片)

????????搶占式調度:在這種調度方式中,系統總是選擇優先級最高的任務進行調度,并且 一旦高優先級的任務準備就緒之后,它就會馬上被調度而不等待低優先級的任務主動放棄 CPU,高優先級的任務搶占了低優先級任務的 CPU 使用權,這就是搶占,在實習操作系統中,這樣子的方式往往是最適用的。

????????協作式調度:則是由任務主動放棄CPU,然后才進行任務調度。


#define configUSE_TIME_SLICING					1	

????????使能時間片調度(默認式使能的)。當優先級相同的時候,就會采用時間片調度,這意味著 RTOS 調度器總是運行處于最高優先級的就緒任務,在每個FreeRTOS 系統節拍中斷時在相同優先級的多個任務間進行任務切換。如果宏configUSE_TIME_SLICING 設置為 0,FreeRTOS 調度器仍然總是運行處于最高優先級的就緒任務,但是當 RTOS 系統節拍中斷發生時,相同優先級的多個任務之間不再進行任務切換,而是在執行完高優先級的任務之后才進行任務切換。一般來說,FreeRTOS 默認支持 32 個優先級,很少情況會把 32 個優先級全用完,所以,官方建議采用搶占式調度。


8.? 修改 stm32f10x_it.c

? ? ? ? 首先我們先導入串口文件,我們這里使用野火的串口文件,它的一個宏定義感覺非常方便,別的也可以,進行導入:

? ? ? ? 運行后會發現這兩個報錯:

? ? ? ? 因為SysTick 中斷服務函數是一個非常重要的函數,FreeRTOS 所有跟時間相關的事情都在里面處理,SysTick 就是 FreeRTOS 的一個心跳時鐘,驅動著 FreeRTOS 的運行,就像人的心跳一樣,假如沒有心跳,我們就相當于“死了”,同樣的,FreeRTOS 沒有了心跳,那么它就會卡死在某個地方,不能進行任務調度,不能運行任何的東西,因此我們需要實現一個 FreeRTOS 的心跳時鐘,FreeRTOS 幫我們實現了 SysTick 的啟動的配置:在 port.c 文件中已經實現 vPortSetupTimerInterrupt()函數,并且 FreeRTOS 通用的 SysTick 中斷服務函數也實現了:在 port.c 文件中已經實現 xPortSysTickHandler()函數,所以移植的時候只需要我們在 stm32f10x_it.c 文件中實現我們對應(STM32)平臺上的 SysTick_Handler()函數即可。FreeRTOS 為開發者考慮得特別多,PendSV_Handler()與 SVC_Handler()這兩個很重要的函數都幫我們實現了,在 port.c 文件中已經實現 xPortPendSVHandler()與 vPortSVCHandler()函數,防止我們自己實現不了,那么在 stm32f10x_it.c 中就需要我們注釋掉PendSV_Handler()與 SVC_Handler()這兩個函數了:

/********************************************************************************* @file    Project/STM32F10x_StdPeriph_Template/stm32f10x_it.c * @author  MCD Application Team* @version V3.5.0* @date    08-April-2011* @brief   Main Interrupt Service Routines.*          This file provides template for all exceptions handler and *          peripherals interrupt service routine.******************************************************************************* @attention** THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.** <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "FreeRTOS.h"					 
#include "task.h" 
/** @addtogroup STM32F10x_StdPeriph_Template* @{*//* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************//*** @brief  This function handles NMI exception.* @param  None* @retval None*/
void NMI_Handler(void)
{
}/*** @brief  This function handles Hard Fault exception.* @param  None* @retval None*/
void HardFault_Handler(void)
{/* Go to infinite loop when Hard Fault exception occurs */while (1){}
}/*** @brief  This function handles Memory Manage exception.* @param  None* @retval None*/
void MemManage_Handler(void)
{/* Go to infinite loop when Memory Manage exception occurs */while (1){}
}/*** @brief  This function handles Bus Fault exception.* @param  None* @retval None*/
void BusFault_Handler(void)
{/* Go to infinite loop when Bus Fault exception occurs */while (1){}
}/*** @brief  This function handles Usage Fault exception.* @param  None* @retval None*/
void UsageFault_Handler(void)
{/* Go to infinite loop when Usage Fault exception occurs */while (1){}
}/*** @brief  This function handles SVCall exception.* @param  None* @retval None*/
//void SVC_Handler(void)
//{
//}/*** @brief  This function handles Debug Monitor exception.* @param  None* @retval None*/
void DebugMon_Handler(void)
{
}/*** @brief  This function handles PendSVC exception.* @param  None* @retval None*/
//void PendSV_Handler(void)
//{
//}/*** @brief  This function handles SysTick Handler.* @param  None* @retval None*/
extern void xPortSysTickHandler(void);
//systick中斷服務函數
void SysTick_Handler(void)
{	#if (INCLUDE_xTaskGetSchedulerState  == 1 )if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){#endif  /* INCLUDE_xTaskGetSchedulerState */  xPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState  == 1 )}#endif  /* INCLUDE_xTaskGetSchedulerState */
}/******************************************************************************/
/*                 STM32F10x Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f10x_xx.s).                                            */
/******************************************************************************//*** @brief  This function handles PPP interrupt request.* @param  None* @retval None*/
/*void PPP_IRQHandler(void)
{
}*//*** @}*/ /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

? ? ? ? 這時候在運行報錯解決了。

工程模版:

STM32F103ZET6的FreeRTOS工程移植模版資源-CSDN文庫

FreeRTOS實時操作系統_時光の塵的博客-CSDN博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/80440.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/80440.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/80440.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

通過 Tailwind CSS 自定義樣式 實現深色模式切換

創建vite項目或者vue-cli配置大同小異 1、當前環境 Vue.js 3.5nuxtjs/tailwindcss 6.13.1nuxt3.15.4node18 這里主要依賴是tailwindcss 因為當前項目是使用nuxt開發。 2、配置顏色模式 在assets/css下創建main.css * {padding: 0;margin: 0;box-sizing: border-box; }[dat…

PWNOS:2.0(vulnhub靶機)

文章目錄 靶機地址主機發現、端口掃描web滲透目錄探測漏洞利用權限提升 解密工具地址總結 靶機地址 https://download.vulnhub.com/pwnos/pWnOS_v2.0.7z 這里如果是windows系統直接使用vmware或者virtubox打開可以使用,如果是mac系統需再去做一個配置&#xff0c;比較麻煩 這里…

Gartner魔力象限(Gartner Magic Quadrant)

Gartner魔力象限&#xff08;Gartner Magic Quadrant&#xff09;是由全球領先的研究和咨詢公司Gartner發布的市場研究報告&#xff0c;廣泛應用于IT行業&#xff0c;尤其是在技術供應商評估中。它以圖形化的方式展示了不同技術領域中各個供應商的市場表現&#xff0c;幫助企業…

信創時代開發工具選擇指南:國產替代背景下的技術生態與實踐路徑

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#, Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開…

人口老齡化丨AI健康小屋如何實現防病于未然?

隨著全球老齡化加劇&#xff0c;“銀發浪潮” 對醫療資源、養老護理和健康管理提出了嚴峻挑戰。 由此智紳科技應運而生&#xff0c;七彩喜智慧養老系統構筑居家養老安全網。 AI 健康小屋作為銀發科技的創新載體&#xff0c;通過智能化健康監測、精準化風險預警、便捷化醫療銜…

【金倉數據庫征文】金倉數據庫:開啟未來技術腦洞,探索數據庫無限可能

我的個人主頁 我的專欄&#xff1a; 人工智能領域、java-數據結構、Javase、C語言&#xff0c;希望能幫助到大家&#xff01;&#xff01;&#xff01; 點贊&#x1f44d;收藏? 目錄 引言&#xff1a;數據庫進化的下一站 —— 未來科技的無限可能金倉數據庫簡介&#xff1a;國…

#什么是爬蟲?——從技術原理到現實應用的全面解析 VI

什么是爬蟲?——從技術原理到現實應用的全面解析 V 二十六、異構數據采集技術突破 26.1 PDF文本與表格提取 import pdfplumber import pandas as pddef extract_pdf_data(pdf_path):"""從PDF中提取文本和表格數據:param pdf_path: PDF文件路徑:return: 包含…

關于Spring Boot構建項目的相關知識

一 前端框架 1 VUE框架 1.1 簡介 Vue是一款流行的JavaScript框架&#xff0c;用于構建用戶界面和單頁面應用程序。它的設計初衷是為了簡化Web開發過程&#xff0c;使開發者能夠快速構建交互性強、響應速度快的Web應用。 1.2 優點 簡單易用&am…

PPO 強化學習機械臂 IK 訓練過程可視化利器 Tensorboard

視頻講解&#xff1a; PPO 強化學習機械臂 IK 訓練過程可視化利器 Tensorboard PPO 強化學習過程中&#xff0c;設置了verbose會顯示數據&#xff0c;但還是不夠直觀&#xff0c;這里上一個可視化利器&#xff0c;Tensorboard&#xff0c;實際上stable baselines3中已經有了這部…

UE5的 Modify Curve 藍圖節點

In Unreal Engine’s Animation Blueprints, the Modify Curve node lets you drive and alter any named Animation Curve on your character at runtime. The Apply Mode setting on that node controls how the “new” value you feed in (via the added curve‐input pin)…

【Hive入門】Hive分區與分區表完全指南:從原理到企業級實踐

引言 在大數據時代&#xff0c;高效管理海量數據成為企業面臨的核心挑戰。Hive作為Hadoop生態系統中最受歡迎的數據倉庫解決方案&#xff0c;其分區技術是優化數據查詢和管理的關鍵手段。本文將全面解析Hive分區技術的原理、實現方式及企業級最佳實踐&#xff0c;幫助您構建高性…

jdk-8u202-linux-x64.tar.gz官方下載地址

https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html 點擊下載&#xff0c;需要先注冊oracle賬號&#xff0c;很好注冊隨便寫&#xff0c;注冊完登錄就可以下載了。目前就Oracle JDK 8u201/202 是最后兩個可免費用于商業用途的公開版本

OpenCv高階(十)——光流估計

文章目錄 前言一、光流估計二、使用步驟1、導庫讀取視頻、隨機初始化顏色2、初始化光流跟蹤3、視頻幀處理循環4、光流計算與可視化5、循環控制與資源釋放完整代碼 總結 前言 在計算機視覺領域&#xff0c;光流估計是捕捉圖像序列中像素點運動信息的核心技術。它描述了圖像中每…

AIGC實戰之如何構建出更好的大模型RAG系統

一、RAG 系統核心架構解析 1. 檢索模塊深度優化 1.1 混合檢索技術實現 技術原理&#xff1a;結合稀疏檢索&#xff08;BM25&#xff09;與密集檢索&#xff08;DPR&#xff09;&#xff0c;通過動態權重分配提升檢索精度。例如&#xff0c;在醫療領域&#xff0c;BM25 負責精…

Rust 學習筆記:函數和控制流

Rust 學習筆記&#xff1a;函數和控制流 Rust 學習筆記&#xff1a;函數和控制流函數&#xff08;Function&#xff09;語句和表達式帶返回值的函數注釋控制流if 表達式使用 else if 處理多個條件在 let 語句中使用 if循環loop從循環中返回值循環標簽消除多個循環之間的歧義帶 …

c#加密證件號的中間部分,改為*號

前言 使用場景&#xff1a;在我項目中&#xff0c;我需要給前端提供接口&#xff0c;所以我要吧證件號進行加密。例如&#xff1a;411421199510225612&#xff0c;這是一個身份證號&#xff0c;18為的&#xff0c;那么我加密完成之后就會是 411421********5612&#xff0c;類似…

存儲新勢力:助力DeepSeek一體機

寶子們&#xff0c;今天要給大家分享一個超酷的科技話題——各大廠商陸續推出的DeepSeek訓推一體機方案。 【集成人工智能訓推平臺】 它就像是一個超級智能的大腦中樞&#xff0c;為各種復雜的AI任務搭建AI模型流水線。預置算法模版、訓練框架、推理框架、模型任務調度和自動…

同樣機身尺寸下伺服電機比無刷電機扭矩更大的原因

點擊下面圖片帶您領略全新的嵌入式學習路線 &#x1f525;爆款熱榜 88萬閱讀 1.6萬收藏 在電機應用領域&#xff0c;伺服電機和無刷電機&#xff08;BLDC&#xff09;都是常見的動力源&#xff0c;但兩者在性能上存在顯著差異。尤其是在相同機身尺寸下&#xff0c;伺服電機的…

.dat 文件一般可以用什么打開

DAT文件是一種常見的文件格式,通常由多種應用程序生成。打開DAT文件的方法取決于其內容和生成它的軟件。 使用文本編輯器 如果DAT文件是一個簡單的文本文件,可以使用Windows的記事本或macOS的文本編輯器打開它。 右鍵點擊文件 -> 選擇“打開方式” -> 選擇“記事本”…