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.

[参考译文] LP-AM243:TI AM243x 工业通信 SDK 短语

Guru**** 2925550 points

Other Parts Discussed in Thread: LP-AM243, SYSCONFIG

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1653182/lp-am243-short-enums-ti-am243x-industrial-communications-sdk

器件型号: LP-AM243

#`tiesc_memcpy`严格排序的 PRU-ICSS 共享 RAM +用于重建 SDK 库的打包枚举 ABI 的安全性

**平台:** AM243x (LP-AM243)
** SDK:** MCU+ SDK 11.01.00.19、工业通信 SDK 2025.00.00.08
**编译器:** ARM 编译器 6 (armclang v6, ARM Development Studio 2025.0)
**应用:** Cortex-R5F、NoRTOS 上的 EtherCAT 子器件 (Beckhoff SSC)

——

##观察 1:所有预构建的 EtherCAT `.lib`文件都使用打包的枚举

`~/ti/ind_comms_sdk_am243x_2025_00_00_08`中附带的所有 EtherCAT`.lib`文件均使用打包枚举进行编译 (` ABI_ENUM_SIZE:packed `):

|库|路径|
|----- |----- |
|`EtherCAT_subdevice_ICSS_fwhal`|`……/EtherCAT_subdevice/ICSS_fwhal/lib/`|
|`ethercat_subdevice_lwip_fretos`|`……/ethercat_subdevice/stack/lwip/lib/`|
|`EtherCAT_subdevice`|`……/EtherCAT_subdevice/stack/lib/`|
`|` EtherCAT_iolink_gateway `|`.../EtherCAT_iolink_gateway/stack/lib/ |

与这些引脚相链接的任何代码也必须使用`-fshort-enums`以避免 ABI 不匹配。

——

##观察 2:PRU-ICSS 共享 RAM 是严格排序的存储器

SysConfig 生成的 MPU 配置 (`ti_DPL_config.c`)、用于 EtherCAT 子器件演示:

```c
//区域 0:涵盖 0x00000000 - 0x7FFFFFFF (2GB)

  .baseAddr = 0x0u、
  .size  = MpuP_RegionSize_2G、
  .attrs ={
    .isCacheable = 0、
    .isBufferable = 0、
    .tex = 0、 // TEx=0、C=0、B=0 ->严格排序 (ARMv7-R)
    ...
  }、
}、
```μ s

无较高优先级的区域覆盖`0x30090000`。 ESC 寄存器实时位于:

```μ s
CSL_PRU_ICSSG1_DRAM0_SLV_RAM_BASE (0x30080000)+ PRUICSS_SHARED_RAM (0x10000)
= 0x30090000 + ESC_OFFSET
```μ s

——

`观察 3:在任意字节偏移处、` tiescbsp.c `m通过` emcpy 访问 ESC 寄存器

```c
// tiescbsp.c 行 111:
void * tiesc_memcpy (uint8_t *dst、const uint8_t * src、uint32_t size_bytes)

  memcpy (dst、src、size_bytes); //直接委托给 libc memcpy
  返回 DST;
}

// tiescbsp.c 行 2438 (bsp_read):
uint8_t *PESC =(uint8_t *)(pruIcssHandle->hwAttrs->baseAddr + PRUICSS_shared_RAM);
tiesc_memcpy (pdata、&PESC[ADDRESS]、len); // address 可以是任何 ESC 偏移量(例如 0x0802)
```μ s

——

##观察 4:TI` tiarmclang `mlibc `emcpy32.S` behavior

从`armv7r-ti-none-eabi/c/libc.a 拆卸`:

```ASM
<_unaln>:               ;在 src & 3!= 0 时输入
  C4:ldrb R3、[R1]、#1      ;字节读取在 src
  C8:strb R3、[r0]、#1
  CC:SUB R2、R2、#1
  D4:TST R1、#3          ; src word-aligned 还没有?
  D8:BNE _unaln          ;循环直至对齐

<_aln> -> <_c16>:           ;一旦 src 被字对齐
  2C:LDM R1!、{R3、R4、IP、LR} ; 16 字节批量字对齐加载
  30:STM r0!、{R3、R4、IP、LR}

<_1line> 尾(剩余 1-3 个字节):
  94:ldrb r3、[r1]、#1      ;剩余 1 个字节
  A0:ldrh r3、[r1]、#2      ;剩余 2 个字节(半字对齐)
  b0:ldrh + ldrb          ;剩余 3 个字节
```μ s

键属性:

-字节 — 仅向前复制,直到`src`达到字对齐—在`src`之前永远不会读取
-`加载 (` LDM`/` LDR `) 只发生在 src`[LDM、src + len ) 内的自然对齐的地址上
- Tail 在半字对齐地址使用`LDRH`,单个字节使用`LDRB`

——

##观察 5: ARM 编译器 6 `memcpy`存在严重差异

从 ARM 编译器 6 `libc.a`(`armv7r_hard_vfpv3_D16`) 进行反汇编:

```ASM
  B8:SUB IP、R1、R4       ; IP = src 向下对齐(在 src 之前!)
  C8:LDR R5、[IP]        ;在请求的 src 之前从读取的 32 位
  d0:LDR R6、[IP、#4]!     ;下一个字
  E8:ORR R1、R1、R5、LSR R4 ;桶形移位以提取目标字节
```μ s

该字将源指针**向下对齐**并在请求的地址之前读取存储器**以填充寄存器、然后使用桶形移位来提取目标字节。 在严格排序的器件存储器上、这会访问调用方从未预期过的 ESC 寄存器—可能会触发读取副作用或总线错误。

——

##观察 6:我们使用 ARM 编译器的权变措施 6.

我们使用 per-TU 编译标志重定向`mtiescbsp.c`的`emcpy`对逐字节`volatile uint8_t*`实现的调用:

```cmake
set_source_files_properties (
  ${ICSS_FWHAL_base}/tiescbsp.c
  属性 compile_flags
  “-memcpy=tiescbsp_safe_memcpy -dmemset=tiescbsp_safe_memset“
)
```μ s

这在对严格排序存储器进行任何对齐时都是安全的。

——

##问题

** Q1(`枚举):**如果客户需要从源代码重新编译 MCU+ SDK 和工业通信 SDK 中的所有 TI 库、是否应使用`-fshort-enum`/`-mshort-enums 重建这些库? 这是否记录在任何地方?

** Q2(存储器访问宽度):** PRU-ICSS 共享 RAM (EtherCAT ESC 寄存器空间为`0x30090000`) 是支持完整 32 位的存储器吗? 在 TI 的`memcpy32`将`src`对齐到字边界后、它会执行`LDM`/`LDR`(32 位)读取。 这对于所有 ESC 寄存器偏移是安全的、还是仅因为实际中的 ESC 访问恰好是字对齐和字大小才起作用?

** Q3(半字访问):**在所有半字对齐的 ESC 寄存器偏移量上`LDRH`(半字加载)是安全的吗? 当保留 2 个字节时、TI 的`memcpy32 `尾路径使用` ldrh R3、[R1]、#2`。

*** Q4 (`tiesc_memcpy` contract ):***` tiesc_memcpy `应该提供一个字节安全的实现,而不是委派给`memcpy ()`? 如果合约在任意 ESC 偏移量下安全访问严格排序的 PRU-ICSS 存储器、则此函数本身不应该使用逐字节访问(类似于 TI 的`libc.a`中已经存在的`TI_memcpy_small`)?

** Q5(ARM 编译器 6 指导):**对于使用 ARM 编译器 6 而不是`tiarmclang`的客户、TI 是否有一种推荐的方法? ARM 的`memcpy`在源地址之前读取(桶式移位器优化)。 我们当前的权变措施是 per-TU`-dmemcpy=`on ` tiescbsp.c`。 这是预期模式、还是有支持的替代模式?