The following type attributes are supported:
The cregister attribute provides support for using the constant registers. If the cregister attribute is used, the peripheral attribute can be used along with it. The syntax is:
int x __attribute__((cregister("MEM", [near|far]), peripheral));
The name "MEM" can be any name, although it will need to correspond to a memory range name in your linker command file. The near or far parameter tells the compiler whether it can use the immediate addressing mode (near) or register indirect addressing mode (far). If the data will be completely contained within the first 256 bytes from the top of the constant register pointer then use near, otherwise use far. The default is near.
The linker command file must use the CREGISTER specifier within the MEMORY directive in order for the cregister attribute to succeed, otherwise relocation errors occur. See the "MEMORY Directive Syntax" section of the PRU Assembly Language Tools User's Guide (SPRUHV6) for details. The linker command file syntax is:
MEMORY
{
MEM: origin=xxx length=xxx CREGISTER=4
}
The peripheral attribute can only be used with the cregister attribute and has two effects. First, it puts the object in a section that will not be loaded onto the device. This prevents initialization of the peripheral at runtime. Second, it allows the same object to be defined in multiple source files without a linker error. The intent is that peripherals can be completely described in a header file.
The packed attribute is supported for struct and union types. It is supported if the --relaxed_ansi option is used.
Members of a packed structure are stored as closely to each other as possible, omitting additional bytes of padding usually added to preserve word-alignment. For example, assuming a word-size of 4 bytes ordinarily has 3 bytes of padding between members c1 and i, and another 3 bytes of trailing padding after member c2, leading to a total size of 12 bytes:
struct unpacked_struct { char c1; int i; char c2;};
However, the members of a packed struct are byte-aligned. Thus the following does not have any bytes of padding between or after members and totals 6 bytes:
struct __attribute__((__packed__)) packed_struct { char c1; int i; char c2; };
Subsequently, packed structures in an array are packed together without trailing padding between array elements.
Bit fields of a packed structure are bit-aligned. The byte alignment of adjacent struct members that are not bit fields does not change. However, there are no bits of padding between adjacent bit fields.
The packed attribute can only be applied to the original definition of a structure or union type. It cannot be applied with a typedef to a non-packed structure that has already been defined, nor can it be applied to the declaration of a struct or union object. Therefore, any given structure or union type can only be packed or non-packed, and all objects of that type will inherit its packed or non-packed attribute.
The packed attribute is not applied recursively to structure types that are contained within a packed structure. Thus, in the following example the member s retains the same internal layout as in the first example above. There is no padding between c and s, so s falls on an unaligned boundary:
struct __attribute__((__packed__)) outer_packed_struct { char c; struct unpacked_struct s; };
It is illegal to implicitly or explicitly cast the address of a packed struct member as a pointer to any non-packed type except an unsigned char. In the following example, p1, p2, and the call to foo are all illegal.
void foo(int *param);
struct packed_struct ps;
int *p1 = &ps.i;
int *p2 = (int *)&ps.i;
foo(&ps.i);
However, it is legal to explicitly cast the address of a packed struct member as a pointer to an unsigned char:
unsigned char *pc = (unsigned char *)&ps.i;
Enumerated types are always packed, and the smallest integral type available for the fields in the type is used.
The TI compiler also supports an unpacked attribute for an enumeration type to allow you to indicate that the representation is to be an integer type that is no smaller than int; in other words, it is not packed.