Hello everyone, first post. I bought a LPC2468 OEM board from Embedded Artists, and their flash tools documentation is lacking (particularly in the OpenOCD dept). I have two problems with OpenOCD (last version from svn) :
1 - While I can write the internal flash through ISP with Flash Magic, and then use the ‘dump_image’ command of OpenOCD to verify flash read capabilities, the first 16 DWords always come out as garbage. That would correspond to twice the size of the vector table. The rest of the dump is accurate.
2 - ‘flash write_image’, while not returning any error, does not modify the flash. However, ‘mww’ returns ‘memory write caused data abort’. I guess write_image does too, but the error does not display. What causes data aborts on write to internal flash? Do I need to disable protection registers first?
After reading through the user manual for the LPC2468, I may have found part of the answer for writing. I did not figure out what a data abort was before, and blamed it on OpenOCD. It seems like I need to write my program to RAM first, because the JTAG interface does not have direct access to internal flash.
I have no idea why the first 16 DWords come out as garbage on read back though. Is it always like that for ARM cpus?
Well, thanks for watching this highly exciting thread where a guy asks answers just to answer them himself later.
For the benefit of anyone stuck in the same situation, the solution to my ‘write’ problem is this : I had a misconfigured ‘working_area’ in the config file for OpenOCD. OpenOCD already handles the “write program to RAM then copy to Flash” part of the process, but needs a proper working_area defined in order to copy the program somewhere.
This is the line used when I began working with the board a couple weeks ago :
working_area 0 0xA0000000 0x100000 nobackup
This worked fine because I used a bootloader which initialized the external SDRAM chip, mapped at address 0xA0000000. However, since I now want to load my own stuff, this memory is no longer usable (my own boot code does not setup SDRAM GPIO’s at of now). Code written by OpenOCD was sent into the void, and the void copied into the Flash. Unfortunately, the void in this case seems to be 0xffffffff, the same as the erased value, so no apparent modification to flash content.
I now use the internal RAM hard-mapped to 0x40000000 :
working_area 0 0x40000000 0x10000 nobackup
Still no idea why dumping the first 16 DWords of the flash yield garbage? Readout through ISP gives accurate dump.
Concerning the 16 first dwords of flash returning “garbage”:
There’s a register on LPC24xx (and LPC23xx which I’m currently working with) called “MEMMAP”, it’s at 0xe01FC040 and it’s the Memory Mapping Control Register. And if you read an address from 0x00000000 - 0x00000003f, what you actually see depends on the content of this MEMMAP register. It’s done that way so you can redirect interrupts to a convenient location when not running from flash (which is physically mapped there).
If MEMMAP == 00 (bits), then bootloader-mode is active. The bootloader is at 0x7fffe000, and hence the first 16dwords are read from physical address 0x7fffe000-0x7fffe03f. That’s because the bootloader (in masked-rom) wants to have control over what’s being run when an interrupt occurs.
If MEMMAP == 01, then you are in user-flash mode. User flash starts at 0x00000000 and so the first 16 dwords are not visibly remapped, they correspond to the first 16 dwords in user-flash.
If MEMMAP == 10, then the first 16 dwords read are the first 16 dwords of internal RAM at 0x40000000, in case you want to dynamically change the interrupt vectors.
If MEMMAP == 11, then the first 16 dwoards are mapped to external memory busses available on some devices.
Why is it 16 dwords, and not only 8? A branch (=jump) on ARM can only directly reach an address in the range of +/-24bit around the current executing address. If you want to jump further, you will have to store the actual address *somewhere *, and this most often is the next 8 dwords after the instruction put in the interrupt table area.