强制 GCC 访问带有单词的结构 [英] Force GCC to access structs with words

查看:20
本文介绍了强制 GCC 访问带有单词的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 ARM 处理器 (HT32F1655) 上,寄存器的特定部分需要字访问.来自用户手册:

On an ARM processor (HT32F1655), a specific section of registers requires word accesses. From the user manual:

请注意,AHB 总线中的所有外设寄存器仅支持字访问.

Note that all peripheral registers in the AHB bus support only word access.

但是 gcc 正在打包结构上生成一些 ldrb(加载字节)和 strb(存储字节)指令.结构看起来像这样:

But gcc is generating some ldrb (load byte) and strb (store byte) instructions on packed structs. The structs look something like this:

typedef union {
    struct {
        uint32_t CKOUTSRC    : 3;    //!< CKOUT Clock Source Selection
        uint32_t             : 5;
        uint32_t PLLSRC      : 1;    //!< PLL Clock Source Selection
        uint32_t             : 2;
        uint32_t CKREFPRE    : 5;    //!< CK_REF Clock Prescaler Selection
        uint32_t             : 4;
        uint32_t URPRE       : 2;    //!< USART Clock Prescaler Selection
        uint32_t USBPRE      : 2;    //!< USB Clock Prescaler Selection
        uint32_t             : 5;
        uint32_t LPMOD       : 3;    //!< Lower Power Mode Status
    } __attribute__((packed)) __attribute__ ((aligned(4)));
    uint32_t word;
} reg;

示例用法:

(*(volatile uint32_t*)0x40088000)->CKOUTSRC = 1;

产生类似于:

 ldrb r2, [r1]
 orr r2, r2, #1
 strb r2, [r1]

当我需要时:

 ldr r2, [r1]
 orr r2, r2, #1
 str r2, [r1]

有没有办法强制 gcc 只生成访问整个单词的指令?某些选项 (-mno-unaligned-access) 使 gcc 生成字访问,但仅当字节不是 4 字对齐时.

Is there any way to force gcc to only generate instructions that access the whole word? Some options (-mno-unaligned-access) make gcc generate word accesses, but only when the byte is not 4-word aligned.

有一个 -mslow-bytes 应该做正确的事情,但是似乎 arm-none-eabi-gcc 不存在该选项.

There is a -mslow-bytes which should do the right thing, however it seems that option does not exist for arm-none-eabi-gcc.

理想情况下,有一种方法可以仅对受影响的结构强制执行此操作.

Ideally, there would be a way to force this only on the affected structs.

请不要回答不要使用位域".我知道缺点,但我有能力在这里控制使用的编译器,所以我不担心可移植性.

Please, no "don't use bitfields" answers. I know the drawbacks, but I have the ability here to control the compiler(s) used, so I am not worried about portability.

推荐答案

您正在寻找的是 GCC 的 -fstrict-volatile-bitfields 选项:

What you're looking for is GCC's -fstrict-volatile-bitfields option:

如果访问易失性位字段(或其他结构字段,尽管编译器通常会尊重这些类型)应该使用该字段类型宽度的单一访问,如果可能的话,应该使用自然对齐方式.例如,具有内存映射外设寄存器的目标可能需要所有此类访问为 16 位宽;使用此标志,您可以将所有外围位字段声明为 unsigned short(假设这些目标上的 short 为 16 位),以强制 GCC 使用 16 位访问,而不是更有效的 32 位访问.

This option should be used if accesses to volatile bit-fields (or other structure fields, although the compiler usually honors those types anyway) should use a single access of the width of the field's type, aligned to a natural alignment if possible. For example, targets with memory-mapped peripheral registers might require all such accesses to be 16 bits wide; with this flag you can declare all peripheral bit-fields as unsigned short (assuming short is 16 bits on these targets) to force GCC to use 16-bit accesses instead of, perhaps, a more efficient 32-bit access.

如果禁用此选项,编译器将使用最高效的指令.在前面的示例中,这可能是 32 位加载指令,即使它访问的字节不包含位字段的任何部分,或者访问与正在更新的寄存器无关的内存映射寄存器.

If this option is disabled, the compiler uses the most efficient instruction. In the previous example, that might be a 32-bit load instruction, even though that accesses bytes that do not contain any portion of the bit-field, or memory-mapped registers unrelated to the one being updated.

在某些情况下,例如当打包属性应用于结构字段时,可能无法通过与目标机器正确对齐的单个读取或写入来访问该字段.在这种情况下,GCC 回退到生成多次访问,而不是在运行时会出错或截断结果的代码.

In some cases, such as when the packed attribute is applied to a structure field, it may not be possible to access the field with a single read or write that is correctly aligned for the target machine. In this case GCC falls back to generating multiple accesses rather than code that will fault or truncate the result at run time.

注意:由于 C/C++11 内存模型的限制,写访问不允许触及非位域成员.因此,建议将字段类型的所有位都定义为位字段成员.

Note: Due to restrictions of the C/C++11 memory model, write accesses are not allowed to touch non bit-field members. It is therefore recommended to define all bits of the field's type as bit-field members.

该选项的默认值由目标处理器的应用程序二进制接口决定.

The default value of this option is determined by the application binary interface for the target processor.

以及使用 volatile 关键字.请参阅:https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

along with use of the volatile keyword. See: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

这篇关于强制 GCC 访问带有单词的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆