MPC56xx RAM Image

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MPC56xx RAM Image

1,741 Views
tbonkers
Contributor II

I am trying to generate a RAM image for use with BAM, following the steps in this topic. Using Code Warrior, I am creating a project and selecting Build for RAM, then copied the __start.c file in my source, and compiled the project. However when it comes to modifying the linker file, I am a bit lost. The example is different from the LCF that I have in my project, which is below. I'm looking for some aid on how to modify the linker file for placing the code in RAM, and also how to make the program as small as possible.

Thanks

/* lcf file for MPC564xB/C processors                                          */
/*              3 MB Flash, 256KB SRAM                                     */




MEMORY
{
    pseudo_rom:             org = 0x40000000,   len = 0x00005800
    init:                   org = 0x40005800,   len = 0x00000800
    exception_handlers_p0:  org = 0x40006000,   len = 0x00001000
    exception_handlers_p1:  org = 0x40007000,   len = 0x00001000
   
    internal_ram:      	    org = 0x40008000,   len = 0x00033000
    heap  :                 org = 0x4003B000,   len = 0x00001000 /* Heap start location */
    stack :                 org = 0x4003C000,   len = 0x00001000 /* Start location for Stack */
    heap_p1  :              org = 0x4003D000,   len = 0x00001000 /* z0 Heap  */
    stack_p1 :              org = 0x4003E000,   len = 0x00001000 /* z0 Stack */
}

SECTIONS
{
    GROUP : {
      .init  : {}
      .init_vle (VLECODE) : {
        *(.init)
        *(.init_vle)
      }
    } > init

    GROUP : {
      .ivor_branch_table_p0 (VLECODE) ALIGN (2048) : {}
      .intc_hw_branch_table_p0 ALIGN (2048) : {}           
      .__exception_handlers_p0 (VLECODE) : {}
    } > exception_handlers_p0

    GROUP : {
      .ivor_branch_table_p1 (VLECODE) ALIGN (2048)  : {}
      .intc_hw_branch_table_p1 (VLECODE) ALIGN (2048) : {}   
      .__exception_handlers_p1 (VLECODE) : {}
    } > exception_handlers_p1

    GROUP : {
      .intc_sw_isr_vector_table_p0 ALIGN (2048) : {}
      .intc_sw_isr_vector_table_p1 ALIGN (2048) : {}

        .text (TEXT) ALIGN(0x1000) : {}
        .text_vle (VLECODE) ALIGN(0x1000): {
             *(.text)
             *(.text_vle)
         }
        .rodata (CONST) : {
            *(.rdata)
            *(.rodata)
        }
        .ctors : {}
        .dtors : {}
        extab : {}
        extabindex : {}
    } > pseudo_rom

    GROUP : {    
       .__uninitialized_intc_handlertable ALIGN(0x10) : {}
       .data   : {}
       .sdata  : {}
       .sbss   : {}
       .sdata2 : {}
       .sbss2  : {}
       .bss    : {}
    } > internal_ram
}

/* Freescale CodeWarrior compiler address designations */

_stack_addr = ADDR(stack)+SIZEOF(stack);
_stack_end  = ADDR(stack);
_heap_addr  = ADDR(heap);
_heap_end   = ADDR(heap)+SIZEOF(heap);

_stack_addr_p1 = ADDR(stack_p1)+SIZEOF(stack_p1);
_stack_end_p1  = ADDR(stack_p1);
_heap_addr_p1  = ADDR(heap_p1);
_heap_end_p1   = ADDR(heap_p1)+SIZEOF(heap_p1);


/* Exceptions Handlers Location (used in Exceptions.c for IVPR initialization) */

EXCEPTION_HANDLERS = ADDR(exception_handlers_p0);
EXCEPTION_HANDLERS_P1 = ADDR(exception_handlers_p1);

 

 

 

0 Kudos
11 Replies

1,318 Views
tbonkers
Contributor II

I am now trying to run code from RAM of a target that does not have any firmware in the flash, hence the RAM is always filled with random garbage. As the function usr_init() is not called for a RAM project, where should I place the RAM initialization code?

 

 

    /* MPC5646 B/C L2SRAM initialization code                         */
    lis r11,L2SRAM_LOCATION@h
    ori r11,r11,L2SRAM_LOCATION@l
    li r12,1994 /*Counter = ((256K - 0x1B00)/4) /32 */
    mtctr r12
    init_l2sram_loop:
        stmw r0,0(r11)        /* Write all 32 GPRs to L2SRAM */
        addi r11,r11,128      /* Inc the ram ptr; 32 GPRs * 4 bytes = 128 */
        bdnz init_l2sram_loop /* Loop for 256k of L2SRAM */

 

 

 

I was placing it in the __start.c code, but it does not work and RAM is not initialized correctly.

Edit: Comments in file __start.c suggest that the memory should be initialized in function __init_hardware. Is that where the RAM initialization is supposed to happen?

/***************************************************************************/
/*
* __start
*
* PowerPC EABI Runtime Initialization. Initialize pointers,
* initialize data, and call main().
*
* This function is the very first location executed in a program, or
* the first location called by the board-level initialization.
* Memory access is not guaranteed to be safe until after __init_hardware.
*/
/***************************************************************************/
0 Kudos

1,725 Views
tbonkers
Contributor II

I think I managed to get the application running from RAM using the linker script below. I've edited the section sizes to make them smaller, and will appreciate any advise on how to make them even smaller.

When I download the code with PE Micro it runs ok, still have not tested it with BAM, as I need to construct  a RAM binary first. In the linked post above there was a description on how to do it, and if my understanding is correct, the procedure is:

  • Download the code in RAM
  • Dump RAM from MCU. In my case, that will be from addresses 0x40000000 to 0x40001D00, 7 kilobytes.
  • Save the dump as .bin file

What is unclear to me now is the statement Notice that downloading of code also initializes ECC. Area that is not written by BAM will contain ECC errors. If your application wants to use uninitialized RAM, it must be explicitly initialized by your SW. I am using only 0x4000 bytes of RAM in my application. How can I make sure that the RAM, heap and stack are properly initialized by my code?

Thanks

/* lcf file for MPC564xB/C processors                                          */
/*              3 MB Flash, 256KB SRAM                                     */

MEMORY
{
    init:                   org = 0x40000000,   len = 0x00000400
    exception_handlers_p0:  org = 0x40000800,   len = 0x00000300
    exception_handlers_p1:  org = 0x40000A00,   len = 0x00000300	
    pseudo_rom:             org = 0x40000D00,   len = 0x000001000

    internal_ram:      	    org = 0x40002000,   len = 0x00004000
    heap  :                 org = 0x40006000,   len = 0x00001000 /* Heap start location */
    stack :                 org = 0x40007000,   len = 0x00001000 /* Start location for Stack */
    heap_p1  :              org = 0x40008000,   len = 0x00001000 /* z0 Heap  */
    stack_p1 :              org = 0x40009000,   len = 0x00001000 /* z0 Stack */
}

SECTIONS
{
    GROUP : {
      .init  : {}
      .init_vle (VLECODE) : {
        *(.init)
        *(.init_vle)
      }
    } > init

    GROUP : {
      .ivor_branch_table_p0 (VLECODE) ALIGN (512) : {}
      .intc_hw_branch_table_p0 ALIGN (512) : {}           
      .__exception_handlers_p0 (VLECODE) : {}
    } > exception_handlers_p0

    GROUP : {
      .ivor_branch_table_p1 (VLECODE) ALIGN (512)  : {}
      .intc_hw_branch_table_p1 (VLECODE) ALIGN (512) : {}   
      .__exception_handlers_p1 (VLECODE) : {}
    } > exception_handlers_p1

    GROUP : {
      .intc_sw_isr_vector_table_p0 ALIGN (512) : {}
      .intc_sw_isr_vector_table_p1 ALIGN (512) : {}

        .text (TEXT) ALIGN(512) : {}
        .text_vle (VLECODE) ALIGN(512): {
             *(.text)
             *(.text_vle)
         }
        .rodata (CONST) : {
            *(.rdata)
            *(.rodata)
        }
        .ctors : {}
        .dtors : {}
        extab : {}
        extabindex : {}
    } > pseudo_rom

    GROUP : {    
       .__uninitialized_intc_handlertable ALIGN(0x10) : {}
       .data   : {}
       .sdata  : {}
       .sbss   : {}
       .sdata2 : {}
       .sbss2  : {}
       .bss    : {}
    } > internal_ram
}

/* Freescale CodeWarrior compiler address designations */

_stack_addr = ADDR(stack)+SIZEOF(stack);
_stack_end  = ADDR(stack);
_heap_addr  = ADDR(heap);
_heap_end   = ADDR(heap)+SIZEOF(heap);

_stack_addr_p1 = ADDR(stack_p1)+SIZEOF(stack_p1);
_stack_end_p1  = ADDR(stack_p1);
_heap_addr_p1  = ADDR(heap_p1);
_heap_end_p1   = ADDR(heap_p1)+SIZEOF(heap_p1);


/* Exceptions Handlers Location (used in Exceptions.c for IVPR initialization) */

EXCEPTION_HANDLERS = ADDR(exception_handlers_p0);
EXCEPTION_HANDLERS_P1 = ADDR(exception_handlers_p1);

 

Tags (1)
0 Kudos

1,717 Views
tbonkers
Contributor II

I am posting a new answer to avoid editing the post above.

 

I dumped the RAM with the running application and saved is as a binary file, then I sent it to BAM - but the application does not run. When connecting the debugger and examining the contents of the RAM, I can see the application image inside, programmed at location 0x40000100 as intended. Below are the first four locations in RAM:

40000000: 40000100 00000000 40001B00 00000000

 

First is the location of the application in RAM, and third is application size (0x40001B00). From this I would conclude that BAM has written the image in RAM correctly.

 

Here's the relevant linker script part:

MEMORY
{
    init:                   			org = 0x40000100,   len = 0x00000400
    exception_handlers_p0:  	org = 0x40000500,   len = 0x00000300
    exception_handlers_p1:  	org = 0x40000800,   len = 0x00000300	
    pseudo_rom:             		org = 0x40000B00,   len = 0x000001000

    internal_ram:      	    org = 0x40002000,   len = 0x00004000
    heap  :                 org = 0x40006000,   len = 0x00001000 /* Heap start location */
    stack :                 org = 0x40007000,   len = 0x00001000 /* Start location for Stack */
    heap_p1  :              org = 0x40008000,   len = 0x00001000 /* z0 Heap  */
    stack_p1 :              org = 0x40009000,   len = 0x00001000 /* z0 Stack */
}

 

There's no reset_vector, but there was none in the original linker script, and the application runs fine when downloaded with debugger.

 

0 Kudos

1,710 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi Teddy,

you can check in the map file if the __start function is placed right at the beginning of the image.

Regarding ECC - when using RAM project, RAM is not initialized by the code because it would overwrite itself.

usr_init() is called only in flash project:

lukaszadrapa_0-1643640778498.png

Then it calls also this piece of code (in MPC5646C_HWInit.c):

/* MPC5646 B/C L2SRAM initialization code */
lis r11,L2SRAM_LOCATION@h
ori r11,r11,L2SRAM_LOCATION@l
li r12,2048 /* Loop counter to get all of L2SRAM; 256k/4 bytes/32 GPRs = 2048 */
mtctr r12
init_l2sram_loop:
stmw r0,0(r11) /* Write all 32 GPRs to L2SRAM */
addi r11,r11,128 /* Inc the ram ptr; 32 GPRs * 4 bytes = 128 */
bdnz init_l2sram_loop /* Loop for 256k of L2SRAM */

You can use this code to initialize the rest of the RAM - everything behind your BAM image. You just need to change L2SRAM_LOCATION and loop counter accordingly.

This is important step and I guess that this is source of the troubles.

Regards,

Lukas

0 Kudos

1,703 Views
tbonkers
Contributor II

Hi Lucas,

I just wrote an answer and lost it when I had to sign in again. Shame.

 

I did a small change in the linker script and I think it's ok:

.init_vle section layout
  Starting        Virtual  File
  address  Size   address  offset
  ---------------------------------
  00000000 00013e 40000100 00000240  1 .init 	__start.o 
  00000000 000064 40000100 00000240  4 __start 	__start.o 
..............................
Memory map:
                       Starting Size     File       S-Record
                       address           Offset     Line
             .init_vle 40000100 0000025c 00000240          2
                 .init 4000035c 000000cc 0000049c         33

 

I can still see the RAM image correctly placed by the BAM at address 0x40000100, but I don't see anything from 0x40000000-0x400000FF. When I connect with the debugger after downloading the RAM image, the program counter points at seemingly random location. When I set the PC to 0x40000100, the code runs fine.

That probably means BAM is not transferring execution to the downloaded code.

0 Kudos

1,690 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

It's OK that you can see nothing at 0x4000_0000 - 0x4000_00FF. You should not use this area. I can see that your linker file is correct because it starts at 0x4000_0100. There's a note in the RM:

lukaszadrapa_0-1643707944897.png

Do you check echo characters? Are all of them correct?

lukaszadrapa_1-1643708035091.png

If you received all and correct echo characters, I can see only one scenario when BAM does not jump to the image - when you entered wrong size of image and the BAM still waits for additional characters. So, try to check the size again.

And make sure that the rest of the RAM is initialized as mentioned in previous post.

Regards,

Lukas

0 Kudos

1,622 Views
tbonkers
Contributor II

I noticed that the RAM application only runs when the device has been powered-on into Flash mode, then boot configuration changed, and the device being reset. After that RAM code downloads and runs OK. Apart from that peculiarity, the RAM application works fine.

0 Kudos

1,616 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

I'm almost 100% sure that this is a problem of RAM ECC initialization. I guess that there's some application in the flash which initializes the RAM. Reset will not affect the RAM and it works in this case. After power-on, the RAM is not initialized and your application downloaded by BAM obviously does not initializes the rest of the RAM appropriately. Please double check this initialization in your application.

Regards,

Lukas

0 Kudos

1,610 Views
tbonkers
Contributor II

I hope it is - here's the code I currently use, copied it from somewhere else:

 

	/* Initialize the SRAM after the RAM image */
	
	lis 		r30, 0x0000
	lis 		r31, 0x0000
	lis 		r11, 0x4000
	ori		r11, r11, 0x1B00
sram_init:
	stmw	r30, 0(r11)
	addi		r11, r11, 8
	andi.		r12, r11, 0xFFFF
	bne		sram_init	
	
	lis 		r30, 0x0000
	lis 		r31, 0x0000
	lis 		r11, 0x4001
	ori		r11, r11, 0x0000
sram_init2:
	stmw	r30, 0(r11)
	addi		r11, r11, 8
	andi.		r12, r11, 0xFFFF
	bne		sram_init2

 

Edit: I also tried the code you suggested. Here's the memory layout:

MEMORY
{
init: org = 0x40000100, len = 0x00000400
exception_handlers_p0: org = 0x40000500, len = 0x00000300
exception_handlers_p1: org = 0x40000800, len = 0x00000300
pseudo_rom: org = 0x40000B00, len = 0x000001000

internal_ram: org = 0x40001B00, len = 0x00001000
heap : org = 0x40002B00, len = 0x00000400 /* Heap start location */
stack : org = 0x40002F00, len = 0x00000400 /* Start location for Stack */
heap_p1 : org = 0x40003300, len = 0x00000400 /* z0 Heap */
stack_p1 : org = 0x40003700, len = 0x00000400 /* z0 Stack */
}

 

And the RAM init function, with the RAM address adjusted to 0x40001B00, which is the space after the image:

/* MPC5646 B/C L2SRAM initialization code */
lis r11,0x4000
ori r11,r11,0x1B00

li r12,1994 /*Counter = ((256K - 0x1B00)/4) /32 */
mtctr r12

init_l2sram_loop:
stmw r0,0(r11) /* Write all 32 GPRs to L2SRAM */
addi r11,r11,128 /* Inc the ram ptr; 32 GPRs * 4 bytes = 128 */
bdnz init_l2sram_loop /* Loop for 256k of L2SRAM */

 

The result is the same again, if I try to boot directly into BAM, I can't load the code. Need to boot into Flash first.

0 Kudos

1,590 Views
lukaszadrapa
NXP TechSupport
NXP TechSupport

The second version should definitely work, I can't see a problem here.

"if I try to boot directly into BAM, I can't load the code" - Do you mean you can't load the image ever or it just does not run? Have you received all echo characters?

Regards,

Lukas

0 Kudos

1,584 Views
tbonkers
Contributor II

The image does not run, but is received and echoed correctly. It's not a big deal, as the device always boots in Flash first, but it's an interesting problem.

0 Kudos