Hi,
I need to place a function in a specific address or segment in memory. I'm using GNU compiler in CodeWarrior for Kinetis KL16.
Just as an example, I was able to do this using MSP430 MCU as below:
void f(void) @ "MYSEGMENT";
void g(void) @ "MYSEGMENT"
{
}
I would appreciate any help in this regard. Thanks in advance.
Solved! Go to Solution.
Hello Siavash:
That thing with the @ was possible with our compiler for S08/ColdFire V1 MCUs, but things are not so straightforward with Kinetis. You need to play with the linker file (.ld) and some function/variable attributes. Here an example:
Say you have a KL16 with 128 KB of flash, and you want to place a function at address 0x0001FF00 at the last part of flash. First in the linker file you would have something like this:
/* Specify the memory areas */
MEMORY
{
m_interrupts (rx) : ORIGIN = 0x00000000, LENGTH = 0xC0
m_cfmprotrom (rx) : ORIGIN = 0x00000400, LENGTH = 0x10
m_text (rx) : ORIGIN = 0x00000800, LENGTH = 128K - 0x800
m_data (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K /* SRAM */
}
We can reserve the last 256 bytes of flash (0x100) by creating a new memory segment called "my_flash_seg", and subtracting those bytes from the m_text segment:
/* Specify the memory areas */
MEMORY
{
m_interrupts (rx) : ORIGIN = 0x00000000, LENGTH = 0xC0
m_cfmprotrom (rx) : ORIGIN = 0x00000400, LENGTH = 0x10
m_text (rx) : ORIGIN = 0x00000800, LENGTH = 128K - 0x800 - 0x100 /* Subtract here the 0x100 */
my_flash_seg (rx) : ORIGIN = 0x0001FF00, LENGTH = 0x100 /* This is my new segment */
m_data (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K /* SRAM */
}
This only reserves a space in memory, but then below in the same linker file inside of SECTIONS we need to create a new section which specifically allocates parts of our code or variables in the "my_flash_seg" segment. In this case I called the new section "my_section". Notice also the tag ".mysegment", this is the tag we will use during function or variable declaration.
/* Section created to relocate code in specific Flash address */
.my_section
{
. = ALIGN(4);
*(.mysegment) /* This is the tag you use in code */
. = ALIGN(4);
} > my_flash_seg
This is all with the linker. The last step is to add an attribute to your function or variable declaration, using the tag mentioned before like this:
__attribute__ ((section(".mysegment"))) void my_func()
{
// ...
}
And that's it :smileylaugh:. It is a little complex, but once you do it a few times you get familiar with the procedure. For an example with RAM, check the next thread:
Re: Re: Syntax to allocate memory assignments to faster memory
And also a tutorial on this same topic by colleague Erich Styger:
Defining Variables at Absolute Addresses with gcc | MCU on Eclipse
Regards!
Jorge Gonzalez
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello Siavash:
That thing with the @ was possible with our compiler for S08/ColdFire V1 MCUs, but things are not so straightforward with Kinetis. You need to play with the linker file (.ld) and some function/variable attributes. Here an example:
Say you have a KL16 with 128 KB of flash, and you want to place a function at address 0x0001FF00 at the last part of flash. First in the linker file you would have something like this:
/* Specify the memory areas */
MEMORY
{
m_interrupts (rx) : ORIGIN = 0x00000000, LENGTH = 0xC0
m_cfmprotrom (rx) : ORIGIN = 0x00000400, LENGTH = 0x10
m_text (rx) : ORIGIN = 0x00000800, LENGTH = 128K - 0x800
m_data (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K /* SRAM */
}
We can reserve the last 256 bytes of flash (0x100) by creating a new memory segment called "my_flash_seg", and subtracting those bytes from the m_text segment:
/* Specify the memory areas */
MEMORY
{
m_interrupts (rx) : ORIGIN = 0x00000000, LENGTH = 0xC0
m_cfmprotrom (rx) : ORIGIN = 0x00000400, LENGTH = 0x10
m_text (rx) : ORIGIN = 0x00000800, LENGTH = 128K - 0x800 - 0x100 /* Subtract here the 0x100 */
my_flash_seg (rx) : ORIGIN = 0x0001FF00, LENGTH = 0x100 /* This is my new segment */
m_data (rwx) : ORIGIN = 0x1FFFF000, LENGTH = 16K /* SRAM */
}
This only reserves a space in memory, but then below in the same linker file inside of SECTIONS we need to create a new section which specifically allocates parts of our code or variables in the "my_flash_seg" segment. In this case I called the new section "my_section". Notice also the tag ".mysegment", this is the tag we will use during function or variable declaration.
/* Section created to relocate code in specific Flash address */
.my_section
{
. = ALIGN(4);
*(.mysegment) /* This is the tag you use in code */
. = ALIGN(4);
} > my_flash_seg
This is all with the linker. The last step is to add an attribute to your function or variable declaration, using the tag mentioned before like this:
__attribute__ ((section(".mysegment"))) void my_func()
{
// ...
}
And that's it :smileylaugh:. It is a little complex, but once you do it a few times you get familiar with the procedure. For an example with RAM, check the next thread:
Re: Re: Syntax to allocate memory assignments to faster memory
And also a tutorial on this same topic by colleague Erich Styger:
Defining Variables at Absolute Addresses with gcc | MCU on Eclipse
Regards!
Jorge Gonzalez
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------