从0开始搭建基于ARM GCC的软件系统04——移植FreeRTOS

一、获取FreeRTOS源码

    进入FreeRTOS官网:https://www.freertos.org/a00104.html

  

点击Download下载源码文件。我下载的是“FreeRTOSv10.2.1_191129.exe”,其它版本也可以。

解压后:

先不用看Labs和Plus两个文件夹(后面熟悉了之后再看)。直接进入到FreeRTOS目录:

Demo:一些演示工程。
License:许可。
Source:源码目录。我们所需要的文件都在这里面。

进入到Source目录:

如图所示,就是FreeRTOS的源代码了。将其移植到我们的系统中即可。

 

二、移植FreeRTOS

在我们的系统工程中创建一个目录用于存放FreeRTOS源码。

我创建目录结构:OS\FreeRTOSv10.2.1\Source。

将以下文件都从刚下载的源码包中拷贝过来。

Source\*.c   (源码c文件)

Source\include\*.h (源码头文件)

Source\portable\GCC\ARM_CM4F\port.c (这里与硬件相关,请根据自己的硬件平台选择。我使用的STM32L4VGT6平台,编译器用的ARM GCC,所以选择了GCC目录下CM4)

Source\portable\GCC\ARM_CM4F\protmacro.h

Source\portable\MemMang\heap_3.c (具体选用哪个可参考https://www.freertos.org/a00111.html)

特别注意:在选择port.c时,一定要选择与硬件对应的目录,否则即使编译通过了,也可能会跑不起来。

文件移植完成后,可以尝试编译看看,不过编译过程中可能会报一些错误。

常用错误是启动文件中的中断响应函数需要做一些修改。

三、修改启动文件

启动文件中会用到port.c中的三个中断函数。

vPortSVCHandler
xPortPendSVHandler
xPortSysTickHandler

这里为了保持启动文件的一致性,我们不修改启动文件,来修改port.c中的函数名:

vPortSVCHandler         修改为:SVC_Handler
xPortPendSVHandler      修改为:PendSV_Handler
xPortSysTickHandler     修改为:SysTick_Handler

这个函数在stm32l4xx_it.c也有定义,所以需要将其注释掉。

四、修改系统时钟频率

根据实际情况修改系统时钟频率:configCPU_CLOCK_HZ。

我的系统中使用SystemCoreClock定义的系统频率。

在FreeRTOSConfig.h中修改如下:

#if 1//def __ICCARM__
    #include <stdint.h>
    extern uint32_t SystemCoreClock;
#endif

#define configUSE_PREEMPTION            1
#define configUSE_IDLE_HOOK                0
#define configUSE_TICK_HOOK                0
#define configCPU_CLOCK_HZ                ( SystemCoreClock )
#define configTICK_RATE_HZ                ( ( TickType_t ) 1000 )

我这里通过前面这些步骤的修改,代码已经顺利编译通过。若还有遇到编译问题,可逐一排除(不清楚的可百度解决^_^)。

五、写测试代码

本例测试GPIOB6以1秒的频率闪烁。

#include "main.h"

// FreeRTOS head file, add here.
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "list.h"
#include "portable.h"
#include "FreeRTOSConfig.h"


void taskMain(void *pvParameters)

{
    GPIO_InitTypeDef  GPIO_InitStruct;
    
    pvParameters = pvParameters;

    //初始化硬件
    HAL_Init();

    //打开GPIOB的时钟
    __HAL_RCC_GPIOB_CLK_ENABLE();

    //初始化GPIOB6为输出
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    while(1)
    {
        HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_6);
        vTaskDelay(1000/portTICK_RATE_MS);
    }
}

int main(void)
{
    //创建任务taskMain
    xTaskCreate( taskMain, "taskMain", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY+2, NULL );

    // 启动任务调度
    vTaskStartScheduler();

    return 0;
}

比较幸运……

编译后直接跑起来了……

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值