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.
工具与软件:
您好!
我有一个可以很好地使用 TI Clang 编译器的 EtherCAT 示例。 但是、对于 GCC 编译器、EtherCAT 演示因对 PRU 的未对齐访问而停止。 我有编译器标志"-munaligned-access"、但这没有帮助、因为未对齐的 memcpy 在 RAM 中运行良好、但 在访问其他外设存储器时可能会导致问题(好像发生了这种情况)。
值得注意的是、长度不均的值(如45)可以正常工作、但长度值(如47)为 memcpy 摊位。 作为权变措施、我从 EtherCAT 演示中修改了 memcpy 包装器函数、并按分段复制最后一个字节。
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; }
我正在使用的 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)时、会发生未对齐的内存访问问题
tiesc_memset(pRegPermUpdateAddr, TIESC_PERM_READ_ONLY, SYNC_PERMISSION_UPDATE_PDI_SIZE); // equivalent to tiesc_memset(0x48000522, 0x02, 10);
似乎正在对 memset 进行优化
// r0 = 0x48000000 // r1 = 0x0202 // r2 = 0x02020202 strh.w r1, [r0, #0x52a] str.w r2, [r0, #0x526] str.w r2, [r0, #0x522]
这会导致未对齐访问错误、因为它正在尝试在仅为字对齐的地址进行 DWORD 存储。 从我可以告诉步进通过具有-O0的内置 memset 的汇编,它最终会 像这样做这些存储
// r0 = 0x48000000 // r1 = 0x02020202 strh.w r1, [r0, #0x522] str.w r1, [r0, #0x524] str.w r1, [r0, #0x528]
这些是正确对齐的存储、但会生成高度未优化的代码。 我可以通过找到所有的地方 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 仅进行对齐存储器访问。
__attribute((noinline)) void * tiesc_memset(uint8_t *dst, int8_t val, uint32_t size_bytes) { memset(dst, val, size_bytes); return dst; }
我喜欢这个解决方案,因为它允许程序的其余部分利用硬件的功能,并且它可以在 clang 和 gcc*之间移植。
*我没有测试 gcc, libc memset 函数可能会在允许的情况下尝试执行未对齐的内存写入。
您好、Pratheesh:
我已经尝试过 -MNO-unaligned-access、但我有相同的问题。
以下是我的编译标记:
此致、
Álvaro μ A
Alvaro
如上面的 Zach 所述、这可能是 gcc memset 出现问题、gcc memset 在允许的情况下尝试执行未对齐的内存写入。 我认为我们无法在这方面提供帮助、因此您可以坚持使用您实施的权变措施。
此致
Pratheesh