STM32F429IG移植FreeRTOS

一,移植文件

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我還在找原因。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章