1.1.4. Changing the Alignment: __align(). Altium TriCore
Publicitate
Publicitate
TASKING VX-toolset for TriCore User Guide
1.1.4. Changing the Alignment: __align()
By default the TriCore compiler aligns objects to the minimum alignment required by the architecture.
With the attribute
__align()
you can change the object alignment.
Caution: Use
__align()
with extreme care! You should know exactly how to use it properly, otherwise it may result in incorrect (trapping) code, as shown in the following example. Use it only to increase the alignment; and the alignment must always be a multiple of the original required alignment!
Example:
#include <stdio.h> short int i[3] = {1,2,3};
__align(2) char *hello="Hello World\n"; /* trap */ int main(void)
{
printf("%s",hello);
}
The pointer ' hello
' is given an alignment of 2 and is actually stored at a non-word aligned address. The compiler however does not take into account that pointers are aligned at 2 and uses a load address instruction. This will lead to a trap at run-time.
Instead of the attribute
__align()
you can also use
#pragma align
.
1.2. Accessing Memory
You can use static memory qualifiers to allocate static objects in a particular part of the addressing space of the processor.
In addition, you can place variables at absolute addresses with the keyword
__at()
. If you declare an integer at an absolute address, you can declare a single bit of that variable as bit variable with the keyword
__atbit()
.
1.2.1. Memory Qualifiers
In the C language you can specify that a variable must lie in a specific part of memory. You can do this with a memory qualifier.
You can specify the following memory qualifiers:
Qualifier Description
__near
*
Near data, direct addressable
Location
First 16 kB of a 256 MB block
Maximum object size
Pointer size
16 kB 32-bit
Section types
neardata, nearrom, nearbss, nearnoclear
6
C Language
Qualifier
__far
__a0
__a1
__a8
__a9
*
Description Location Maximum object size
Pointer size
no limit 32-bit Far data, indirect addressable
Small data
Anywhere
Literal data, read-only
Data, reserved for
OS
Data, reserved for
OS
Sign-extended 16-bit offset from address register A0.
64 kB
Sign-extended 16-bit offset from address register A1.
64 kB
Sign-extended 16-bit offset from address register A8.
64 kB
Sign-extended 16-bit offset from address register A9.
64 kB
32-bit
32-bit
32-bit
32-bit
Section types
fardata, farrom, farbss, farnoclear a0data, a0bss a1rom a8data, a8rom, a8bss a9data, a9rom, a9bss
*
If you do not specify
__near
or
__far
, the compiler chooses where to place the declared object.
With the C compiler option --default-near-size (maximum size in bytes for data elements that are
by default located in
__near
sections) you can specify the size of data objects which the compiler then by default places in near memory.
Address registers A0, A1, A8, and A9 are designated as system global registers. They are not part of either context partition and are not saved/restored across calls. They can be protected against write access by user applications.
By convention, A0 and A1 are reserved for compiler use, while A8 and A9 are reserved for OS or application use. A0 is used as a base pointer to the small data section, where global data elements can be accessed using base + offset addressing. A0 is initialized by the execution environment.
A1 is used as a base pointer to the literal data section. The literal data section is a read-only data section intended for holding address constants and program literal values. Like A0, it is initialized by the execution environment.
As noted, A8 and A9 are reserved for OS use, or for application use in cases where the application and
OS are tightly coupled.
All these memory qualifiers (
__near
,
__far
,
__a0
,
__a1
,
__a8
and
__a9
) are related to the object being defined, they influence where the object will be located in memory. They are not part of the type of the object defined. Therefore, you cannot use these qualifiers in typedefs, type casts or for members of a struct or union.
Examples using memory qualifiers
To declare a fast accessible integer in directly addressable memory: int __near Var_in_near;
To allocate a pointer in far memory (the compiler will not use absolute addressing mode):
__far int *Ptr_in_far;
7
Descarcă
Publicitate