memory mapped using linker - gcc

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.

Related

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.

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

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

Write default values to eeprom

This is my Setup:
Atmel studio 7.0
avr-gcc
ATmega644PA
I'm trying to write default values to the eeprom. I mean: in code, predefined values at a specific place in the eeprom.
I can use:
__attribute__((section(".eeprom")))
Which works to put the variables in the eeprom, but this links the variables automatic to a location.
I want to manually set the location where the variable is stored. How can I do this?
Thanks!
Ps: this needs to work for >300 variables
You can place all variables in one struct. The variables will be placed in EEPROM in the specified order.
struct {
uint8_t var1;
uint8_t var2;
uint16_t var3;
...
} eeprom_data __attribute__ ((section(".eeprom")));
you may encapsulate your need.
E.g. you may use this ASF API: http://asf.atmel.com/docs/3.22.0/xmegae/html/nvm_8h.html
Then write your default values into the EEPROM plus an identifier that your init routine has already set the default or not.
Pseudo-code:
if defaultWritten == true
myAppDataStruct = readFromEeprom()
else
initEeprom(yourDesiredAddress, myDefaultAppDataStruct)
You then use the myAppDataStruct as the representation of you EEPROM data.
Otherwise, you may use the approach of declaring the variables into the data section ".eeprom" but than the linker will align it for you.
The solution depends whether you want to intialise the EEPROM on programing time or at each startup of the device. I will describe the solution for programming time (It is what I understand from the question).
The __attribute__((section(".eeprom"))) will say to the linker : "put this variable in the .eep output file". The .eep file is a intel hex file format that will be flashed to EEPROM.
If you want to define specific location for your variable you could either generate and flash the .eep file manually or do a complete EEPROM map letting 0xFF for uninitialised values :
__attribute__((section(".eeprom"))) uint8_t eepContent[6] = {0,1,0xFF,3,4,5};
You could also manually define sections but this is only convenient if you want to use whole block of EEPROM memory not located at the beginning.

what does __init_refok keyword means in linux kernel code?

While browsing the kernel code, I came accross a keyword that is used in several kernel init functions, __init_refok.
some of the lines I came accross are like
void __init_refok free_initmem(void)
static void __init_refok vgacon_scrollback_startup(void)
const struct linux_logo * __init_refok fb_find_logo(int depth)
void noinline __init_refok rest_init(void)
and others.
I searched for the reference , from that I came to know that it is defined as a preprocessor macro in include/linux/init.h, line 71.
After browsing that, I got the following codes
#define __init_refok __ref
and
#define __ref __section(.ref.text) noinline
After that, I am losing track.
If anyone can let me know what is the purpose of using that keyword in the code, it will be very helpful.
[I am looking for the basic functionality achieved by using this keyword, just like using __init helps to put the initialization code in seperate memory location to be cleared after init process has been completed.]
Thanks in advance.
EDIT
In the include/linux/init.h, it is mentioned like __init_refok is to supress the warning from modpost check, due to any reference form normal code to init section code, but still, I am not getting it exactly. Does that mean that these codes will ba place somewhere else? How actually the behaviour differs from the normal behaviour by using __init_refok keyword?
To my understanding, include/linux/init.h clearly documents the purpose of __init_refok. As you have mentioned
using __init helps to put the initialization code in separate memory
location to be cleared after init process has been completed.
compiler generates a warning when we use the data or code from the separate memory as they might will be removed at the time of the execution of the particular code referencing them.
__init_refok is a way to tell the compiler that you are aware and consciously referencing the initialization code or data. It means ref erencing init section is ok for you. Thus compiler does not generate any warning.
The file also documents that, though the warning is suppressed, it is the programmer's responsibility write such code that refers init section data or code.
of course, no warning does not mean code is correct, so optimally
document why the __ref is needed and why it's OK
In your example, the functions free_initmem(void) is probably referring to some data or code, that are tagged with _init.
The _init_refok tag does not remove the code neither relocate. The code is treated as ordinary except, if it contains any reference to init code or data, warning will be suppressed.

Looking for C source code for snprintf()

I need to port snprintf() to another platform that does not fully support GLibC.
I am looking for the underlying declaration in the Glibc 2.14 source code. I follow many function calls, but get stuck on vfprintf(). It then seems to call _IO_vfprintf(), but I cannot find the definition. Probably a macro is obfuscating things.
I need to see the real C code that scans the format string and calculates the number of bytes it would write if input buffer was large enough.
I also tried looking in newlib 1.19.0, but I got stuck on _svfprintf_r(). I cannot find the definition anywhere.
Can someone point me to either definition or another one for snprintf()?
I've spent quite a while digging the sources to find _svfprintf_r() (and friends) definitions in the Newlib. Since OP asked about it, I'll post my finding for the poor souls who need those as well. The following holds true for Newlib 1.20.0, but I guess it is more or less the same across different versions.
The actual sources are located in the vfprintf.c file. There is a macro _VFPRINTF_R set to one of _svfiprintf_r, _vfiprintf_r, _svfprintf_r, or _vfprintf_r (depending on the build options), and then the actual implementation function is defined accordingly:
int
_DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
struct _reent *data _AND
FILE * fp _AND
_CONST char *fmt0 _AND
va_list ap)
{
...
http://www.ijs.si/software/snprintf/ has what they claim is a portable implementation of snprintf, including vsnprintf.c, asnprintf, vasnprintf, asprintf, vasprintf. Perhaps it can help.
The source code of the GNU C library (glibc) is hosted on sourceware.org.
Here is a link to the implementation of vfprintf(), which is called by snprintf():
https://sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/vfprintf.c

Resources