ZHCU876Z July 2001 – October 2023 SM320F28335-EP
C2000 架构具有 16 位字。但一些外设为 8 位字节可寻址。字节外设桥可将地址视为字节地址,从而在 CPU 和字节外设之间转换地址。因此,只有一些 C2000 地址可以正确映射到字节外设。16 位数据的偶数和奇数地址均映射到字节外设的同一数据元件。
32 位数据的地址也是一样。16 位访问的地址必须与 32 位对齐,32 位访问的地址必须与 64 位对齐。
提供 C2000 驱动程序库和位域头文件,以访问外设。为了支持对字节外设数据的正常访问,编译器提供 __byte_peripheral_32 内在函数和 byte_peripheral 类型属性。
C2000 驱动程序库可在正确的起始地址访问字节外设数据。但在 C2000 上,32 位数据的运算经常会拆分为两个 16 位数据的运算,因为在此架构上这种方式更加高效。对 32 位字节外设数据的访问无法有规律地拆分为两个 16 位访问,因为第二个 16 位的起始偏移量将不正确。__byte_peripheral_32 内在函数可用于访问一个 32 位字节外设数据地址,因而无需拆分访问。该内在函数会返回对无符号长整型值的引用,并可用于读取和写入数据。有关此内在函数的信息,请参阅 节 7.6。
byte_peripheral 类型属性可按如下方式应用于无符号整型和无符号长整型的 typedefs(类型定义),以支持位域。
typedef unsigned int bp_16 __attribute__((byte_peripheral)) ;
typedef unsigned long bp_32 __attribute__((byte_peripheral));
typedef 名称并不重要。属性会自动应用可变关键字并处理对齐。字节外设结构中的所有结构成员(无论是否为位域)必须通过 typedef 应用这些属性,以确保结构访问的正确对齐。请注意,对齐方式不同将导致结构布局不同,因此位域无法始终通过常规结构中的容器类型进行访问。
例如,字节外设位域类型的位位置在以下示例中与常规位域的位置进行比较。16 位访问必须与 32 位对齐,因此不可能访问 16 位容器偏移 16-31 的位。若要访问这些位,必须使用 32 位容器。在示例 1 中,您可以将 field4 到 field6 的域类型更改为 bp_32,创建与常规情况相同的布局。在示例 2 中,您要将 field2 到 field4 的域类型更改为 bp_32。
struct example1 { // regular bits position //byte peripherals
bp_16 field1:9; // 0-8 // 0-8
bp_16 field2:6; // 9-14 // 9-14
bp_32 field3:4; // 15-18 // 15-18
bp_16 field4:1; // 19 // 32
bp_16 field5:5; // 20-24 // 33-37
bp_16 field6:7; // 25-31 // 38-44
};
struct example2{ // regular bits position //byte peripherals
bp_32 field1:29; // 0-28 // 0-28
bp_16 field2:1; // 29 // 32
bp_16 field3:1; // 30 // 33
bp_16 field4:1; // 31 // 34
};
由于对齐会在声明的任何对象中生成边界填充,建议您将字节外设地址转换为字节外设结构类型,而不是声明这些结构类型的对象。
您无法使用字节外设类型属性创建数组。这是因为 C 语言可以保证数组的大小等于每个元素的大小乘以元素数量。但在字节外设数组中不会出现这种情况,因为数组中需要有边界填充。