This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM2434:尝试写入 PRU 时 GCC memcpy 停止

Guru**** 2198640 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1439764/am2434-gcc-memcpy-stalls-when-trying-to-write-to-the-pru

器件型号:AM2434

工具与软件:

您好!

我有一个可以很好地使用 TI Clang 编译器的 EtherCAT 示例。 但是、对于 GCC 编译器、EtherCAT 演示因对 PRU 的未对齐访问而停止。 我有编译器标志"-munaligned-access"、但这没有帮助、因为未对齐的 memcpy 在 RAM 中运行良好、但 在访问其他外设存储器时可能会导致问题(好像发生了这种情况)。

值得注意的是、长度不均的值(如45)可以正常工作、但长度值(如47)为 memcpy 摊位。 作为权变措施、我从 EtherCAT 演示中修改了 memcpy 包装器函数、并按分段复制最后一个字节。

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void * tiesc_memcpy(uint8_t *dst, const uint8_t *src, uint32_t size_bytes)
{
#if 0
memcpy(dst, src, size_bytes);
return dst;
#endif
if(size_bytes % 4 != 3)
{
memcpy(dst, src, size_bytes);
}
else
{
memcpy(dst, src, size_bytes - 3);
for(int i = size_bytes - 3; i < size_bytes; i++)
{
dst[i] = src[i];
}
}
return dst;
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我正在使用的 GCC 版本是 GCC-10.3-2021.10。  您是否有比使用此权变措施更好的想法?

提前感谢、

Álvaro μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Alvaro:

    请预计响应会有延迟。 将在本周结束之前返回到您的查询。 同时、您可以继续使用您的权变措施。

    此致、
    亚伦

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Aaron:

    感谢您的答复。 我不着急

    此致!

    Álvaro μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的耐心 Alvaro。

    此致、

    亚伦

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Aaaron:

    我希望你做得好。 您有任何关于此主题的更新吗?

    提前感谢、

    Álvaro μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我也看到了这个问题、但略有不同、所以我将在这里添加我的问题。

    我`签署` ti-cgt-armllvm_3.2.LTS 编译器。 在一行的 tiescbsp.c 中打开优化(-O2和-OS)时、会发生未对齐的内存访问问题

    Fullscreen
    1
    2
    3
    tiesc_memset(pRegPermUpdateAddr, TIESC_PERM_READ_ONLY, SYNC_PERMISSION_UPDATE_PDI_SIZE);
    // equivalent to
    tiesc_memset(0x48000522, 0x02, 10);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    似乎正在对 memset 进行优化  

    Fullscreen
    1
    2
    3
    4
    5
    6
    // r0 = 0x48000000
    // r1 = 0x0202
    // r2 = 0x02020202
    strh.w r1, [r0, #0x52a]
    str.w r2, [r0, #0x526]
    str.w r2, [r0, #0x522]
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    这会导致未对齐访问错误、因为它正在尝试在仅为字对齐的地址进行 DWORD 存储。 从我可以告诉步进通过具有-O0的内置 memset 的汇编,它最终会 像这样做这些存储

    Fullscreen
    1
    2
    3
    4
    5
    // r0 = 0x48000000
    // r1 = 0x02020202
    strh.w r1, [r0, #0x522]
    str.w r1, [r0, #0x524]
    str.w r1, [r0, #0x528]
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    这些是正确对齐的存储、但会生成高度未优化的代码。 我可以通过找到所有的地方 memset 最终做未对齐的商店,并手动替换它们来解决这个问题,但会更倾向于一个更好的解决方法。

    我想知道为什么编译时优化的 memset 不会使用未对齐的存储、而内置 memset 不会使用。 不过、这似乎是常规的 clang / llvm 行为、如 该简化示例所示

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Unknown 说:
    我有编译器标志"-munaligned-access"

    在基于 gcc 的 AM335x 实现中、我们使用的是 -MnO-UNaligned-access。 munaligned-access 将启用这一功能!!!

    -munaligned-access-mno-unaligned-access

    启用(或禁用)从非16或32位对齐的地址读取和写入16和32位值。 默认情况下、对所有预 ARMv6、所有 ARMv6-M 和 ARMv8-M 基线架构禁用未对齐访问、并对所有其他架构启用。 如果未启用未对齐访问、则每次访问一个字节的打包数据结构中的字。  

    这最终取决于 TI 无法控制的 libc memcpy 实现。 不管怎么说,检查这,让我们知道...

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我正在签署`ti-cgt-armllvm_3.2.2.LTS`编译器。 发生未对齐内存访问问题

    具有 -mNO-unaligned-access  

    对于 所示的这个简化示例、我看到以下内容。 (BTW 这是一个很好的工具)

    主页:
    按{r7、LR}
    LDR r0、。 LCPI0_0
    MOVs R1、#2
    MOVS R2、#10
    . LPC0_0:
    添加 r0、pc
    相加 r0、#2
    BL memset
    MOVS r0、#0
    弹出{r7、PC}
    . LCPI0_0:
    .long buffer-(. LPC0_0+4)

    缓冲器:
    第16章

    PS:tiarmclang 是 TI 支持的工具链、因此最好针对与此相关的问题创建新帖子。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    看起来将 _attribute ((noinline))添加到  tiesc_memset 最终会生成相同的结果。 它会强制调用 libc memset、对于 clang、libc memset 仅进行对齐存储器访问。  

    Fullscreen
    1
    2
    3
    4
    5
    __attribute((noinline)) void * tiesc_memset(uint8_t *dst, int8_t val, uint32_t size_bytes)
    {
    memset(dst, val, size_bytes);
    return dst;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    我喜欢这个解决方案,因为它允许程序的其余部分利用硬件的功能,并且它可以在 clang 和 gcc*之间移植。

    *我没有测试 gcc, libc memset 函数可能会在允许的情况下尝试执行未对齐的内存写入。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Pratheesh:

    我已经尝试过 -MNO-unaligned-access、但我有相同的问题。

    以下是我的编译标记:

      Set (Compiler_flags.
                -mcpu=cortex-r5
                -mthumb
                小端字节序
                -mfloat-abi=hard
                -mfpu=vfpv3-d16
                -fmessage-length=0
                -fsigned-char
                -ffunfunction-sections
                -Fdata-sections
                -MNO-unaligned-access
                -wno-unused-function
                -wno-address-of-packed-member)

    此致、

    Álvaro μ A

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Alvaro

    如上面的 Zach 所述、这可能是 gcc memset 出现问题、gcc memset  在允许的情况下尝试执行未对齐的内存写入。 我认为我们无法在这方面提供帮助、因此您可以坚持使用您实施的权变措施。

    此致

    Pratheesh