__attribute__((io)), __attribute__((address)) in gcc for AVR don't seem to have any effect - gcc

I am trying to use variable attributes specifically provided by AVR flavor of gcc (https://gcc.gnu.org/onlinedocs/gcc/AVR-Variable-Attributes.html#AVR-Variable-Attributes).
The manual says that these special attributes should allow me to force the placement of a variable at the predetermined memory address. They even give an example:
volatile int porta __attribute__((address (0x600)));
But when I compile and debug this code example from the above mentioned document, the variable declared with such attribute is placed into a location in SRAM that compiler and linker determine, not at the address 0x600, as requested. Actually, if I remove the attribute entirely from the declaration, the end result does not change - the variable is placed at the same "whatever" address. Same thing happens when I use "io" and "io_low" attributes instead of "address".
I am using gcc toolchain packaged in the latest version Atmel Studio 7.0.19.31 targeted at 8-bit MCUs (ATMega64).
Hence the question: has anyone tried to use these special AVR-specific attributes with any success?
Important notes:
I am aware that in general to accomplish a placement of a variable at a fixed address in gcc you need to follow a two-step process (using section attribute and then modifying the linker script), but specificially for AVR it seems like these single-step attributes were provided, the question is how to make them work. A two-step process is not an option for me.
I am aware that in general one can always do this:
*(volatile int*)0x600 = your_data_here;
But this is not an option for me either, I need an actual variable declared (because I want to map it onto a bitwise structure to have access to individual bits without explicitly using the masks and logical operations.
So I am really looking for a way to make the provided attributes work, not for a workaround. What am I missing?

typedef struct {
uint8_t rx:4;
uint8_t tx:4;
} Pio_TXRXMUX_t;
#define Pio_TXRXMUX (*(volatile Pio_TXRXMUX_t *)(0x22)) //PORTA on ATMEGA1280

Related

The placement order of __attribute__((section("name")))

I am using a code example where I have this define:
#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__)))
all over the code.
e.g.
//file1.cpp
PLACE_IN_SECTION("A") static int a1;
//file2.cpp
PLACE_IN_SECTION("A") static int a2;
I can't find information regarding the order the variables are placed in a specific section.
Keil just told me to put everything in a struct to have control over the addresses.
But I still want to know if there is any rule regarding the order, per compiler.
So basically the question is who will be first, and why?
Using both gcc, and arm compiler (v6)
Edit:
This variables are shard with another CPU, and the address they get matter to the system.
It is up to the compiler to decide order of variables in memory. Different versions of the same compiler can give different order on the same code.
To retain order the variables as in the source, GCC has optimization flag -fno-toplevel-reorder
Do not reorder top-level functions, variables, and asm statements. Output them in the same order that they appear in the input file. When this option is used, unreferenced static variables are not removed. This option is intended to support existing code that relies on a particular ordering. For new code, it is better to use attributes when possible.
-ftoplevel-reorder is the default at -O1 and higher, and also at -O0 if -fsection-anchors is explicitly requested. Additionally -fno-toplevel-reorder implies -fno-section-anchors.
link
This might reduce quality of optimization. To prevent it globaly, the variables, that must be placed in a known order, should be moved to a separate file, which is compiled with this option.

Can register name be passed into assembly template in GCC inline assembly [duplicate]

I have recently started learning how to use the inline assembly in C Code and came across an interesting feature where you can specify registers for local variables (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html#Local-Register-Variables).
The usage of this feature is as follows:
register int *foo asm ("r12");
Then I started to wonder whether it was possible to insert a char pointer such as
const char d[4] = "r12";
register int *foo asm (d);
but got the error: expected string literal before ā€˜dā€™ (as expected)
I can understand why this would be a bad practice, but is there any possible way to achieve a similar effect where I can use a char pointer to access the register? If not, is there any particular reason why this is not allowed besides the potential security issues?
Additionally, I read this StackOverflow question: String literals: pointer vs. char array
Thank you.
The syntax to initialize the variable would be register char *foo asm ("r12") = d; to point an asm-register variable at a string. You can't use a runtime-variable string as the register name; register choices have to get assembled into machine code at compile time.
If that's what you're trying to do, you're misunderstanding something fundamental about assembly language and/or how ahead-of-time compiled languages compile into machine code. GCC won't make self-modifying code (and even if it wanted to, doing that safely would require redoing register allocation done by the ahead-of-time optimizer), or code that re-JITs itself based on a string.
(The first time I looked at your question, I didn't understand what you were even trying to do, because I was only considering things that are possible. #FelixG's comment was the clue I needed to make sense of the question.)
(Also note that registers aren't indexable; even in asm you can't use a single instruction to read a register number selected by an integer in another register. You could branch on it, or store all the registers in memory and index that like variadic functions do for their incoming register args.)
And if you do want a compile-time constant string literal, just use it with the normal syntax. Use a CPP macro if you want the same string to initialize a char array.

Purpose of using Windows Data Types in a program

I am trying to understand the purpose of using Windows Data Types when defining parameters of a function/structure fields in a particular language. I've read explanations detailing how this prevents code from "breaking" if "underlying types" are changed. Can some one present a concise explanation and example to clarify? Thanks.
Found answer in a similar post (Why are the standard datatypes not used in Win32 API?):
And the reason that these types are defined the way they are, rather than using int, char and so on is that it removes the "whatever the compiler thinks an int should be sized as" from the interface of the OS. Which is a very good thing, because if you use compiler A, or compiler B, or compiler C, they will all use the same types - only the library interface header file needs to do the right thing defining the types.
By defining types that are not standard types, it's easy to change int from 16 to 32 bit, for example. The first C/C++ compilers for Windows were using 16-bit integers. It was only in the mid to late 1990's that Windows got a 32-bit API, and up until that point, you were using int that was 16-bit. Imagine that you have a well-working program that uses several hundred int variables, and all of a sudden, you have to change ALL of those variables to something else... Wouldn't be very nice, right - especially as SOME of those variables DON'T need changing, because moving to a 32-bit int for some of your code won't make any difference, so no point in changing those bits.
It should be noted that WCHAR is NOT the same as const char - WCHAR is a "wide char" so wchar_t is the comparable type.
So, basically, the "define our own type" is a way to guarantee that it's possible to change the underlying compiler architecture, without having to change (much of the) source code. All larger projects that do machine-dependant coding does this sort of thing.

memory mapped using linker

How can I force the linker to put some of my variables to specific place in memory. For example I want to allocate integer name in 0x8100000. If I didn't miss understand I can use:
int name __attribute__ ((section ("name_of_section")));
and then in linker scripts:
SECTIONS
{
...
. = 0x8100000;
.data : { name_of_section }
...
}
I want to use something similar for map a uC port.
But something doesn't match and I don't know where I made mistake. (I have never use linker script, so sorry if I wrote something very stupid).
Usually this is done without a linker script.
int volatile * const portA = 0x8100000; //portA is a constant pointer to a volatile int
...
*portA = 53; //write value 53 to output port
If you must use a linker script, it is going to be compiler and/or chip specific. Can you tell us what chip and toolchain you are using?
Thanks for all your advice! Now it's working.
.ld file:
SECTIONS
{
...
.data: {
...
}
...
var_name = 0x40010CA0;
}
.c file:
extern volatile int var_name;
After study docs which I linked above (Input Section Example), I tried also something like that:
.ld file:
.hrd_map 0x40010CA0 :
{
main.o(.b_section)
}
Where .b_section was a global variable with attribute:
int b __attribute__((section(".b_section")));
But it doesn't work, I got this kind of error: multiple definition of `main'.
I think that's because earlier in .ld file I have other asignment like: .data: {...} .bss .text.
Maybe someone know how to fix this, or how to get to some variables without using section attribute. I tried to look for symbols to variables in main.o file but I didn't see anything looking like symbol name for variable, except .b_section that I have created using section attribute and other (created by default? ) .data .bss .text etc.
#Dan You are right I am doing this for learning, and I agree with you. But on the other hand I think that this code will be quite portable beacuse every chip require .ld and Startup file and the definition of ports are also included in libraries.
I recommend NOT using the linker for access to hardware registers. Your code will be much easier to understand and maintain if you explicitly code the addresses. It is a good idea to gather all device-specific register information in an include file. For complex peripherals it is usually a good idea to typedef a structure for the register block associated with a peripheral, especially when the device supports several instances of a particular peripheral. Then use the technique from Luke's answer to get at the register or register block in your code. And the volatile keyword should always be used when accessing hardware registers.

How can I create a custom variable attribute to direct movs into different address spaces?

So, I'm building a custom backend for GCC for a processor. This processor has 4 address spaces: local, global, mmm, and mmr. I want to make it such that when writing c code, you can do this:
int global x = 5;
which would cause the compiler to spit out an instruction like this:
ldi.g %reg, 5
I know that certain processors like blackfin and MeP do something similar to this, so I figure its possible to do, however I have no idea how to do it. The technique that should allow me to do this is a variable attribute.
Any suggestions on how I could go about doing this?
You can add target-specific attributes by registering a struct attribute_spec table using TARGET_ATTRIBUTE_TABLE, as described in the GCC internals documentation. The details of struct attribute_spec can be found in the source (gcc/tree.h).
This handler doesn't need to do anything beyond returning NULL_TREE, although typically it will at least do some error checking. (Read the comments in gcc/tree.h, and look at examples in other targets.)
Later, you can obtain the list of attributes for a declaration tree node with DECL_ATTRIBUTES() (see the internals docs again), and use lookup_attribute() (see gcc/tree.h again) to see if a given attribute in the list.
You want to references to a symbol to generate different assembly based on your new attributes, so you probably want to use the TARGET_ENCODE_SECTION_INFO hook ("Define this hook if references to a symbol or a constant must be treated differently depending on something about the variable or function named by the symbol") to set a flag on the symbol_ref (as the docs suggest). You can define a predicate for testing this flag in the .md .

Resources