From: nono240 on
Hi there !

My CPU has no MMU, very little RAM (8KB), and is running a modified
FreeRTOS. I'd like to have the ability to "load" and run some code
from USART/DATAFLASH to FLASH as a RTOS task. Of course, for
convenience, the compiled code must be fully position independent.
Using the -fPIC or -fpic option, looking at the assembler, the code
seems OK : a dynamically computed offset is applied to every
operations.

BUT, looking deeply, both DATA and CODE are applied the base offset !
While this is the expected behavior for CODE (running anywhere in
FLASH), moving my CODE over the entire flash space doesn't mean moving
my RAM ! This make only sense when executing everything from SDRAM !

I'm looking for a solution to generate position independent *code*,
but with position dependent *data* using GCC/LD... Any help ?


From: Tim Wescott on
On 06/30/2010 08:41 AM, nono240 wrote:
> Hi there !
>
> My CPU has no MMU, very little RAM (8KB), and is running a modified
> FreeRTOS. I'd like to have the ability to "load" and run some code
> from USART/DATAFLASH to FLASH as a RTOS task. Of course, for
> convenience, the compiled code must be fully position independent.
> Using the -fPIC or -fpic option, looking at the assembler, the code
> seems OK : a dynamically computed offset is applied to every
> operations.
>
> BUT, looking deeply, both DATA and CODE are applied the base offset !
> While this is the expected behavior for CODE (running anywhere in
> FLASH), moving my CODE over the entire flash space doesn't mean moving
> my RAM ! This make only sense when executing everything from SDRAM !
>
> I'm looking for a solution to generate position independent *code*,
> but with position dependent *data* using GCC/LD... Any help ?
>
>
What processor?

Is the generated code using only relative branch instructions, or is it
using absolute branches in a '.o' file format that requires a loader to
fix up the absolute addresses? If so, why not fix up the code addresses
when you fix up the absolute ones?

You may be able to do this by not using any statically allocated memory
at all -- i.e., no file-extent variables. Allocate everything from
within a function (so it'll go on the stack) or explicitly allocate from
"malloc" (and make sure that heap fragmentation won't kill your app
after running for a bit longer than you ever tested for).

--

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
From: Vladimir Vassilevsky on


nono240 wrote:

> Hi there !
>
> My CPU has no MMU, very little RAM (8KB), and is running a modified
> FreeRTOS. I'd like to have the ability to "load" and run some code
> from USART/DATAFLASH to FLASH as a RTOS task. Of course, for
> convenience, the compiled code must be fully position independent.
> Using the -fPIC or -fpic option, looking at the assembler, the code
> seems OK : a dynamically computed offset is applied to every
> operations.
>
> BUT, looking deeply, both DATA and CODE are applied the base offset !
> While this is the expected behavior for CODE (running anywhere in
> FLASH), moving my CODE over the entire flash space doesn't mean moving
> my RAM ! This make only sense when executing everything from SDRAM !
>
> I'm looking for a solution to generate position independent *code*,
> but with position dependent *data* using GCC/LD... Any help ?

Define your variables in the other module, refer to it as "external".

VLV

From: David Brown on
On 30/06/2010 17:41, nono240 wrote:
> Hi there !
>
> My CPU has no MMU, very little RAM (8KB), and is running a modified
> FreeRTOS. I'd like to have the ability to "load" and run some code
> from USART/DATAFLASH to FLASH as a RTOS task. Of course, for
> convenience, the compiled code must be fully position independent.
> Using the -fPIC or -fpic option, looking at the assembler, the code
> seems OK : a dynamically computed offset is applied to every
> operations.
>
> BUT, looking deeply, both DATA and CODE are applied the base offset !
> While this is the expected behavior for CODE (running anywhere in
> FLASH), moving my CODE over the entire flash space doesn't mean moving
> my RAM ! This make only sense when executing everything from SDRAM !
>
> I'm looking for a solution to generate position independent *code*,
> but with position dependent *data* using GCC/LD... Any help ?
>
>

Unless you want to download multiple tasks like this, and have them
stored in arbitrary places in flash (and ram), then there is no need for
position-independent data or code. Simple arrange (by linker script
magic, typically) for the code and data to link at the specific
addresses of the flash and ram slots you have available.

From: Jon Kirwan on
On Wed, 30 Jun 2010 08:41:42 -0700 (PDT), nono240
<nono240(a)gmail.com> wrote:

>My CPU has no MMU, very little RAM (8KB), and is running a modified
>FreeRTOS. I'd like to have the ability to "load" and run some code
>from USART/DATAFLASH to FLASH as a RTOS task. Of course, for
>convenience, the compiled code must be fully position independent.
>Using the -fPIC or -fpic option, looking at the assembler, the code
>seems OK : a dynamically computed offset is applied to every
>operations.
>
>BUT, looking deeply, both DATA and CODE are applied the base offset !
>While this is the expected behavior for CODE (running anywhere in
>FLASH), moving my CODE over the entire flash space doesn't mean moving
>my RAM ! This make only sense when executing everything from SDRAM !
>
>I'm looking for a solution to generate position independent *code*,
>but with position dependent *data* using GCC/LD... Any help ?

Position independent code (in my mind, anyway) is machine
code that does not require a relinking or fixup phase in
order to be moved to a different address in memory. There
are a lot of assumptions in that statement.

Since your program requires _flash_ and _sram_ to operate and
you don't say that much about the cpu and software environs,
I can only add a few thoughts.

Code and constants used, either directly as data, such as a
table of values, or else copied into sram prior to the start
of the program to initialize writable variable instances that
need specific initial values to be present, can be placed
into flash either as a single segment or multiple ones.

However, with sram fixed in one place and flash in another
place (I'm assuming that's the case as you point out there is
no MMU), there is no question about the fact that there are
at least two separate segments in your situation. The base
address of the flash-located segment might be the PC register
so that this flash block can be moved around freely and uses
the PC register as a cheap way to figure out where it's own
stuff is at (assuming the processor supports that), but that
won't work for the sram data instance segment which is
obviously located "elsewhere." Somehow, a base address for
that region needs to be made available to your code and
applied at run time. What mechanism is available for that?
Can you reserve a segment for it located at a physical
address that is not permitted to change, for example? In
other words, reserve it?

Also, there are (not infrequently) specific hardware
peripherals and other features that may be "memory mapped" to
specific addresses. Clearly, these should not depend upon
the flash memory locations of your code.

How all this gets done does depend on what else you are
doing. And you haven't talked about that. I don't think
there is a universal, always-works-everywhere, answer. More
info is needed, I believe.

The above is general theory and applies broadly.

Jon