[導讀] 大家好,我是逸珺。
之前挖了圖解freeRTOS的坑,挖了坑就得填。今天就從使用開始,先把freeRTOS用起來。先聊一聊在STM32F407上的如何電燈,如果只用freeRTOS點燈,無疑有點殺雞用牛刀的感覺。但是想用freeRTOS做產品,先照類似步驟則可以驗證最小系統,驗證freeRTOS是否能正確跑起來,再在此基礎上開始做應用開發,就把任務分解了。本文主要梳理一下如何利用官方移植例子,創建一個自己demo工程,對于沒用過的有點參考價值。
注:本文基于IAR for ARM 8.22.1(個人喜歡IAR),硬件采用正點原子的STM32F407探索者開發板,STLink V2。
準備工作去官網https://www.freertos.org/a00104.html下載
按下載,目前最新為202104.00,這個帶多種移植好的例子。解壓出來,是這樣的:
tools為AWS iot配置工具,quick start例子以及cmake
FreeRTOS-Plus包含了MQTT,TCP,FAT等很多例子,先不去管
FreeRTOS為真正的操作系統源碼以及多平臺移植例子,如下:
使用開源軟件,記得看看README,一般會有些介紹信息。分別介紹一下該文件夾下的大體內容:
Demo:大部分硬件平臺的官方移植例子
Source:內核代碼,包含硬件獨立文件與可移植文件
Test:內核測試代碼
license:MIT開源協議,可以直接商業應用。
建立工程1.打開IAR,創建Workspace
2.創建工程
選擇空工程(Empty project),命名為demo保存。
設置工程
右鍵選擇Options,進入設置界面
設置單片機為STM32F407VG
Library Configuration使能CMSIS
添加源文件
4.1 新建freeRTOS文件夾
4.2 添加內核文件,在工程文件夾下新建freeRTOS文件夾,將下列文件拷貝過來
4.3 添加進IAR工程
4.4 將freeRTOS下的include文件夾以及portable文件夾拷貝到當前工程下
4.5 portable文件夾下保留下面這幾個文件夾
4.6 IAR文件夾下保留下面這兩個文件夾
注:全保留也可以,就是其他的用不到,會使工程文件夾變的很大,如果用版本控制軟件管理,會增加倉庫的大小。ARM_CM4F_MPU文件夾暫時沒用,這個留做備用。
4.7 在IAR工程中新建portable文件夾,并加入相應的文件
4.8 將下面幾個文件從官方例子中拷貝過來,并加入工程
FreeRTOSConfig.h是內核配置文件,本文配置如下:
#define configUSE_PREEMPTION 1#define configUSE_IDLE_HOOK 0#define configUSE_TICK_HOOK 0#define configCPU_CLOCK_HZ ( SystemCoreClock )#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )#define configMAX_PRIORITIES ( 5 )#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 130 )#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 75 * 1024 ) )#define configMAX_TASK_NAME_LEN ( 10 )#define configUSE_TRACE_FACILITY 1#define configUSE_16_BIT_TICKS 0#define configIDLE_SHOULD_YIELD 1#define configUSE_MUTEXES 1#define configQUEUE_REGISTRY_SIZE 8#define configCHECK_FOR_STACK_OVERFLOW 0#define configUSE_RECURSIVE_MUTEXES 1#define configUSE_MALLOC_FAILED_HOOK 0#define configUSE_APPLICATION_TASK_TAG 0#define configUSE_COUNTING_SEMAPHORES 1#define configGENERATE_RUN_TIME_STATS 0/* Co-routine definitions. */#define configUSE_CO_ROUTINES 0#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )/* Software timer definitions. */#define configUSE_TIMERS 1#define configTIMER_TASK_PRIORITY ( 2 )#define configTIMER_QUEUE_LENGTH 10#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */#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
將IDLE_HOOK/TICK_HOOK禁止了,先不去關注這兩個功能。
將STM32相關文件搬過來,如下加入到工程
建立main.c
正點原子的板子,有兩個LED,我們就建立兩個任務來閃燈吧,相當于hello world,容易理解。
/* 操作系統頭文件。 */
#include “FreeRTOS.h”#include “task.h”#include “timers.h”#include “semphr.h”#include “stm32f4xx.h”
//LED管腳
#define LED1_PIN GPIO_Pin_9#define LED1_GPIO_PORT GPIOF#define LED1_GPIO_CLK RCC_AHB1Periph_GPIOF
#define LED2_PIN GPIO_Pin_10#define LED2_GPIO_PORT GPIOF#define LED2_GPIO_CLK RCC_AHB1Periph_GPIOF
static void prvLedInitialise()
{
GPIO_InitTypeDef GPIO_InitStructure;
/* LED1時能時鐘 */
RCC_AHB1PeriphClockCmd(LED1_GPIO_CLK, ENABLE);
/* LED1 GPIO 配置為輸出 */
GPIO_InitStructure.GPIO_Pin = LED1_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
/* LED2時能時鐘 */
RCC_AHB1PeriphClockCmd(LED2_GPIO_CLK, ENABLE);
/* LED2 GPIO配置為輸出 */
GPIO_InitStructure.GPIO_Pin = LED2_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
}
static void prvSetupHardware( void )
{
/* 配置時鐘,PLL,FLASH */
SystemInit();
/* 配置NVIC優先級。 */
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
/*LED GPIO配置*/
prvLedInitialise();
}
//500ms LED1燈狀態翻轉一次
static void led1Task( void * pvParameters )
{
while(1)
{
LED1_GPIO_PORT-》ODR ^= LED1_PIN;
vTaskDelay(500);
}
}
//1000ms LED2燈狀態翻轉一次
static void led2Task( void * pvParameters )
{
while(1)
{
LED2_GPIO_PORT-》ODR ^= LED2_PIN;
vTaskDelay(1000);
}
}
int main(void)
{
prvSetupHardware();
xTaskCreate(led1Task,“LED1”,256,NULL,100,(TaskHandle_t *)NULL);
xTaskCreate(led2Task,“LED2”,256,NULL,101,(TaskHandle_t *)NULL);
/* 啟動任務調度器。 */
vTaskStartScheduler();
}
5.設置包含路徑
5.1 右鍵打開options,設置C/C++編譯器包含路徑
5.2 設置包含路徑為:
$PROJECT_DIR$是一個變量,表示當前路徑,不要設成絕對路徑,否則拷貝到不同路徑就無法編譯了。
$PROJ_DIR$
$PROJ_DIR$halCMSISDeviceSTSTM32F4xxInclude
$PROJ_DIR$halSTM32F4xx_StdPeriph_Driverinc
$PROJ_DIR$freeRTOSinclude
$PROJ_DIR$freeRTOSportableIARARM_CM4F
$PROJ_DIR$Commoninclude示當前工程目錄,利用這個變量就可以設置和工程相關的路徑了,不要設置為絕對路徑,否則如果工程拷貝到其他路徑,就無法正確編譯了。
并設置兩個宏:
USE_STDPERIPH_DRIVER
STM32F4XX
5.3 設置匯編器包含路徑
6. 設置鏈接配置文件
注:如果遇到下面的錯誤,應該是你使用了老版本的startup_stm32f4xx.s
Warning[25]: Label ‘CAN2_SCE_IRQHandler’ is defined pubweak in a section implicitly declared root
官方例子中下面路徑的startup_stm32f4xx.s為老版本
CMSISDeviceSTSTM32F4xxSourceTemplatesiar
該警告詳細信息可參考:
https://www.iar.com/knowledge/support/technical-notes/assembler/warning25-label-xxxxx-is-defined-pubweak-in-a-section-implicitly-declared-root/
編譯運行
設置ST-Link
總結一下官方的例子,要直接拿來開發產品有很多不需要的文件,可以按照本文的步驟做些刪減,先建立這樣一個基本工程,然后就可以結合自己的實際硬件以及需求,開始做應用開發了。
編輯:jq
-
STM32F4
+關注
關注
3文章
194瀏覽量
28003
原文標題:手把手教你在STM32F4上跑freeRTOS
文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論