running application in RAM with IAR

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

running application in RAM with IAR

4,704 Views
ryanlush
Contributor IV

I would like to write an IAR application that lives solely in RAM. I have a bootloader that will load the code via USB at runtime but I don't know how to setup the linker script. Does anyone have an example? Just a linker script would be nice but a whole project would be fantastic.

IAR Execute in RAM after copying from Flash or ROM 

IAR Download and run whole application in RAM (Cortex-M3) 

I'm trying to follow these examples but IAR doesn't work that way anymore (big surprise). I took the gpio_led_output I found in the CMSIS pack examples but it tells me I can only edit the linker in the text editor. Honestly I didn't even know the "edit" button would bring up another menu, I always assumed it just open the file in an editor.

0 Kudos
10 Replies

3,501 Views
ryanlush
Contributor IV

The keyword __root seems to protect it but it's not placed at 0x20000000 as I have told it to.

0 Kudos

3,501 Views
ryanlush
Contributor IV

I am able to force the entry point to a given address as long as the function is named __low_level_init. If I rename this function startup (its not really the __low_level_init function in the compiler sense) the compiler tosses it out because it's not actually called from my program. What must I do to prevent the compiler from removing this "unused" function?

0 Kudos

3,501 Views
ryanlush
Contributor IV

I apologize for my "shotgun" approach to asking questions...

I'm not sure if this is right but I added a call to main at the bottom of my __low_level_init function and I've got some blinking lights now.

0 Kudos

3,501 Views
ryanlush
Contributor IV

I've got one more piece of the puzzle figured out. I added this

place at address mem:__ICFEDIT_region_ROM_start__ { readonly section .init };

to the linker file and then added

#pragma location=".init"

above my __low_level_init function. I can see that the __low_level_init function is now at 0x20000000 but I still dont ever see the code jumping to main.

0 Kudos

3,501 Views
ryanlush
Contributor IV

Mark,

When you say you are loading and operating in SRAM, what exactly are you loading? Is this some code that exists as a standalone IAR project (meaning it includes the low level init stuff). The only thing I've done is update the linker script to put everything in RAM and then override the low_level_init.c code with my own where I update the SCB_VTOR

SCB_VTOR = (unsigned int) & __vector_table;

I jump to the code like so...

typedef void(*jumpFunc)(void);

uint8_t BootJump(uint32_t address)
{
    /* Jump to whatever address user specifies */
    jumpFunc jump = (jumpFunc)(address | 0x1);
    jump();
        
    //EnableInterrupts
    return TRUE;
}

with address = 0x20000000

the contents of that address is the new stack pointer and when I jump to that address I get a hardfault. I want to use the upper SRAM to hold my ramcode and the lower SRAM is for my stack and heap with the stack pointer starting at 0x20000000.

Essentially what im trying to do is create a project i can use to build ramcode modules I can load and run at runtime. When I do this with the older processor expert (not sure if im saying this right, before KSDK I used codewarrior and a GNU compiler) code my startup function looks like this

__attribute__ ((section (".init"))) void startup(void)
{
    extern unsigned int __vector_table[];
    extern char __START_BSS[];
    extern char __END_BSS[];
    char * ptr = __START_BSS;
    
    __DI();
    
    /* Copy interrupts from flash to allow RAM code to install it's own handlers */
    memcpy(__vector_table, (unsigned char *)ROM_VECTOR_LOCATION, VECTOR_TABLE_SIZE);
    SCB_VTOR = (uint32_t)__vector_table; /* Set the interrupt vector table position */

    //    zero-fill the .bss section
    while(ptr != __END_BSS)
    {
        *ptr++ = 0x00;
    }

    /* Enter main with interrupts disabled */
    main();

    /* Reset interrupt vectors to ROM */
    SCB_VTOR = (uint32_t)ROM_VECTOR_LOCATION;
    
    /* Return to bootloader */
        
}

IAR has hidden most of the startup code from me so I can't figure out where I need to initialize things.

Does any of this make sense? I'm having a hard time explaining what I'm trying to do.

0 Kudos

3,501 Views
mjbcswitzerland
Specialist V

Ryan

You don't want to jump to the stack pointer - you want to jump to the entry point - this is at 0x20000004 and not at 0x20000000.

You need to load the content of the first address to the SP and then the second to the PC (or jump to it as you have done).

You don't need to "or" the address with 1 since if it is valid code it will already be an odd (Thumb) address.

Regards

Mark

P.S. I use only the IAR variable initialisation code (which one can't really avoid) and nothing else from the IAR startup.

P.P.S. I understand what you are doing since I have done the same in various product developments with Cortex parts

0 Kudos

3,501 Views
ryanlush
Contributor IV

Mark,

Would you be willing to take a look at my code if I shared it with you? I would like to force the entry point to be 0x20000000 (it needs to be to be backwards compatible with my code warrior bootloader). I was able to move the vector table to 0x2007000 but the disassembly I see at 0x20000000 does not look like an entry point. From the map file I see it placed "packbits_init_single" at 0x20000000.

What exactly should my entry point be considering the bootloader as already initialized the processor? I tried to force it to be _low_level_init in the linker settings but that doesn't appear to do anything. I also tried to change the assembly in the reset handler to jump to __low_level_init instead of __iar_program_start but the linker complains that its missing __iar_data_init3. I don't think I want the reset handler to be the entry point anyways.

0 Kudos

3,500 Views
ryanlush
Contributor IV

Mark,

What I’m really trying to do is move the vector table to 0x2007000 so 0x20000000 would be the entry point.

Then at ramcode startup I will copy the bootloader’s vector table to the new location so I can install my own handlers.

Thank you,

Ryan

(sent from mobile device)

0 Kudos

3,501 Views
mjbcswitzerland
Specialist V

Ryan

I have attached an IAR linker script from the uTasker project which I use to load and operate in SRAM.
This particular one is for Kinetis K parts with 128k SRAM.
Maybe it will help.

Regards

Mark

0 Kudos

3,500 Views
ryanlush
Contributor IV

Mark,

Thank you so much! I also found an example project at the bottom of this link

IAR Download and run whole application in RAM (Cortex-M3) 

its for an ST processor but it was still very helpful.

0 Kudos