開始這篇文章之前先簡單說明一下,我使用的MCU是我們公司自主研發的ACH1180芯片,和STM32差不多,都是Cortex-M4的核,所以移植的過程參考了STM32移植的步驟。
1.解壓FreeRTOSV8.2.3到本地目錄(FreeRTOS的源碼在官網上有,目前是9.0.0版本,據說8版本穩定,但未做考證)
2.將\FreeRTOSV8.2.3\FreeRTOS\中的Source文件夾復制到待移植的代碼工程中,並且重新命名為“FreeRTOS”
3.在IAR中建立FreeRTOS的文件域,FreeRTOS文件域下建立src和inc.
4.添加FreeRTOS文件:
I)在src文件域下,添加FreeRTOS文件夾中源文件
II)在src文件域下,添加\FreeRTOS\portable\IAR\ARM_CM4F中源文件
III)在src文件域下,添加FreeRTOS/portable/MemMang下的源文件
完成效果圖:
5.制作FreeRTOSConfig.h文件
由於ACH的核和STM32F4XX系列的核都是ARM CM4F的核,所以可以參考STM32F4XX的FreeRTOSConfig.h的文檔.
把源碼中,FreeRTOSV8.2.3\FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SK中的FreeRTOSConfig.h復制到 待移植的工程目錄中:ACH_170727\FreeRTOS\include
將FreeRTOSConfig.h添加到IAR工程中,FreeRTOS inc文件域下。(這步僅僅為了編輯代碼方便)
將待修改FreeRTOSConfig信息:
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 1
#define configCHECK_FOR_STACK_OVERFLOW 2
#define configUSE_MALLOC_FAILED_HOOK 1
修改為:
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 0
#define configUSE_MALLOC_FAILED_HOOK 0
以下為ACH訂制修改方案:
將:#define configMAX_PRIORITIES ( 5 )
#define configTOTAL_HEAP_SIZE ( size_t ) ( 75 * 1024 ) )
修改為:
#define configMAX_PRIORITIES (12)
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 50 * 1024 ) ))
6.添加編譯路徑
I)添加C文件編譯路徑
II)添加匯編文件編譯路徑
完成以上步驟,可以編譯了,若編譯沒有錯誤,表示FreeRTOSconfig文件修改正確。
7.刪除FreeRTOS中多余的庫文件。
在\ACH_170727\FreeRTOS\portable\文件夾中,除了IAR 和MemMang保留,其他文件夾刪除。
在\ACH_170727\FreeRTOS\portable\IAR文件夾中,除了ARM_CM4F保留,其他文件夾刪除。
8.引入系統時鍾
在GKI_SetSystemCoreClock函數中,把sulSystemClcok變量復制給SystemCoreClcok
9.編寫測試代碼。
測試代碼如下:
/* Scheduler includes. */
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define TASK1_PRIORITY 2
#define TASK2_PRIORITY 3
#define TASK3_PRIORITY 4
void vTask1( void *pvParameters );
void vTask2( void *pvParameters );
void vTask3( void *pvParameters );
void FreeRTOS_test(void)
{
printf("portTICK_PERIOD_MS = %d\r\n", portTICK_PERIOD_MS);
xTaskCreate( vTask1, "Task1", 512, NULL, TASK1_PRIORITY, NULL );
xTaskCreate( vTask2, "Task2", 512, NULL, TASK2_PRIORITY, NULL );
xTaskCreate( vTask3, "Task3", 512, NULL, TASK3_PRIORITY, NULL );
vTaskStartScheduler();
GKI_Printf("FreeRTOS Failed\r\n");
}
void vTask1(void *pvParameters)
{
while (1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
GKI_Printf("vTask1\r\n");
}
}
void vTask2(void *pvParameters)
{
while (1) {
vTaskDelay(2000 / portTICK_PERIOD_MS);
GKI_Printf("vTask2\r\n");
}
}
void vTask3(void *pvParameters)
{
while (1) {
vTaskDelay(3000 / portTICK_PERIOD_MS);
GKI_Printf("vTask3\r\n");
}
}
在Uart0端可以看到vTask1 vTask2 vTask3 在指定的時間片上打印,表示FreeRTOS移植成功。