Building code for 0x00000000

cancel
Showing results for 
Search instead for 
Did you mean: 

Building code for 0x00000000

635 Views
edarrington
Contributor II

I wqould like to build a project to address 0x0, while still loading it into SPIFI memory at 0x14000000 using LPCExpresso:

NXP TechNote TN0006 states that:  "The intention in providing the MxMEMMAP registers is to make it possible to build for a fixed address. Always building code for 0x0000 0000 could simplify booting from different memories since the code will be the same regardless of the address of the memory."

That's exactly what I'd like to do.  I'd like to build my code for 0x00000000, use M4MEMMAP to set the shadow register, but still have the debugger load the code into SPIFI memory at the location of choice, such as 0x14000000.

It feels like there should be a simple linker option or directive to help with this, but I'm not having any luck finding it.  Can someone point me in the right direction?

Thanks!!

Tags (2)
0 Kudos
2 Replies

210 Views
lpcxpresso_supp
NXP Employee
NXP Employee

There is no support built in to LPCXpresso IDE to make use of this functionality.

You could perhaps use the memory configuration editor to add a duplicate flash region at 0x0 (which you would need to place first in the list). After building your image, you could then convert it to binary. Then use the GUI flash programmer to program the binary into the "real" flash memory address range. Finally you could then use an "attach only" debug connection to debug.

Using the GUI flash programming tool 

https://community.nxp.com/message/630604 

These additional steps for debugging are because your code is not built for the address that the flash drivers expect the flash to be at.

But this is all untested, and I can't make any guarantees.

Regards,

LPCXpresso Support

0 Kudos

210 Views
edarrington
Contributor II

Thank you, LPCX support, for your reply.  Your suggestion, however, that we use the GUI flash programmer to program, along with the attach-only debug methodology, seemed like it would make the edit/debug cycle quite cumbersome.  I figured there had to be a simpler way.

I found one.

Since I could not find any evidence of how to accomplish multiple regions with 0x0 base linking, and in case this is helpful to someone else, here's what we did:

1. As LPCX support suggested, in the memory configuration dialog, I createda flash memory location at 0x0 with the length required for the firmware.  We use a length of 0x40000 which is 256kB.  This should *not* be the first flash memory area listed (as the first location will be the load address).  We named the new segment ShadowFlash.

2. We modified the link_template.ld file with a simple change.  At the end of any .text section--after the close bracket--there normally is an instruction to position .text in the first firmware bank that looks like this:  >${CODE}.  Change that line to be: >ShadowFlash  AT>${CODE}.  This change instructs the linker to compile the code in the ShadowRam region (0x0), but load it in the ${CODE} region.  The macro ${CODE} resolves to the name of the first flash bank in the memory configuration dialog.

3. We used the M4MEMMAP register to set the base address of where the code will load, which is the first flash memory area in the memory configuration dialog.  M4MEMMAP tells the processor that any addresses referenced from 0 should be mapped to the ${CODE} region.  However, there's a gotcha here.  The M4MEMMAP register does not add a specified memory location to the M4MEMMAP value correctly.  It does an XOR instead.  To avoid this mapping problem, make sure that the entire region you hope to reach is represented by zeros in the ${CODE} region base address.  For example, using 0x14030000 will not work for more than one 64k block, but 0x14080000 will work for several 64k blocks.  In other words, the memory map register needs to be aligned to the nearest power of 2 that is greater than or equal to the size of the region you want to map.  I didn't design it, but that's how it works.

4. In the boot loader, after setting the M4MEMMAP register, do not immediately jump to a location in the new memory area.  Apparently it takes a beat or two before the M4MEMMAP register gets correctly set.  We defined the M4MEMMAP as volatile which may help, then we added a loop to read back the value until we were sure the value was set correctly, before jumping into the newly mapped space.  Again, I didn't design it, but much experimentation and debugging led to the conclusion.

Now our code can work in either our A region or B region.  It only debugs in the A region (which is ok with us), but the best part is that it loads correctly in the debugger just as before.

Thanks,

0 Kudos