Send variable to linker via source code - c

In some header I've got FLASH_BASE and FLASH_SIZE makro and I would like to use them in linker script. I have tried something like this:
// main.c
long CURRENT_FLASH_START = FLASH_BASE + FLASH_SIZE / 2;
int main(void) {
return 0;
}
// s_FLASH.ld
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 48K
RAM2 (xrw) : ORIGIN = 0x10000000, LENGTH = 16K
FLASH (rx) : ORIGIN = CURRENT_FLASH_START, LENGTH = 256K
}
But in map file I see that place for code in flash starts at address 0. Is there any possibilty to use variable from makro (from .h file) in linker script file? I use Ac6 STM32 MCU GCC with Gnu Make builder.

Related

Linker with overlapping memory definitions

I made an ld script with the following memory layout:
MEMORY
{
FLASH (rx) : ORIGIN = 0x00027000, LENGTH = 0xC8000
RAM (rwx) : ORIGIN = 0x20003FC0, LENGTH = 0x3B040
RRAM (rwx) : ORIGIN = 0x2000F000, LENGTH = 0x01000
}
As you can see, the RRAM (from 0x2000F000 to 0x2000FFFF) portion overlaps with the RAM portion (from 0x20003FC0 to 0x2002FFF). The code compiles and links with no warnings or errors.
My question is: during normal code execution,.will the system still be able to use the memory from 0x2001000 up to 0x2002FFF? Or does this unusual layout stop the code from using anything after the end of RRAM (unless explicitly allocated to an address)?

GCC some data outside sections

This is my linker file memory definition (Cortex M4 MCU with flash memory starting at 0x0 address):
MEMORY
{
m_interrupts (RX) : ORIGIN = 0x0000A000, LENGTH = 0x00000410
m_text (RX) : ORIGIN = 0x0000A410, LENGTH = 0x00050BF0
m_data (RW) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001F000
m_data_2 (RW) : ORIGIN = 0x2000F000, LENGTH = 0x00001000
}
I want to offset my flash from 0x0 to 0xA000 to keep the beginning of the flash clean.
However, when I generate my output (bin) file for my project, I can see the beginning of the flash is still occupied by some data. From .map file I think this is .ARM.attributes, .debug_info, .debug_abbrev, etc. I don't know what it is, but I want the beginning of my flash to be clean, not programmed by anything. How to remove these data from my output bin file or how to move this data to the end of the output bin file?

PIC32 Bootloader app linker script boot section

A Bootloader and an application is working fine.
The bootloader loads the application, and then jumps into it.
The problem: I need to use different linker script to either have the app standalone or bootloader compatible.
I believe it is because the memory segment is not correctly defined for kseg0_program_mem, kseg0_boot_mem & kseg1_boot_mem.
//_RESET_ADDR = 0xBFC00000; <- work without bootloader
_RESET_ADDR = 0x9D000480; <- work with bootloader
[....]
MEMORY
{
kseg0_program_mem (rx) : ORIGIN = 0x9D000000 + 0x800, LENGTH = 0x100000 - 0x800
kseg0_boot_mem : ORIGIN = 0x9D000000, LENGTH = 0x0
debug_exec_mem : ORIGIN = 0x9FC20490, LENGTH = 0x3B20
kseg0_boot_mem : ORIGIN = 0x9FC20490, LENGTH = 0x0
kseg1_boot_mem : ORIGIN = 0x9D000000, LENGTH = 0x480
kseg1_boot_mem_4B0 : ORIGIN = 0xBFC004B0, LENGTH = 0x3B00
config_BFC03FC0 : ORIGIN = 0xBFC03FC0, LENGTH = 0x4

Why won't debug linker file compile (ld:200 cannot move location counter backwards)

Now before you you tell me my program is using too much memory...
I know what "cannot move location counter backwards means"...
here is the real problem...
I have a linker file that WILL compile no problem.
call this linker file release version....
MEMORY
{
/* SOFTCONSOLE FLASH USE: microsemi-smartfusion2-envm */
rom (rx) : ORIGIN = 0x20000000, LENGTH = 35k
/* SmartFusion2 internal eSRAM */
ram (rwx) : ORIGIN = 0x20008C00, LENGTH = 29k
}
RAM_START_ADDRESS = 0x20008C00; /* Must be the same value MEMORY region ram ORIGIN above. */
RAM_SIZE = 29k; /* Must be the same value MEMORY region ram LENGTH above. */
MAIN_STACK_SIZE = 11k; /* Cortex main stack size. */
MIN_SIZE_HEAP = 512; /* needs to be calculated for your application */
notice the entire space occupied is 64k... this compiles
but when I try to use the following linker file (debug); I get the location counter error
MEMORY
{
/* SmartFusion2 internal eSRAM */
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64k
}
RAM_START_ADDRESS = 0x20000000; /* Must be the same value MEMORY region ram ORIGIN above. */
RAM_SIZE = 64k; /* Must be the same value MEMORY region ram LENGTH above. */
MAIN_STACK_SIZE = 11k; /* Cortex main stack size. */
MIN_SIZE_HEAP = 512; /* needs to be calculated for your application */
THE ONLY differences between the two linker files are show plus anywhere there is a >rom or >ram AT>rom directive in the release version, it is replace by >ram in the debug version...
I am using the same exact optimize and debugging flags
When I try to link the debug version i get the following error
ld:200 cannot move location counter backwards (from 20011d80 to 2000d400)
Anyone have any ideas???

Allocate an array in C a specific location using linker commands

I am a beginner... I would like to write to a specific memory location in my embedded flash...How do I mention it in my C header file? And then link it with the specific memory location using linker scripts. Right now I have declared the array as extern and it compiles properly. While liking, I need to tell the linker that I need it at this particular location. Should it be given in .ld file? What is a .dld file? This is not for GCC, for diab compiler. I have seen a sample code bubble.dld for bubble sort. But in some projects .dld files are created while making the project. In what step is it actually created?
First solution
in ".c":
// Talk to linker to place this in ".mysection"
__attribute__((section(".mysection"))) char MyArrray[52];
in ".ld":
MEMORY {
m_interrupts (RX) : ORIGIN = 0x00040000, LENGTH = 0x000001E8
m_text (RX) : ORIGIN = 0x00050000, LENGTH = 0x000BFE18
/* memory which will contain secion ".mysection" */
m_my_memory (RX) : ORIGIN = 0x00045000, LENGTH = 0x00000100
}
SECTIONS
{
/***** Other sections *****/
/* place "mysection" inside "m_my_memory" */
.mysection :
{
. = ALIGN(4);
KEEP(*(.mysection));
. = ALIGN(4);
} > m_my_memory
/***** Other sections *****/
}
Second solution
in ".c"
extern char myArray[52];
in ".ld"
MEMORY {
m_interrupts (RX) : ORIGIN = 0x00040000, LENGTH = 0x000001E8
m_text (RX) : ORIGIN = 0x00050000, LENGTH = 0x000BFE18
/* memory which will contain secion "myArray" */
m_my_memory (RX) : ORIGIN = 0x00045000, LENGTH = 0x00000100
}
SECTIONS
{
/***** Other sections *****/
/* place "myArray" inside "m_my_memory" */
.mysection :
{
. = ALIGN(4);
myArray = .; /* Place myArray at current address, ie first address of m_my_memory */
. = ALIGN(4);
} > m_my_memory
/***** Other sections *****/
}
See this good manual to learn more how to place elements where you want

Resources