FreeRTOS qemu mps2-an385 bsp 移植制作 :系统运行篇

相关文章

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

前言

中断向量表

  • 为了实现系统 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 的 例程,比如实现多任务间的通信等功能

猜你喜欢

转载自blog.csdn.net/tcjy1000/article/details/132330481
BSP