打印
[STM32F4]

基于stm32F407的hal库,移植FreeRTOS的具体步骤和遇到的问题

[复制链接]
902|39
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
g36xcv|  楼主 | 2023-12-26 19:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1. 资料准备
因为板子是stm32F407的第二版的,所以开始下的资料是旧版本的,但是旧版本的FreeRTOS工程没有hal库的,都是标准库的,这里是下载stm32F407最新版的资料,进行移植。

资料可以在正点原子官网下载,如下:
http://www.openedv.com/docs/boards/stm32/index.html

一定要下载最新的资料(开始用旧版本的移植不成功)。

准备stm32F407 hal库的 实验8 基本定时器实验和 实验37 内存管理实验两个工程,以及FreeRTOS的源码,以内存管理实验为模版,进行移植。


使用特权

评论回复
评论
g36xcv 2023-12-26 19:11 回复TA
———————————————— 版权声明:本文为CSDN博主「你走以后」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/m0_64053511/article/details/130869760 
沙发
g36xcv|  楼主 | 2023-12-26 19:12 | 只看该作者
2. 实验流程
添加 FreeRTOS 源码
添加FreeRTOSConfig.h配置文件
修改SYSTEM文件
修改中断相关文件
添加应用程序

使用特权

评论回复
板凳
g36xcv|  楼主 | 2023-12-26 19:12 | 只看该作者
2.1 添加 FreeRTOS 源码
在Middlewares文件夹中新建一个FreeRTOS文件夹,把FreeRTOS源码中的source中文件都拷贝到新建的FreeRTOS文件夹中,删去其余不是.c的文件。

使用特权

评论回复
地板
g36xcv|  楼主 | 2023-12-26 19:12 | 只看该作者
portable文件夹里面的东西是连接软件层面的FreeRTOS 操作系统和硬件层面的芯片的桥梁,这里只保留portable文件夹中的RVDS、MemMang、Keil三个文件夹(因为stm32F4只用到这三个文件夹)。

使用特权

评论回复
5
g36xcv|  楼主 | 2023-12-26 19:12 | 只看该作者
2.2 将文件添加到工程
在工程中新建两个分组,Middlewares/FreeRTOS_CORE 和 Middlewares/FreeRTOS_PORT。

使用特权

评论回复
6
g36xcv|  楼主 | 2023-12-26 19:12 | 只看该作者
将.c文件添加到Middlewares/FreeRTOS_CORE 分组中。

使用特权

评论回复
7
g36xcv|  楼主 | 2023-12-26 19:13 | 只看该作者
将MemMang文件夹下的heap_4.c添加到Middlewares/FreeRTOS_PORT分组中。

使用特权

评论回复
8
g36xcv|  楼主 | 2023-12-26 19:13 | 只看该作者
将RVDS文件夹下的ARM_CM4F下的port.c添加到Middlewares/FreeRTOS_PORT分组中。

使用特权

评论回复
9
g36xcv|  楼主 | 2023-12-26 19:13 | 只看该作者
2.3 添加头文件路径
添加头文件路径FreeRTOS/include和port.c的文件路径。

使用特权

评论回复
10
g36xcv|  楼主 | 2023-12-26 19:13 | 只看该作者
2.4 添加 FreeRTOSConfig.h文件
在FreeRTOS的例程中找到该文件FreeRTOSConfig.h,放到移植工程即可,这里放到user文件夹中。

使用特权

评论回复
11
g36xcv|  楼主 | 2023-12-26 19:13 | 只看该作者

使用特权

评论回复
12
g36xcv|  楼主 | 2023-12-26 19:14 | 只看该作者
2.5 修改SYSTEM文件
修改sys.h文件/**
1. SYS_SUPPORT_OS用于定义系统文件夹是否支持OS
2. 0,不支持OS
3. 1,支持OS
*/
//#define SYS_SUPPORT_OS       0
#define SYS_SUPPORT_OS         1

使用特权

评论回复
13
g36xcv|  楼主 | 2023-12-26 19:14 | 只看该作者
修改usart.c 文件,删掉OSIntEnter()和 OSIntExit()两个函数void USART_UX_IRQHandler(void)
{
    uint32_t timeout = 0;
    uint32_t maxDelay = 0x1FFFF;
//#if SYS_SUPPORT_OS                              /* 使用OS */
//    OSIntEnter();   
//#endif
    HAL_UART_IRQHandler(&g_uart1_handle);       /* 调用HAL库中断处理公用函数 */
    timeout = 0;
    while (HAL_UART_GetState(&g_uart1_handle) != HAL_UART_STATE_READY) /* 等待就绪 */
    {
        timeout++;                              /* 超时处理 */
        if(timeout > maxDelay)
        {
            break;
        }
    }
    timeout=0;
    /* 一次处理完成之后,重新开启中断并设置RxXferCount为1 */
    while (HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE) != HAL_OK)
    {
        timeout++;                              /* 超时处理 */
        if (timeout > maxDelay)
        {
            break;
        }
    }
//#if SYS_SUPPORT_OS                              /* 使用OS */
//    OSIntExit();
//#endif
}

使用特权

评论回复
14
g36xcv|  楼主 | 2023-12-26 19:14 | 只看该作者
修改usart.c 文件,删掉OSIntEnter()和 OSIntExit()两个函数void USART_UX_IRQHandler(void)
{
    uint32_t timeout = 0;
    uint32_t maxDelay = 0x1FFFF;
//#if SYS_SUPPORT_OS                              /* 使用OS */
//    OSIntEnter();   
//#endif
    HAL_UART_IRQHandler(&g_uart1_handle);       /* 调用HAL库中断处理公用函数 */
    timeout = 0;
    while (HAL_UART_GetState(&g_uart1_handle) != HAL_UART_STATE_READY) /* 等待就绪 */
    {
        timeout++;                              /* 超时处理 */
        if(timeout > maxDelay)
        {
            break;
        }
    }
    timeout=0;
    /* 一次处理完成之后,重新开启中断并设置RxXferCount为1 */
    while (HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE) != HAL_OK)
    {
        timeout++;                              /* 超时处理 */
        if (timeout > maxDelay)
        {
            break;
        }
    }
//#if SYS_SUPPORT_OS                              /* 使用OS */
//    OSIntExit();
//#endif
}

使用特权

评论回复
15
g36xcv|  楼主 | 2023-12-26 19:14 | 只看该作者
将 usart.c中包含的关于 OS 的头文件删除///* 如果使用os,则包括下面的头文件即可 */
//#if SYS_SUPPORT_OS
//#include "includes.h"                               /* os 使用 */
//#endif

使用特权

评论回复
16
g36xcv|  楼主 | 2023-12-26 19:15 | 只看该作者
修改delay.c 文件,删除如下代码//static uint16_t g_fac_ms = 0;
///*
// *  当delay_us/delay_ms需要支持OS的时候需要三个与OS相关的宏定义和函数来支持
// *  首先是3个宏定义:
// *      delay_osrunning    :用于表示OS当前是否正在运行,以决定是否可以使用相关函数
// *      delay_ostickspersec:用于表示OS设定的时钟节拍,delay_init将根据这个参数来初始化systick
// *      delay_osintnesting :用于表示OS中断嵌套级别,因为中断里面不可以调度,delay_ms使用该参数来决定如何运行
// *  然后是3个函数:
// *      delay_osschedlock  :用于锁定OS任务调度,禁止调度
// *      delay_osschedunlock:用于解锁OS任务调度,重新开启调度
// *      delay_ostimedly    :用于OS延时,可以引起任务调度.
// *
// *  本例程仅作UCOSII和UCOSIII的支持,其他OS,请自行参考移植
// */
//
///* 支持UCOSII */
//#ifdef  OS_CRITICAL_METHOD                      /* OS_CRITICAL_METHOD定义了,说明要支持UCOSII */
//#define delay_osrunning     OSRunning           /* OS是否运行标记,0,不运行;1,在运行 */
//#define delay_ostickspersec OS_TICKS_PER_SEC    /* OS时钟节拍,即每秒调度次数 */
//#define delay_osintnesting  OSIntNesting        /* 中断嵌套级别,即中断嵌套次数 */
//#endif

///* 支持UCOSIII */
//#ifdef  CPU_CFG_CRITICAL_METHOD                 /* CPU_CFG_CRITICAL_METHOD定义了,说明要支持UCOSIII */
//#define delay_osrunning     OSRunning           /* OS是否运行标记,0,不运行;1,在运行 */
//#define delay_ostickspersec OSCfg_TickRate_Hz   /* OS时钟节拍,即每秒调度次数 */
//#define delay_osintnesting  OSIntNestingCtr     /* 中断嵌套级别,即中断嵌套次数 */
//#endif

///**
// * @brief     us级延时时,关闭任务调度(防止打断us级延迟)
// * @param     无  
// * @retval    无
// */  
//void delay_osschedlock(void)
//{
//#ifdef CPU_CFG_CRITICAL_METHOD          /* 使用UCOSIII */
//    OS_ERR err;
//    OSSchedLock(&err);                  /* UCOSIII的方式,禁止调度,防止打断us延时 */
//#else                                   /* 否则UCOSII */
//    OSSchedLock();                      /* UCOSII的方式,禁止调度,防止打断us延时 */
//#endif
//}

///**
// * @brief     us级延时时,恢复任务调度
// * @param     无
// * @retval    无
// */  
//void delay_osschedunlock(void)
//{
//#ifdef CPU_CFG_CRITICAL_METHOD          /* 使用UCOSIII */
//    OS_ERR err;
//    OSSchedUnlock(&err);                /* UCOSIII的方式,恢复调度 */
//#else                                   /* 否则UCOSII */
//    OSSchedUnlock();                    /* UCOSII的方式,恢复调度 */
//#endif
//}

///**
// * @brief     us级延时时,恢复任务调度
// * @param     ticks : 延时的节拍数
// * @retval    无
// */  
//void delay_ostimedly(uint32_t ticks)
//{
//#ifdef CPU_CFG_CRITICAL_METHOD
//    OS_ERR err;
//    OSTimeDly(ticks, OS_OPT_TIME_PERIODIC, &err);   /* UCOSIII延时采用周期模式 */
//#else
//    OSTimeDly(ticks);                               /* UCOSII延时 */
//#endif
//}

使用特权

评论回复
17
g36xcv|  楼主 | 2023-12-26 19:15 | 只看该作者
添加 FreeRTOS 的相关代码(在delay.c文件中)
extern void xPortSysTickHandler(void);

使用特权

评论回复
18
g36xcv|  楼主 | 2023-12-26 19:15 | 只看该作者
修改SysTick_Handler()函数
void SysTick_Handler(void)
{
    HAL_IncTick();
//    if (delay_osrunning == 1)       /* OS开始跑了,才执行正常的调度处理 */
//    {
//        OSIntEnter();               /* 进入中断 */
//        OSTimeTick();               /* 调用ucos的时钟服务程序 */
//        OSIntExit();                /* 触发任务切换软中断 */
//    }
        /* OS 开始跑了,才执行正常的调度处理 */
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
      {
         xPortSysTickHandler();
      }
}

使用特权

评论回复
19
g36xcv|  楼主 | 2023-12-26 19:15 | 只看该作者
修改delay_init()函数
void delay_init(uint16_t sysclk)
{
reload *= 1000000 / configTICK_RATE_HZ;
//    g_fac_ms = 1000 / delay_ostickspersec;
}
/* 删除不用的 g_fac_ms 相关代码 */

使用特权

评论回复
20
g36xcv|  楼主 | 2023-12-26 19:15 | 只看该作者
修改delay_us()函数
void delay_us(uint32_t nus)
{
   // delay_osschedlock();                    /* 阻止OS调度,防止打断us延时 */
   // delay_osschedunlock();                  /* 恢复OS调度 */
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

194

帖子

0

粉丝