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);
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?
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:
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);
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.
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:
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
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.
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:
Do you check echo characters? Are all of them correct?
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
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.
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
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.
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