硬汉嵌入式论坛

 找回密码
 立即注册
查看: 4527|回复: 3
收起左侧

[FreeRTOS] 移植FreeRTOS过程中SysTick_Handler()重定义相关的一个问题

[复制链接]

1

主题

2

回帖

5

积分

新手上路

积分
5
发表于 2024-7-17 12:42:23 | 显示全部楼层 |阅读模式

芯片:stm32f407zgtb,MDK:5.39,FreeRTOS:V202210.01,HAL:V1.28,DSP:2.17.1
HAL与FreeRTOS均为手动移植,未使用STM32CubeMX。
最近在移植FreeRTOS的时候发现的一个问题:

总所周知,FreeRTOS在port.c文件中帮忙完成了SVC_Handler()、PendSV_Handler()、SysTick_Handler()三个中断处理函数,分别为vPortSVCHandler()、xPortPendSVHandler()xPortSysTickHandler(),所以在对应的中断处理函数文件中需要作一些修改,使得芯片处理中断时调用port.c中的函数。我在网络上翻教程时发现,对于SVC_Handler()、PendSV_Handler()的处理都比较一致,即把原本的中断函数注释掉,在FreeRTOSConfig.h中进行如下宏定义:
#define vPortSVCHandler       SVC_Handler
#define xPortPendSVHandler  PendSV_Handler

但在SysTick_Handler()的处理上出现了两种情况,一是与上面对SVC_Handler()、PendSV_Handler()的处理一样,注释原本的中断函数后在FreeRTOSConfig.h中进行宏定义:
#define xPortSysTickHandler SysTick_Handler
另一种是修改原本的中断函数SysTick_Handler():
void SysTick_Handler(void){
        #if (INCLUDE_xTaskGetSchedulerState  == 1 )
        if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){
        #endif
                xPortSysTickHandler();
        #if (INCLUDE_xTaskGetSchedulerState  == 1 )
        }
        #endif
}
我两种方法都尝试了一下,后者FreeRTOS能正常运行,前者则会进入HardFault_Handler()。
对此,网上有的解释是在汇编启动文件中会调用SysTick_Handler()(原帖:FreeRTOS 移植,问题总结_uxdeletedtaskswaitingcleanup-CSDN博客),但以我当前的理解以上三个中断在汇编启动文件中仅仅定义了向量表,并未实质性使用这些函数;况且按照该帖子的思路汇编启动文件中同样调用了PendSV_Handler()等其他函数,但以宏定义的方式重定义PendSV_Handler()并没有遇到问题。
目前我还没有找到原因,望知道其中原因的大佬们指点。
随帖附上我当前能成功运行的处理方法:

<stm32f4xx_it.c>中修改为:

#ifndef FREERTOS_CONFIG_H
//        Supervisor Call
//        This function should be redefined by vPortSVCHandler() in OS
        void SVC_Handler(void){
               
        }

//        Pend System Service Call
//        This function should be redefined by xPortPendSVHandler() in OS
        void PendSV_Handler(void){
               
        }
#endif //FREERTOS_CONFIG_H

//        System Tick
void SysTick_Handler(void){
        #ifndef FREERTOS_CONFIG_H
                HAL_IncTick();
       
        #else
                #if (INCLUDE_xTaskGetSchedulerState  == 1 )
                if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){
                #endif
                        xPortSysTickHandler();
                #if (INCLUDE_xTaskGetSchedulerState  == 1 )
                }
                #endif
       
        #endif //FREERTOS_CONFIG_H
}

<stm32f4xx_it.h>中保留SVC_Handler()、PendSV_Handler()、SysTick_Handler()三个函数的声明并包含FreeRTOS.h


<FreeRTOSConfig.h>中添加:

#define vPortSVCHandler       SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
void xPortSysTickHandler(void);



回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2024-7-17 18:53:37 | 显示全部楼层
根本原因是HAL库也使用滴答定时器了,你可能没有处理这个,要处理下。

可以看下此贴的time base文件,你们做了两种方式,一个是HAL和FreeRTOS继续使用滴答定时器,还有一个是HAL其它硬件定时器

https://forum.anfulai.cn/forum.p ... B%BA%CF%C4%A3%B0%E5
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2024-7-19 11:20:25 | 显示全部楼层
eric2013 发表于 2024-7-17 18:53
根本原因是HAL库也使用滴答定时器了,你可能没有处理这个,要处理下。

可以看下此贴的time base文件,你 ...

感谢您的源码与回复,我理解了。
回复

使用道具 举报

1

主题

2

回帖

5

积分

新手上路

积分
5
 楼主| 发表于 2024-7-19 12:48:21 | 显示全部楼层
OK,根据硬汉哥的回答以及网络上的一些资料我也重新总结一下。
首先,有同样问题的各位可以去先去看一下本帖硬汉哥的回复,并去看一下以下两个帖子:
cubemx在使用freertos的时候为何推荐使用除systick以外的timebase_cubemx提示freertos不用systick时基-CSDN博客
STM32 HAL使用TIM6代替Systick作为时基_stm32f4 hal tim6-CSDN博客
先回答一下为什么直接在<FreeRTOSConfig.h>中添加宏定义会出现HardFault
#define xPortSysTickHandler SysTick_Handler
在该宏定义下会出现两个同名的SysTick_Handler()函数一个是操作HAL中的tick、一个操作RTOS的tick,后者实际就是原本位于port.c文件中的xPortSysTickHandler()函数,二者会发生冲突。
我原本的方式实际也是有问题的,因为按照我的宏定义,SysTick_Handler()函数中仅操作了RTOS的tick,并未操作HAL的tick。
实际可以修改为如下:
void SysTick_Handler(void){
        
        HAL_IncTick();
      
        #ifdef FREERTOS_CONFIG_H
                #if (INCLUDE_xTaskGetSchedulerState  == 1 )
                if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){
                #endif
                        xPortSysTickHandler();
                #if (INCLUDE_xTaskGetSchedulerState  == 1 )
                }
                #endif
      
        #endif //FREERTOS_CONFIG_H
}
这样做,两者的tick都兼顾,但就会出现上面引用的两个帖子中提到的优先级的问题,因而不是最优解。
最优解还是使用一个定时器作为HAL的时基,并在该时基的基础上构建delay函数,详细内容我还没有尝试,各位可以参考硬汉哥的源码里User/stm32h7xx_hal_timebase_tim.c文件的内容。
再次感谢硬汉哥的回答与源码。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 06:04 , Processed in 0.039531 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表