相關文章
FreeRTOS qemu mps2-an385 bsp 移植制作 :環境搭建篇
FreeRTOS qemu mps2-an385 bsp 移植制作 :系統啟動篇
開發環境
-
Win10 64位 + VS Code,ssh 遠程連接 ubuntu
-
VMware Workstation Pro 16 + Ubuntu 20.04
-
FreeRTOSv202212.01(備注:可以在 github 獲取最新版本)
-
qemu qemu-system-arm mps2-an385 開發板,qemu 版本 QEMU emulator version 4.2.1 或更高
-
arm gcc 交叉編譯工具鏈:當前使用 gcc 編譯環境, gcc-arm-11.2-2022.02-x86_64-arm-none-eabi, gcc version 11.2.1 20220111
前言
-
前面的 FreeRTOS qemu mps2-an385 bsp 移植制作 :環境搭建篇 大體講了一下環境搭建,初步配置了工程目錄
-
FreeRTOS qemu mps2-an385 bsp 移植制作 :系統啟動篇 配置了 VS Code gdb 調試環境,初步讓MCU 啟動,進入了啟動入口函數
-
本篇繼續優化,創建 FreeRTOS task ,讓系統啟動起來
中斷向量表
-
為了實現系統 systick 定時器與 任務調度,FreeRTOS 實現了 systick、pendSV 等功能,需要關聯啟動文件
-
在
qemu_mps2/application/FreeRTOSConfig.h
中,追加
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
-
【備注】這個
FreeRTOSConfig.h
可以從FreeRTOS 的 相關 demo 中復制出來并修改,當前復制于FreeRTOSv202212.01\FreeRTOS\Demo\CORTEX_MPS2_QEMU_IAR_GCC\FreeRTOSConfig.h
-
這樣就對接了系統的 systick 定時器與任務調度中斷處理:
PendSV_Handler
讓啟動直接進入 main 函數
- 默認第一個執行函數是:
qemu_mps2/CMSDK_CM3/Source/GCC/startup_CMSDK_CM3.S
中的Reset_Handler
,當前調試發現bl _start
時會卡住,所以這里直接改為bl main
,也就是跳轉到 main 函數
- main.c 的代碼如下:
#include "FreeRTOS.h"
#include "task.h"#include <stdio.h>
#include <string.h>#define TASK_TEST_PRIORITY (tskIDLE_PRIORITY + 6)static void task_test_entry(void *pvParameters)
{while (1){vTaskDelay(1000);}
}void main( void )
{xTaskCreate(task_test_entry, "task_test", configMINIMAL_STACK_SIZE, NULL, TASK_TEST_PRIORITY, NULL);vTaskStartScheduler();for( ;; );
}
- 這里暫時沒有開啟串口打印,后續補上,創建一個 task,taks 里面什么都不干,就是 1秒延時
ilde 與 timer 任務棧
-
編譯并運行后,發現出現了斷言,提示 idle task 的 棧指針為空,經過分析發現,需要完善 idle 線程棧的獲取函數,當前 timer task 的棧也需要完善,比如使用靜態數組作為 task 的線程棧
-
hook 等函數在
qemu_mps2/application/port.c
中實現,完善
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{static StaticTask_t xIdleTaskTCB;static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;*ppxIdleTaskStackBuffer = uxIdleTaskStack;*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{static StaticTask_t xTimerTaskTCB;static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;*ppxTimerTaskStackBuffer = uxTimerTaskStack;*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
- 再次編譯后調試運行,發現 FreeRTOS 正常進入 task 任務函數,并且周期性的工作(1秒的延時)
- 以上說明 FreeRTOS 系統運行起來了,初步移植成功
小結
-
后續繼續實現系統串口的打印功能,讓系統運行可以看的到
-
后續繼續完善 FreeRTOS 的 例程,比如實現多任務間的通信等功能