Skip to content

Conversation

ericQiang
Copy link
Contributor

拉取/合并请求描述:(PR description)

[
为什么提交这份PR (why to submit this PR)
cortex-a平台下,中断中如果使用浮点计算会破坏线程栈中的浮点寄存器

你的解决方案是什么 (what is your solution)
对中断进行浮点寄存器的保护

在什么测试环境下测试通过 (what is the test environment)
在stm32mp135fae7上,基于lts-v4.1.x分支测试OK。
]

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 代码是高质量的 Code in this PR is of high quality
  • 已经使用formatting 等源码格式化工具确保格式符合RT-Thread代码规范 This PR complies with RT-Thread code specification

…n the floating point calculation will be safe in interrupt function.
beq 1f
vstmdb sp!, {d0-d15}
vstmdb sp!, {d16-d31}
#ifdef RT_USING_VFPD32 /*there art 32 double float registers to save*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个在编译的时候应该是不同的参数,对应的参数分别是什么?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

浮点单元有多种版本,VFPv2,VFPv3-D16,VFPv4-D16是只有D0-D15寄存器,VFPv3-D32,VFPv4-D32有D0-D31寄存器。我手上用的芯片实现的版本是VFPv4-D16,所以我只能测试D0-D15。我看到其它RTOS(如threadX,FreeRTOS)对于该处的实现均是保存的D0-D31,所以我默认它们的移植是正确的。所以就用RT_USING_VFPD32表示浮点寄存器是D0-D31的情况,至于只有D0-D15的情况,在我写代码时没有过多考虑(因为低16个寄存器大家都有),当然也可以使用如RT_USING_VFPD16来表示。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果这里能够通过gcc内部的宏来控制,这个就最好了。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

浮点单元有多种版本,VFPv2,VFPv3-D16,VFPv4-D16是只有D0-D15寄存器,VFPv3-D32,VFPv4-D32有D0-D31寄存器。我手上用的芯片实现的版本是VFPv4-D16,所以我只能测试D0-D15。我看到其它RTOS(如threadX,FreeRTOS)对于该处的实现均是保存的D0-D31,所以我默认它们的移植是正确的。所以就用RT_USING_VFPD32表示浮点寄存器是D0-D31的情况,至于只有D0-D15的情况,在我写代码时没有过多考虑(因为低16个寄存器大家都有),当然也可以使用如RT_USING_VFPD16来表示。

唔,我的意思是,类似这样的方式,在编译时这个编译参数是什么?有不同的编译参数了,是否可能会出现gcc内部定义宏是有差异的。如果有差异,直接使用内置宏来做区分就显得最方便了,而不需要自己来定于宏。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有的,如下:
-mfpu=name
This specifies what floating-point hardware (or hardware emulation) is available on the target. Permissible names are: ‘auto’, ‘vfpv2’, ‘vfpv3’, ‘vfpv3-fp16’, ‘vfpv3-d16’, ‘vfpv3-d16-fp16’, ‘vfpv3xd’, ‘vfpv3xd-fp16’, ‘neon-vfpv3’, ‘neon-fp16’, ‘vfpv4’, ‘vfpv4-d16’, ‘fpv4-sp-d16’, ‘neon-vfpv4’, ‘fpv5-d16’, ‘fpv5-sp-d16’, ‘fp-armv8’, ‘neon-fp-armv8’ and ‘crypto-neon-fp-armv8’. Note that ‘neon’ is an alias for ‘neon-vfpv3’ and ‘vfp’ is an alias for ‘vfpv2’.

The setting ‘auto’ is the default and is special. It causes the compiler to select the floating-point and Advanced SIMD instructions based on the settings of -mcpu and -march.

If the selected floating-point hardware includes the NEON extension (e.g. -mfpu=neon), note that floating-point operations are not generated by GCC’s auto-vectorization pass unless -funsafe-math-optimizations is also specified. This is because NEON hardware does not fully implement the IEEE 754 standard for floating-point arithmetic (in particular denormal values are treated as zero), so the use of NEON instructions may lead to a loss of precision.

You can also set the fpu name at function level by using the target("fpu=") function attributes (see ARM Function Attributes) or pragmas (see Function Specific Option Pragmas).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但是之前了解的是没办法让这个-mfpu 编译选项被.S文件识别出。

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以用不同的编译参数从 gcc dump 出两份宏定义,然后对比一下文件是否有差异

@Guozhanxin Guozhanxin added the +1 Agree +1 label Sep 25, 2023
@BernardXiong BernardXiong added the discussion This PR/issue needs to be discussed later label Oct 11, 2023

#else
stmfd sp!, {r0-r12,lr}
#ifdef RT_USING_FPU
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

中断一般都是主动保存,主动恢复 FPU 状态的。否则为了一个小概率发生的事件,系统却要付出每一次 IRQ 增加大量访存的巨大代价。这是不合理的。

因此建议是新增 FPU_SAVE/RESTORE 的 API/汇编宏,而不是修改 IRQ

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

同意,这样会比较合理。中断函数中是否使用了浮点数,编程人员是知道的,主动进行保护是明智的。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

但这样好像也存在一个问题,就是线程在创建的时候就需要告知rt_hw_stack_init在初始化栈时要预留浮点单元的栈空间。所以相关的接口函数参数可能需要修改。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion This PR/issue needs to be discussed later +1 Agree +1
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants