破防了,家人们,移植完了才发现我这启动文件怎么是f429的,要老命了,但是别慌,步骤都是一样的,就是得重新来一遍,服了,闷头干半天,直接全错,苦命的嵌入式老农民

看的正点原子的教程,自己跟着移植一遍,就是视频文字版,用的正点原子探索者,芯片是f407系列。另,由于原子一直都在更新,找教程和例程的时候找最新的,也就是和视频一样的,不然移植的时候会乱套,老版教程没准都是固件库的,我这个板子的资料链接如下

STM32F407探索者开发板V3 — 点原子资料下载中心 1.0.0 文档

教程在A盘

例程在 A盘/4,程序源码/3,扩展例程/2,FreeRTOS例程.zip

明确一点,所谓移植,其实就是复制粘贴,把别人写好的东西,复制到自己的空工程里,接下来主要就是复制

1.准备工作

1.1 找到移植所需工程

需要用到三个工程:HAL库版本的内存管理实验、基本定时器实验以及FreeRTOS源码

自己新建一个文件夹,存放以下三个工程,

源码:可以自己下载,我这里直接用的正点原子网盘里的链接,在 "A盘/软件资料/FreeRTOS学习资料.zip" 里

HAL库版本例程:"A盘/程序源码/标准例程-HAL库版本.zip" 里

内存管理实验为移植所需的主要工程,代码也会在这个例程里改,其余的工程只是将所需要的部分文件复制到内存管理实验里

将内存管理实验改名为FreeRTOS移植(想改什么改什么,不改也行,为了区分这个工程是移植的,我才改名,好区分,下面都叫这个名字了,没有内存管理实验这个名字了)

2. 开始移植

2.1 添加FreeRTOS源码

① 移植定时器实验里的TIMER文件

内存管理实验里的TIMER文件夹直接复制到 "FreeRTOS移植\Drivers\BSP" 里

TIMER文件在基本定时器实验\实验7-1 基本定时中断器实验\Drivers\BSP里

复制好的工程文件如图

② 源码移植

在 "FreeRTOS移植/Middlewares" 里新建FreeRTOS文件夹,用于存放FreeRTOS相关源码

将 "源码/Source" 里的源码文件(.c / .h这类)放入刚才新建的FreeRTOS文件夹里

Source文件如图,需要复制这三个

其中portable里只要keil、MemMang和RVDS,其余删掉就行

移植完如图

MemMang文件里只保留heap_4.c,RVDS只保留CM4F文件夹

我这里用的芯片是f407系列,所以只留M4核相关的东西

2.2 添加配置文件(Keil里)

① 添加源文件

工程里新建 FreeRTOS_CORE  &  FreeRTOS_PORT 

FreeRTOS_CORE 添加 "\FreeRTOS移植\Middlewares\FreeRTOS" 文件夹下的所有头文件

同样的步骤添加 heap_4.c 和 port.c 到FreeRTOS_PORT

heap_4.c在MemMang里,port.c在"RVDS\ARM_CM4F"里

添加成功可以从左侧工程栏里看到,有了就是添加成功了

② 添加头文件

最终添加两个文件夹进来

"FreeRTOS移植\Middlewares\FreeRTOS\portable\RVDS\ARM_CM4F"

"FreeRTOS移植\Middlewares\FreeRTOS\include"

③ 添加配置文件(FreeRTOSConfig.h)

FreeRTOSConfig.h复制到"FreeRTOS移植\Middlewares\FreeRTOS\include"里

FreeRTOSConfig.h就是配置文件,可以从源码任意demo里找,也可以从正点原子的例程里找

2.3 修改文件 (SYSTEM  &  中断)

2.3.1 修改SYSTEM文件

①  sys.h 

② usart.c

删掉框住部分

报错部分删掉

③ delay.c

1. line44--93全部删掉

2.添加FreeRTOS相关代码
2.1 添加 extern void xPortSysTickHandler(void);

2.2 改四个函数,直接复制就行

2.2.1 改SysTick_Handler()

/**
 * @brief     systick中断服务函数,使用OS时用到
 * @param     ticks: 延时的节拍数
 * @retval    无
 */  
void SysTick_Handler(void)
{
    HAL_IncTick();
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) /* OS开始跑了,才执行正常的调度处理 */
    {
        xPortSysTickHandler();
    }
}

2.2.2 改delay_init(uint16_t sysclk)

/**
 * @brief     初始化延迟函数
 * @param     sysclk: 系统时钟频率, 即CPU频率(rcc_c_ck), 168Mhz
 * @retval    无
 */  
void delay_init(uint16_t sysclk)
{
#if SYS_SUPPORT_OS                                      /* 如果需要支持OS */
    uint32_t reload;
#endif
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* SYSTICK使用内核时钟源,同CPU同频率 */
    g_fac_us = sysclk;                                  /* 不论是否使用OS,g_fac_us都需要使用 */
#if SYS_SUPPORT_OS                                      /* 如果需要支持OS. */
    reload = sysclk;                                    /* 每秒钟的计数次数 单位为M */
    reload *= 1000000 / configTICK_RATE_HZ;             /* 根据delay_ostickspersec设定溢出时间,reload为24位
                                                           寄存器,最大值:16777216,在168M下,约合0.099s左右 */
    SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk;          /* 开启SYSTICK中断 */
    SysTick->LOAD = reload;                             /* 每1/delay_ostickspersec秒中断一次 */
    SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;           /* 开启SYSTICK */
#endif 
}

2.2.3 改delay_us(uint32_t nus)

void delay_us(uint32_t nus)
{
  uint32_t ticks;
    uint32_t told, tnow, tcnt = 0;
    uint32_t reload = SysTick->LOAD;        /* LOAD的值 */
    
    ticks = nus * g_fac_us;                 /* 需要的节拍数 */
    told = SysTick->VAL;                    /* 刚进入时的计数器值 */
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += told - tnow;        /* 这里注意一下SYSTICK是一个递减的计数器就可以了 */
            }
            else
            {
                tcnt += reload - tnow + told;
            }
            told = tnow;
            if (tcnt >= ticks) 
            {
                break;                      /* 时间超过/等于要延迟的时间,则退出 */
            }
        }
    }	
} 

2.2.4 改delay_ms(uint16_t nms)

void delay_ms(uint16_t nms)
{
  uint32_t i;

    for (i=0; i<nms; i++)
    {
        delay_us(1000);
    }
}

这里我手里的代码和例程不太一样,我去问了客服,说没有影响,那我们就直接用就行了,其他不用管

2.3 改头文件

之前一直有个报错的头文件,换成

#include "FreeRTOS.h"
#include "task.h"

改成

2.3.2 改中断文件(stm32f4xx_it.c)

①加头文件 

#include "./SYSTEM/sys/sys.h"

②宏开关注释

给 SVC_Handler(void)、PendSV_Handler(void)、SysTick_Handler(void)三个函数加宏开关

2.3.3 改FreeRTOSConfig.h

改为   __NVIC_PRIO_BITS   4

这里需要先编译,不然找不到这个头文件,编译之后找到并打开,编译之后会有报错,先别着急,待会一个一个处理

在配置文件找到这个变量并跳转

跳转发现跳转不过去,有这个No Browse,这时去魔术棒选项里添加配置就行

步骤如下

然后再跳转,还是会弹出一个框,点确定之后可以跳转

改了就行,编译保存

至此教程里的移植完成,我自己还有10个error,来改改

2.4 改error

FreeRTOSConfig.h

前面说过FreeRTOSConfig.h文件里有两个头文件报错,是路径的问题,改了就行,直接复制

#include "sys.h" ---> #include "./SYSTEM/sys/sys.h"

#include "usart.h"  ---> #include "./SYSTEM/usart/usart.h"

欸嘿,改了以后编译,直接没error了,看来就是头文件导致的10个error,具体的error我也没细看,我就是先发现了这两个,就想着先改这两个,没想到直接就好了,反正有error别害怕,看具体的错误一个一个改就行

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐