Controlling data and function placement in memory

cancel
Showing results for 
Search instead for 
Did you mean: 

Controlling data and function placement in memory

Jump to solution
4,535 Views
sfarzan
Contributor I

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.

Labels (1)
1 Solution
478 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

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!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

1 Reply
479 Views
Jorge_Gonzalez
NXP Employee
NXP Employee

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!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post