目錄
一,移植文件
1.1 建立文件夾
工廠目錄建立文件夾:FreeRTOS
1.2 移植底層文件
1.2.1 Source
路徑:FreeRTOSv9.0.0\FreeRTOS\Source
除文件夾portable全部複製到FreeRTOS文件夾下。
1.2.2 RVDS
路徑:FreeRTOSv9.0.0\FreeRTOS\Source\portable\RVDS\ARM_CM4F
port.c portmacro.h裏面兩個也複製到FreeRTOS文件夾下。
1.2.3 MemMang
路徑:FreeRTOSv9.0.0\FreeRTOS\Source\portable\MemMang
heap_4.c複製到FreeRTOS文件夾下。
1.2.4 FreeRTOSConfig.h
FreeRTOSv9.0.0\FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SK
FreeRTOSConfig.h複製到FreeRTOS文件夾下。
1.2.5 user_app_task.C
user_app_task.c user_app_task.h自建函數
1.3 添加到工程,添加路徑
二,處理
2.1 FreeRTOSConfig.h
改成這個
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
最下面的SysTick_Handler註釋掉
不註釋掉會跟系統SysTick_Handler衝突
// #define xPortSysTickHandler SysTick_Handler
//這兩個如果衝突,把stm32f4xx_it.h裏的兩個給註釋掉,反正我沒用到
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
四個鉤子函數關了,以後用到再開:
不關會有一堆函數未定義
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0
加上這個:
/*****************************************************************
FreeRTOS與內存申請有關配置選項
*****************************************************************/
//支持動態內存申請
#define configSUPPORT_DYNAMIC_ALLOCATION 1
//支持靜態內存
#define configSUPPORT_STATIC_ALLOCATION 1
//系統所有總的堆大小
#define configTOTAL_HEAP_SIZE ((size_t)(36*1024))
2.2 stm32f4xx_it.h
添加:
#include "FreeRTOS.h"
#include "task.h"
void SysTick_Handler(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1 )
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
{
#endif
xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1 )
}
#endif
SysTick_IRQHandle();//我自己的軟件定時器,不用,可以註釋的
}
到這算是移植成功了,也不會報錯(前面都提前改了),FreeRTOS的心跳是通過SysTick_Handler連接的。
三,測試
3.1 main.c
static StackType_t AppTaskCreate_Stack[128];
static StaticTask_t AppTaskCreate_TCB;
StaticTask_t Idle_Task_TCB;
StaticTask_t Timer_Task_TCB;
StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];
StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];
TaskHandle_t AppTaskCreate_Handle;
int main(void)
{
NVIC_Configuration();
SysTick_Init();
debug_Init();
AppTaskCreate_Handle = xTaskCreateStatic((TaskFunction_t )AppTaskCreate, //任務函數
(const char* )"AppTaskCreate", //任務名稱
(uint32_t )128, //任務堆棧大小
(void* )NULL, //傳遞給任務函數的參數
(UBaseType_t )3, //任務優先級
(StackType_t* )AppTaskCreate_Stack, //任務堆棧
(StaticTask_t* )&AppTaskCreate_TCB); //任務控制塊
if(NULL != AppTaskCreate_Handle)/* 創建成功 */
vTaskStartScheduler(); /* 啓動任務,開啓調度 */
while(1);
}
3.2 #include “user_app_task.c”
static StackType_t LED_Task_Stack[128];
static StackType_t LED1_Task_Stack[128];
static StaticTask_t LED_Task_TCB;
static StaticTask_t LED1_Task_TCB;
static void LED_Task(void* parameter)
{
while (1)
{
Debug_Printf("LED_Task\r\n");
vTaskDelay(2000);
}
}
static void LED1_Task(void* parameter)
{
while (1)
{
Debug_Printf("LED1_Task\r\n");
vTaskDelay(1000);
}
}
/**
**********************************************************************
* @brief 獲取空閒任務的任務堆棧和任務控制塊內存
* ppxTimerTaskTCBBuffer : 任務控制塊內存
* ppxTimerTaskStackBuffer : 任務堆棧內存
* pulTimerTaskStackSize : 任務堆棧大小
* @author fire
* @version V1.0
* @date 2018-xx-xx
**********************************************************************
*/
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer=&Idle_Task_TCB;/* 任務控制塊內存 */
*ppxIdleTaskStackBuffer=Idle_Task_Stack;/* 任務堆棧內存 */
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;/* 任務堆棧大小 */
}
/**
*********************************************************************
* @brief 獲取定時器任務的任務堆棧和任務控制塊內存
* ppxTimerTaskTCBBuffer : 任務控制塊內存
* ppxTimerTaskStackBuffer : 任務堆棧內存
* pulTimerTaskStackSize : 任務堆棧大小
* @author fire
* @version V1.0
* @date 2018-xx-xx
**********************************************************************
*/
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&Timer_Task_TCB;/* 任務控制塊內存 */
*ppxTimerTaskStackBuffer=Timer_Task_Stack;/* 任務堆棧內存 */
*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;/* 任務堆棧大小 */
}
void AppTaskCreate(void)
{
taskENTER_CRITICAL(); //進入臨界區
/* 創建LED_Task任務 */
xTaskCreateStatic((TaskFunction_t )LED_Task, //任務函數
(const char* )"LED_Task", //任務名稱
(uint32_t )128, //任務堆棧大小
(void* )NULL, //傳遞給任務函數的參數
(UBaseType_t )4, //任務優先級
(StackType_t* )LED_Task_Stack, //任務堆棧
(StaticTask_t* )&LED_Task_TCB); //任務控制塊
xTaskCreateStatic((TaskFunction_t )LED1_Task, //任務函數
(const char* )"LED1_Task", //任務名稱
(uint32_t )128, //任務堆棧大小
(void* )NULL, //傳遞給任務函數的參數
(UBaseType_t )4, //任務優先級
(StackType_t* )LED1_Task_Stack, //任務堆棧
(StaticTask_t* )&LED1_Task_TCB); //任務控制塊
vTaskDelete(AppTaskCreate_Handle); //刪除AppTaskCreate任務
taskEXIT_CRITICAL(); //退出臨界區
}
3.3 #include “user_app_task.h”
extern StackType_t Idle_Task_Stack[configMINIMAL_STACK_SIZE];
extern StackType_t Timer_Task_Stack[configTIMER_TASK_STACK_DEPTH];
extern StaticTask_t Idle_Task_TCB;
extern StaticTask_t Timer_Task_TCB;
extern TaskHandle_t AppTaskCreate_Handle;
extern void AppTaskCreate(void);
3.4 處理報錯
到這應該沒什麼錯誤了,有問題可以在下面留言大家一起討論。
只有一條很坑爹的地方:
不能爲NVIC_PriorityGroup_1我還在找原因。