EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Running code from Ethernet and USB RAM

Started by "h.belig" January 7, 2009
I tested 2 short programmes from Paul. Both are doing well.
So we know that it principally should work.

One difference however is that I am using the section attribute to
locate code into these 16k-byte-segments, while Paul's programme
copies the code.

0x80000000 is the start address of external NOR flash. I changed that
source address to 0x40000100, which is internal SRAM, but that did not
solve the problem.

Henry

--- In l..., "capiman26061973"
wrote:
>
> Hello Henry,
>
> have you tried to comment out the content of CopyMem2 ?
> Or e.g. do a single access ? Or only a write access ? Or only a read
> access ?
>
> You have two addresses, which you access: one is RAM, the other i
> don't know, is it a real address, which you can access ?
>
> Can you perhaps copy only a few locations from SRAM to SRAM ?
>
> Regards,
>
> Martin
>
> --- In l..., "h.belig" wrote:
> >
> > Please ignore my last posting. That was overhasty.
> > I had forgotten to rename the line that assigns the section.
> > As a result CopyMem has been executed in internal flash.
> >
> > So the problem still exists:
> > test_me() is fine, but CopyMem() is not.
> > Once again, this is main.c, this time with both functions:
> >
> > typedef unsigned long DWORD;
> > void CopyMem2(DWORD *QuellAdr, DWORD *ZielAdr, DWORD Length)
> > __attribute__ ((section(".usbfast")));
> >
> >
> > void CopyMem2(DWORD *QuellAdr, DWORD *ZielAdr, DWORD Length) {
> > DWORD *PtSrc, *PtDest, Len, i;
> > PtSrc = QuellAdr;
> > PtDest = ZielAdr;
> > for (i=0; i < Length; i++) {
> > *PtDest++ = *PtSrc++;
> > }
> > }
> >
> > void test_me(void) {
> > int i;
> > typedef void (*void_fn)(void);
> > register unsigned long *ethernet_ram=(unsigned long*)0x7fe00000;
> >
> > // Run lots of ARM NOPs
> > for (i=0;i<1024;++i) ethernet_ram[i]=0xE51B3020; // ldr
r3,[r11,-32]
> > ethernet_ram[i]=0xE12FFF1E;
> > __asm volatile (" ldr r11,=0x40000840");
> > __asm volatile (" ldr r3,=0x7fe00000");
> > __asm volatile (" bx r3"); // tail call
> > }
> >
> > main() {
> > test_me();
> > CopyMem2((DWORD *)0x80000000, (DWORD *)0x40000100, 30);
> > }
> >
> > Does anybody have an idea?
> >
> >
> >
> >
> >
> >
> >
> > --- In l..., "h.belig" wrote:
> > >
> > > Hello Paul,
> > >
> > > thank you for the program.
> > >
> > > I invoked both subroutines one after another. Your program is
ok, mine
> > > is not.
> > >
> > > When I renamed my function from CopyMem to CopyMem1 everything
was ok.
> > > I have no idea why that solved the problem and how such issues
can be
> > > avoided. Is there a list of forbidden function names?
> > > Does anybody has an explanation?
> > >
> > > Henry
> > >
> > >
> > >
> > >
> > >
> > > --- In l..., "lpc2100_fan" wrote:
> > > >
> > > > --- In l..., "Paul Curtis" wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > I suggest you try this simple program. I used an LPC2378
> board, not
> > > > a 2486
> > > > > (no idea what a 2486 is). 2478? I used the Olimex LPC2478-STK
> > > and it's
> > > > > just fine on that too. Make sure you do indeed have rev. B
> silicon.
> > > > >
> > > > > void main(void)
> > > > > {
> > > > > void *p;
> > > > >
> > > > > int i;
> > > > > typedef void (*void_fn)(void);
> > > > > unsigned long *ethernet_ram = (unsigned long *)0x7FE00000;
> > > > >
> > > > > // Run lots of ARM NOPs.
> > > > > for (i = 0; i < 1024; ++i)
> > > > > ethernet_ram[i] = 0xE1A00000;
> > > > > ethernet_ram[i] = 0xE12FFF1E;
> > > > > ((void_fn)ethernet_ram)();
> > > > >
> > > > > // Run lots of Thumb NOPs.
> > > > > for (i = 0; i < 1024; ++i)
> > > > > ethernet_ram[i] = 0x46C046C0;
> > > > > ethernet_ram[i] = 0x47704770;
> > > > > ((void_fn)((char *)ethernet_ram+1))();
> > > > >
> > > > > debug_printf("OK!");
> > > > > }
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: l...
> [mailto:l...] On
> > > > Behalf
> > > > > Of
> > > > > > h.belig
> > > > > > Sent: 07 January 2009 15:10
> > > > > > To: l...
> > > > > > Subject: [lpc2000] Running code from Ethernet and USB RAM
> > > > > >
> > > > > > Did anybody ever run program code from the ethernet or usb
> RAM of
> > > > LPC2468?
> > > > > >
> > > > > > I am using EA's LPC2486-16 OEM Board and Rowley`s
> "CrossStudio for
> > > > ARM".
> > > > > > I modified the flash_placement file and created sections for
> > these 2
> > > > > > 16KB RAM areas.
> > > > > > When I start debugging, I reach the subroutine that is
placed in
> > > that
> > > > > > ram section. I also can do some steps in the routine
(assembler
> > > > > > instructions), but then I get an "undef" exception (or an
> "abort"
> > > > > > exception when I tested with another project).
> > > > > >
> > > > > > According to the errata sheet the ethernet ram cannot be used
> > > because
> > > > > > of an issue with silicon revision '-'. I have got revision
'B',
> > > which
> > > > > > should not have this problem.
> > > > > >
> > > > > > Can anybody advice?
> > > > > >
> > > > > > Henry
> > > > > >
> > > >
> > > > Hi Henry,
> > > >
> > > > just for your information. Even if you get the code to run
from bith
> > > > of the SRAMS, connected to the AHB busses, the code will be MUCH
> > > > slower than running from internal Flash or the other 64K SRAM. It
> > > > loads through "bus-bridges" to be mirrored into the code
space. You
> > > > can still gt the benefit of easier debugging using the AHB SRAM
> but it
> > > > is not going to be real-time.
> > > > You get 100% speed from the 64k SRAM, >90% from internal Flash
> > > > probably around 50% from AHB SRAM and less than that from external
> > > > memory.
> > > >
> > > > Bob
> > > > -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > > > Need a consultant with in depth LPC2000 knowledge? -> Let me know!
> > > > http://www.lpc2000.com
> > > > -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> > > >
> > >
>

An Engineer's Guide to the LPC2100 Series

Here comes the solution (thanks to Paul Curtis!):

The modifications to the sections in flash_placement.xml were correct.

But the programme code has to be copied "manually" from internal flash
to the desired RAM section. Only for the '.fast' section this is done
automatically.
This just requires the labels of the sections and 2 memcpy functions
at the beginning of 'main'.

// External symbols defining where data is initialized and when it
// needs to run
// labels are generated by linker, see "Linking and section placement"
// in HELP menu!
extern unsigned char __ethernetfast_load_start__[];
extern unsigned char __ethernetfast_start__[];

extern unsigned char __usbfast_load_start__[];
extern unsigned char __usbfast_load_end__[];
extern unsigned char __usbfast_run_start__[];

/*****************************************************************************/
main() {

// Initialize .usbfast and .ethernetfast sections from copies held
// in internal FLASH
memcpy(__ethernetfast_start__, __ethernetfast_load_start__, 0x4000);
memcpy(__usbfast_run_start__, __usbfast_load_start__,
__usbfast_load_end__ - __usbfast_load_start__);

...


The 2024 Embedded Online Conference