Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #27474 > unrolled thread

Copy to and execution from RAM

Started byKlaus Kragelund <klauskvik@hotmail.com>
First post2017-12-22 12:13 -0800
Last post2018-01-02 11:49 +0100
Articles 11 — 7 participants

Back to article view | Back to comp.arch.embedded


Contents

  Copy to and execution from RAM Klaus Kragelund <klauskvik@hotmail.com> - 2017-12-22 12:13 -0800
    Copy to and execution from RAM Klaus Kragelund <klauskvik@hotmail.com> - 2017-12-22 12:21 -0800
      Copy to and execution from RAM Klaus Kragelund <klauskvik@hotmail.com> - 2017-12-22 12:27 -0800
      Re: Copy to and execution from RAM lasselangwadtchristensen@gmail.com - 2017-12-27 09:56 -0800
    Re: Copy to and execution from RAM Dave Nadler <drn@nadler.com> - 2017-12-23 08:29 -0800
    Re: Copy to and execution from RAM marcin.tomasz.bawolski@gmail.com - 2017-12-24 03:29 -0800
    Re: Copy to and execution from RAM pozz <pozzugno@gmail.com> - 2017-12-28 08:56 +0100
    Re: Copy to and execution from RAM Richard Damon <Richard@Damon-Family.org> - 2017-12-28 09:51 -0500
      Re: Copy to and execution from RAM pozz <pozzugno@gmail.com> - 2017-12-28 17:50 +0100
        Re: Copy to and execution from RAM Richard Damon <Richard@Damon-Family.org> - 2017-12-28 12:08 -0500
    Re: Copy to and execution from RAM Gunther Mannigel <newsgroups@mannigel.net> - 2018-01-02 11:49 +0100

#27474 — Copy to and execution from RAM

FromKlaus Kragelund <klauskvik@hotmail.com>
Date2017-12-22 12:13 -0800
SubjectCopy to and execution from RAM
Message-ID<08cd49ed-14ef-4c81-b609-3fdeaef04a7e@googlegroups.com>
Hi

I am using a STM32 and I want to use the flash as storage, but I need the processor to keep running

Writing to flash while execution from flash will take about 20us for 16bit value and when the entire block is close to be filled up an erase of the block takes 20ms

20ms halt of code execution is not an option  

So, the plan is:

Copy code that needs to run to RAM
Move program counter to first RAM address to start RAM execution
Write to flash, and keep running in RAM
When finished writing to flash, return code execution to flash (that way only limited code needs to be copied to RAM). Move program counter to flash

But, I have never written such a program before 

Isn’t just a matter of copying the flash contents to RAM byte for byte? Of course I need to make sure reference to flash functions since then I will be in trouble 

So it’s just a couple of lines of code??

Cheers

Klaus 

[toc] | [next] | [standalone]


#27475

FromKlaus Kragelund <klauskvik@hotmail.com>
Date2017-12-22 12:21 -0800
Message-ID<51337af2-6594-4209-bddc-2b0c568ae8de@googlegroups.com>
In reply to#27474
Of course I need to make sure reference to flash functions since then I will be in trouble

Should be:

Of course I need to make sure no reference to flash functions are possible since then I will be in trouble

[toc] | [prev] | [next] | [standalone]


#27476

FromKlaus Kragelund <klauskvik@hotmail.com>
Date2017-12-22 12:27 -0800
Message-ID<10454142-eea0-4a02-8582-9a196d039956@googlegroups.com>
In reply to#27475
This app note is probably a good starting point:

http://www.st.com/content/ccc/resource/technical/document/application_note/group0/7c/6a/88/d1/27/04/46/2f/DM00260799/files/DM00260799.pdf/jcr:content/translations/en.DM00260799.pdf


[toc] | [prev] | [next] | [standalone]


#27479

Fromlasselangwadtchristensen@gmail.com
Date2017-12-27 09:56 -0800
Message-ID<f256f559-a034-4513-a00e-060a83bfc57a@googlegroups.com>
In reply to#27475
Den fredag den 22. december 2017 kl. 21.21.26 UTC+1 skrev Klaus Kragelund:
> Of course I need to make sure reference to flash functions since then I will be in trouble
> 
> Should be:
> 
> Of course I need to make sure no reference to flash functions are possible since then I will be in trouble

don't forget the interrupt vectors if you need interrupts

[toc] | [prev] | [next] | [standalone]


#27477

FromDave Nadler <drn@nadler.com>
Date2017-12-23 08:29 -0800
Message-ID<aafa8110-55fb-4a2d-a8f8-7e2e5fe02445@googlegroups.com>
In reply to#27474
You've got a number of problems...

1) Code must be compiled/linked for the specific location you're
going to execute it, or alternatively compiled as "position independent code". Otherwise when you copy it to RAM, it isn't going to work.

2) The code can't reference any other code in areas which are off-limits
during flash programming.

The details of how to do this are highly dependent on the specific
tool chain you are using.

Hope that helps!
Best Regards, Dave

[toc] | [prev] | [next] | [standalone]


#27478

Frommarcin.tomasz.bawolski@gmail.com
Date2017-12-24 03:29 -0800
Message-ID<d76f6b9c-d76d-459a-9c95-008ca330d77c@googlegroups.com>
In reply to#27474
Hi,

When using GCC placing code to execute in RAM is quite straightforward. All you need is an __attribute__ and correct section in linker file. 

Here some example I used:

#define FASTRUN __attribute__ ((long_call, section (".code_in_ram")))

FASTRUN void blink3(uint32_t *reg0, uint32_t reg1, uint32_t reg2) {

	while (1) {
		asm("str r1, [r0]");
		asm("str r2, [r0]");
	}
}
Here only important is my FASTRUN attribute, assembly inside was only to test how fast I can toggle pin on XMC1200

Above code can be automatically copied from flash to ram in the same way as initialized data  are copied at startup from flash to runtime location.

Part of my linkerfile:

MEMORY
{
  rom (rx)  : org = 0x10001000, len = 0x32000
  ram (rwx) : org = 0x20000000, len = 0x4000
}
..........other sections were cut......

  .data : 
  {
    . = ALIGN(4);
    __data_init_start = LOADADDR (.data);
    PROVIDE(__data_init_start = __data_init_start);
    __data_start = .;
    PROVIDE(__data_start = __data_start);

    . = ALIGN(4);
    *(.data .data.* .gnu.linkonce.d.*)
    
    . = ALIGN(4);
     *(.code_in_ram)
   
    . = ALIGN(4);
    __data_end = .;
    PROVIDE(__data_end = __data_end);
  } > ram AT > rom

Section .code_in_ram will contain in our blink3 function.

syntax > ram AT >rom will tell linker to set runtime  addresses of section .data to ram but have them ready to load from rom ( flash in my case)

already existing startup code initializing data (between __data_init_start and __data_end )  will copy our blink3 to ram, and all calls to this function from your program will have 

Cheers, 
Marcin  

[toc] | [prev] | [next] | [standalone]


#27480

Frompozz <pozzugno@gmail.com>
Date2017-12-28 08:56 +0100
Message-ID<p2283r$lem$1@dont-email.me>
In reply to#27474
Il 22/12/2017 21:13, Klaus Kragelund ha scritto:
> Hi
> 
> I am using a STM32 and I want to use the flash as storage, but I need the processor to keep running
> 
> Writing to flash while execution from flash will take about 20us for 16bit value and when the entire block is close to be filled up an erase of the block takes 20ms
> 
> 20ms halt of code execution is not an option

I encountered the same problem on a project that used a Cortex-M3 NXP 
MCU.  My solution was to add an external I2C EEPROM for data storage.

Your solution could be ok, but it's very complex to implement. 
Additional to place code in RAM, compile with "position indipendent" 
code address and so on... the big issue is with interrupts.

If you can't accept a program that blocks for 20ms, I imagine you have 
ISRs that react to some events in a short time (for example, data 
received by some peripheral, such as UART).
In your scenario, you need to move ISRs code to RAM too *and* the 
interrupt vectors.

Surely this can be done, but it is difficult to me.
It could be nice to see a full project that works in this way for some 
Cortex-Mx MCUs and arm-gcc toolchain.

[toc] | [prev] | [next] | [standalone]


#27481

FromRichard Damon <Richard@Damon-Family.org>
Date2017-12-28 09:51 -0500
Message-ID<Rx71C.113857$qe.55431@fx18.iad>
In reply to#27474
On 12/22/17 3:13 PM, Klaus Kragelund wrote:
> Hi
> 
> I am using a STM32 and I want to use the flash as storage, but I need the processor to keep running
> 
> Writing to flash while execution from flash will take about 20us for 16bit value and when the entire block is close to be filled up an erase of the block takes 20ms
> 
> 20ms halt of code execution is not an option
> 
> So, the plan is:
> 
> Copy code that needs to run to RAM
> Move program counter to first RAM address to start RAM execution
> Write to flash, and keep running in RAM
> When finished writing to flash, return code execution to flash (that way only limited code needs to be copied to RAM). Move program counter to flash
> 
> But, I have never written such a program before
> 
> Isn’t just a matter of copying the flash contents to RAM byte for byte? Of course I need to make sure reference to flash functions since then I will be in trouble
> 
> So it’s just a couple of lines of code??
> 
> Cheers
> 
> Klaus
> 

Normally, you don't just 'move' code designed to run in flash to ram to 
run it, but you tag the needed parts of code with some attribute to tell 
the compiler/linker to build such code to be placed in ram in the first 
place (copied from flash at startup, like any variables with static 
initializers). This is commonly done for things like this, where you 
need to write code to update the flash the program came from.

Some processors have two blocks of flash with separate controllers 
allowing code to run from one when the other is being updated. 
Processors that only have one controller ARE much harder to use part of 
the flash for non-volatile update-able parameter storage due to the 
issue you are seeing. You normally need to have the code 'blink' (go 
into a severally reduced capability mode)during the flash update, or on 
boot up copy the full program into ram (but often there isn't enough ram 
for this)

[toc] | [prev] | [next] | [standalone]


#27482

Frompozz <pozzugno@gmail.com>
Date2017-12-28 17:50 +0100
Message-ID<p237di$a44$3@dont-email.me>
In reply to#27481
Il 28/12/2017 15:51, Richard Damon ha scritto:
 > [...]
> Some processors have two blocks of flash with separate controllers 
> allowing code to run from one when the other is being updated. 

One of this is SAM C21 MCUs from Atmel/Microchip.  Maybe others from the 
same manufacturer.

Do you know something else?

Anyway I don't think this is a "two separate controllers" problem.  I 
think the Flash memory is manufactured in a different way.

[toc] | [prev] | [next] | [standalone]


#27483

FromRichard Damon <Richard@Damon-Family.org>
Date2017-12-28 12:08 -0500
Message-ID<Rx91C.19506$ET6.8269@fx38.iad>
In reply to#27482
On 12/28/17 11:50 AM, pozz wrote:
> Il 28/12/2017 15:51, Richard Damon ha scritto:
>  > [...]
>> Some processors have two blocks of flash with separate controllers 
>> allowing code to run from one when the other is being updated. 
> 
> One of this is SAM C21 MCUs from Atmel/Microchip.  Maybe others from the 
> same manufacturer.
> 
> Do you know something else?
> 
> Anyway I don't think this is a "two separate controllers" problem.  I 
> think the Flash memory is manufactured in a different way.

The bank being erased, obviously can't have code running in it, 
typically multiple pages of flash have a single controller which is 
simple enough that it can't handle writing/erasing one bank while 
reading from another, and with this sort of controller, sometimes a 
given processor will have 2 controllers, so that one set of banks can be 
running code, while the other is having data being updated. Sometimes 
the 2 controllers use different size pages, with big pages for the 
larger flash memory for programs and smaller pages for the smaller flash 
for data.

There are also some processors with controllers that can read from one 
bank while writing to another, in which case you don't have this issue. 
I know that a lot of the Microchip controllers work this way, you just 
need to make sure you keep your data and code in different pages.

It has been a few years since I have done a processor selection survey, 
so not in the best place to give options.

[toc] | [prev] | [next] | [standalone]


#27484

FromGunther Mannigel <newsgroups@mannigel.net>
Date2018-01-02 11:49 +0100
Message-ID<fb16d1F6eujU1@mid.individual.net>
In reply to#27474
Am 22.12.2017 um 21:13 schrieb Klaus Kragelund:
> Copy code that needs to run to RAM
> Move program counter to first RAM address to start RAM execution
> Write to flash, and keep running in RAM
> When finished writing to flash, return code execution to flash (that way only limited code needs to be copied to RAM). Move program counter to flash

Yes, it's that easy. If you write the RAM code in assembler, you can
make sure that no relocation of adress data is necessary. If you don't,
you should tell the linker of that code segment in RAM. Either an extra
segment or an overlay.
There may be some security / MMU that prevents code execution in RAM /
segments with write enabled.
Be sure not to trigger any interrupt, as the vector table usually
resides in FLASH. Imho ARM lets you relocate that into RAM.
I remember a TI app note about that for MSP430, but other vendors will
have that too, as this is a well known problem of boot loaders. Maybe
there is something like that hard coded into that uC?

cheers
Gunther

[toc] | [prev] | [standalone]


Back to top | Article view | comp.arch.embedded


csiph-web