<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.arm.com/utility/feedstylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/developer/tools-software/tools/f/keil-forum/31967/lpc1768-copy-function-code-for-flash-to-ram</link><description> 
I use the LPC1768 board and I want to copy a function from flash
to RAM in runtime. I use the following code 

 
void f() 
{ int x=0; printf(&amp;quot;%d\n&amp;quot;,x); 
} void g() 
{ int x=5; printf(&amp;quot;Hello: g&amp;quot;); printf(&amp;quot;%d\n&amp;quot;,x); 
} int main(void) 
{ char c; static</description><dc:language>en-US</dc:language><generator>Telligent Community 10</generator><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/133928?ContentTypeID=1</link><pubDate>Tue, 03 Jun 2014 07:12:17 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:a7d3c6f5-2d83-4245-997f-a0914cc2c187</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello,&lt;br /&gt;
Regarding the Hard Fault exception. This took place because of the
LSP of PC was 0. I fixed this . And now the only issue that I have is
with the permision writes.&lt;br /&gt;
I went throught the datasheet of LPC1768 and I noticed that the
region 0x10004000 has exec rights.&lt;br /&gt;
The program counter has LSB 1.&lt;br /&gt;
I attached the scatter file again&lt;br /&gt;
LR_IROM1 0x00000000 0x00080000 { ; load region size_region ER_IROM1
0x00000000 0x00080000 { ; load address = execution address *.o(RESET,
+First) *(InRoot&amp;#36;&amp;#36;Sections) *.o(+RO) } RW_IRAM1 0x10000000 0x00004000
{ ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x10004000 0x00002000 { ; RW
data *(section)&lt;/p&gt;

&lt;p&gt;
}&lt;/p&gt;

&lt;p&gt;
Regarding the scatter file the following memory mapping is
generated for the variable ProgramRamToSpace&lt;/p&gt;

&lt;p&gt;
Execution Region RW_IRAM2 (Base: 0x10004000, Size: 0x00000040,
Max: 0x00002000, ABSOLUTE)&lt;/p&gt;

&lt;p&gt;
Base Addr Size Type Attr Idx E Section Name Object&lt;/p&gt;

&lt;p&gt;
0x10004000 0x00000040 Data RW 137 section copytoram.o.&lt;/p&gt;

&lt;p&gt;
This variable includes function instructions. But its type is
Data. Can i mark in someway this variable as thumb code type as the
functions that are allocated in ROM. I read carefully your previous
post and I think that the corrects instructions are saved in the
buffer and the initial address of the function in the RAM is
correct.&lt;/p&gt;

&lt;p&gt;
Thank you for your time&lt;/p&gt;

&lt;p&gt;
Best regards&lt;br /&gt;
George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/133929?ContentTypeID=1</link><pubDate>Tue, 03 Jun 2014 02:05:10 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:9cee123c-25db-4f50-b333-e5d52657e367</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello,&lt;br /&gt;
I understood your point. I was not right before. The INVSTATE bit is
1 not INVPC.&lt;br /&gt;
Thank you&lt;br /&gt;
George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/120337?ContentTypeID=1</link><pubDate>Tue, 03 Jun 2014 01:45:05 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:46045726-cbd0-4846-8047-86d019e62c3a</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
When placing functions in RAM using the scatter file, you can get
the linker to store the function code in the flash similar to initial
data values. But the linker links the function will all references as
if the code is in RAM. So any part of the program that wants to call
the function will make jumps into RAM. And the startup code can keep
track of how large the function is and perform the copy from flash to
RAM.&lt;/p&gt;

&lt;p&gt;
Have you verified the individual assembler instructions to make
sure that your memcpy() really will place a complete and correct
function into RAM? The error indicates that you either land at the
wrong address, or that there isn&amp;#39;t correct code in the RAM. Or that
you are copying to a RAM region that doesn&amp;#39;t support program
execution.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/107720?ContentTypeID=1</link><pubDate>Tue, 03 Jun 2014 01:33:33 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:d04ed87b-3432-464a-8de1-28cd3e1d5df9</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello,&lt;br /&gt;
The function use use absolute addresses, I think. The only that do is
a simple add.&lt;/p&gt;

&lt;p&gt;
Have look below :&lt;br /&gt;
I have this simple function that I copy&lt;br /&gt;
void f()&lt;br /&gt;
{ int x=5; int y=5; int a=x+5;&lt;br /&gt;
} I use this code to copy&lt;br /&gt;
void copyToRam()&lt;br /&gt;
{&lt;/p&gt;

&lt;p&gt;
static void (*fnRAM_code)(void) = f;&lt;/p&gt;

&lt;p&gt;
unsigned char *pCodeStart = (unsigned char *)f;&lt;br /&gt;
f(); // f is allocated in flash&lt;/p&gt;

&lt;p&gt;
//thump2 addresss&lt;br /&gt;
pCodeStart = (unsigned char *)(((unsigned int)pCodeStart) &amp;amp;
~0x1);&lt;/p&gt;

&lt;p&gt;
//copy all the instructions of the f function in buffer that is
allocated in RAM&lt;br /&gt;
memcpy((char*)ProgRamSpace,pCodeStart,sizeof(ProgRamSpace));&lt;/p&gt;

&lt;p&gt;
//create a thumb-2 call&lt;br /&gt;
fnRAM_code = (void(*)(void))(&amp;amp;ProgRamSpace[1]);//The last
significant of PC should be 1&lt;/p&gt;

&lt;p&gt;
/create a call&lt;br /&gt;
(*fnRAM_code)();&lt;/p&gt;

&lt;p&gt;
}&lt;/p&gt;

&lt;p&gt;
The first issue when I executed the code is that there are not
read/execute rights in the region that the ProgRamSpace is allocated.
But in memory map seems that this region has execute rights.&lt;/p&gt;

&lt;p&gt;
The other is issue is that INVPC has value 1.&lt;/p&gt;

&lt;p&gt;
But the instructions in the RAM and ROM are the same.&lt;/p&gt;

&lt;p&gt;
- which is the reason why it&amp;#39;s nice to have the linker link the
function for use in RAM but with an initial copy stored in flash&lt;/p&gt;

&lt;p&gt;
I can not understand what you mean. If I copy the function, the if
I load the instruction should execute, should it?&lt;/p&gt;

&lt;p&gt;
Best regards&lt;br /&gt;
George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/93200?ContentTypeID=1</link><pubDate>Tue, 03 Jun 2014 00:39:14 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:0a554343-2534-46b8-a52a-aa51800148c9</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
But what instructions have you copied?&lt;/p&gt;

&lt;p&gt;
Does the function use absolute or relative addresses when
accessing other functions or data? It isn&amp;#39;t so trivial to just move a
function to a different address - which is the reason why it&amp;#39;s nice
to have the linker link the function for use in RAM but with an
initial copy stored in flash. Then you know that the RAM function
makes correct accesses to all other symbols it needs access to.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/62860?ContentTypeID=1</link><pubDate>Tue, 03 Jun 2014 00:16:29 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:2ee6dcb8-ac8d-4902-94cb-936325308976</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello,&lt;/p&gt;

&lt;p&gt;
Regarding to the above problem (LPC1768 copy function code for
flash to RAM). The Hard fault exception takes place because of the
INVPC bit in usageFault Register is 1. I can not understand why this
happens. The first instruction in the f function that is allocated in
the flash is the same with the instruction that is allocated in RAM
after copy.&lt;br /&gt;
Could you please provide a solution&lt;br /&gt;
Best regards&lt;br /&gt;
George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/150410?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 13:03:06 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:0efa0f63-d801-4ec0-a71a-4ac1600c275e</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
Hello,&lt;br /&gt;
Thanks for the sample.&lt;br /&gt;
It is very useful&lt;br /&gt;
George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/149977?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 11:40:56 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:6efc7ba3-44be-47b0-a212-e919ebf82076</guid><dc:creator>Westonsupermare Pier</dc:creator><description>&lt;p&gt;&lt;p&gt;
Here I put a whole object file in RAM, but you can do so on a
section or function basis also.&lt;br /&gt;
&lt;a href="http://www.keil.com/forum/24821/"&gt;http://www.keil.com/forum/24821/&lt;/a&gt;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/149505?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 10:38:07 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:b8f791ee-ab1f-4cec-8d71-39cd3925b2fc</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
If reprogramming a flash, then it&amp;#39;s often best to create a
self-contained piece of assembler code to run in RAM to make really
sure there aren&amp;#39;t any hidden helper functions that gets referenced
from flash.&lt;/p&gt;

&lt;p&gt;
But if the goal is to use RAM for additional speed, like critical
ISR or evaluation code, then it works well to just make use of the
scatter file.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/149008?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 09:43:25 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:b38aaa8a-cbe8-4c7d-9f34-1d395be0e0a9</guid><dc:creator>Westonsupermare Pier</dc:creator><description>&lt;p&gt;&lt;p&gt;
Clearly there are many solutions to the problem, but the problem
is multifaceted and one really has to understand the requirements and
ramification very precisely.&lt;/p&gt;

&lt;p&gt;
If you start calling functions, or libraries from RAM based code
you need to make sure everything in the call tree is brought there
too, if the goal is to modify or erase flash, or other things that
would preclude running from flash, or would cause significant
stalling of execution.&lt;/p&gt;

&lt;p&gt;
IAR has a directive like &amp;#39;ramfunc&amp;#39; in Keil I think you need to use
attributes, sections and scatter files, I&amp;#39;ve made that work in the
past too, but don&amp;#39;t have my example to hand.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/128610?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 09:07:34 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:0f970d7c-3875-4f63-8887-a2dd2d77a98e</guid><dc:creator>ImPer Westermark</dc:creator><description>&lt;p&gt;&lt;p&gt;
Why not let the linker place the function in RAM? Then the startup
code will perform the copy of the code from flash into RAM and all
references to that function will make use of the RAM address.&lt;/p&gt;

&lt;p&gt;
The datasheet for the processor contains information which memory
regions that supports code execution, DMA transfers etc.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/120339?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 08:13:21 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:4402b271-3e29-49fa-8872-28cea3dc9fa2</guid><dc:creator>Westonsupermare Pier</dc:creator><description>&lt;p&gt;&lt;p&gt;
As I said, I know very little about the NXP/LPC part, would have
to research addresses and if core design permits execution from RAM,
or requires remapping, so more generically&lt;/p&gt;

&lt;pre&gt;
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

typedef int (*pFunction)(void);

void ExecuteFromRAM(void)
{
    static const uint16_t CodeStart[] = { 0xF04F, 0x007B, 0x4770 }; // function, in ROM
    uint8_t ProgRamSpace[16]; // as big as required, here on stack
    pFunction fnRAM_code;

    memcpy(ProgRamSpace, CodeStart, sizeof(CodeStart)); // Copy code

    fnRAM_code = (pFunction)&amp;amp;ProgRamSpace[1]; // +1 for Thumb code

    printf(&amp;quot;%d\n&amp;quot;,fnRAM_code());
}
&lt;/pre&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/107719?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 07:29:01 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:37df68cc-6c83-4591-8d62-e250b51be503</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
I have already check this in address 0x20000000 and does not
works. When access the function pointer that indicates to the buffer,
that are saved the instructions a HardFault exception is
triggered&lt;br /&gt;
The scatter file&lt;br /&gt;
LR_IROM1 0x00000000 0x00080000 { ; load region size_region ER_IROM1
0x00000000 0x00080000 { ; load address = execution address *.o
(RESET, +First) *(InRoot&amp;#36;&amp;#36;Sections) .ANY (+RO) } RW_IRAM1 0x20000000
0x00008000 { ; RW data .ANY (+RW +ZI) }&lt;br /&gt;
} George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/81927?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 07:21:39 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:e9a268d2-93b2-4b91-97db-6e276bfe9ba9</guid><dc:creator>George Tsoumplekas</dc:creator><description>&lt;p&gt;&lt;p&gt;
Thank you for the prompt reply,&lt;br /&gt;
Yes I know that is very hard and maybe does not work in this way. For
this reason I have an really small f function.&lt;br /&gt;
Then, I have already checked the instructions that are saved in the
ProgRamSpace and seems to be correct. The problem as I explain above
is that the function can not execute in this memory space Your point
is to allocate the ProgRamSpace in the address 0x20000000, is
this?&lt;br /&gt;
Thank you&lt;br /&gt;
George&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item><item><title>RE: LPC1768 copy function code for flash to RAM</title><link>https://community.arm.com/thread/62854?ContentTypeID=1</link><pubDate>Thu, 29 May 2014 07:02:12 GMT</pubDate><guid isPermaLink="false">dd9e70c8-6d3c-4c71-b136-2456382a7b5c:a2533f33-0fca-4be7-a912-5e0f9d4b31f3</guid><dc:creator>Westonsupermare Pier</dc:creator><description>&lt;p&gt;&lt;p&gt;
It&amp;#39;s real hard to determine the size of a compiled function and
it&amp;#39;s literal pool, or the relative position to branch to external
subroutines, etc.&lt;/p&gt;

&lt;p&gt;
Thumb code needs to be copied to 16-bit half-word address, but
execution will be at an ODD address, nominally the base address you
copied to plus one.&lt;/p&gt;

&lt;p&gt;
The RAM may, or may not, permit execution, don&amp;#39;t know about
NXP/LPC, but others fault at 0x10000000, but work at 0x20000000&lt;/p&gt;

&lt;p&gt;
Try a little assembler code fragment that sets R0 with a value and
returns, and print the result from that.&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;</description></item></channel></rss>