Hi Paul
After another day of work I have defined a simple way to show that the "MultiSerialMega" fails (doesn't operate as normal) if the code is set at an offset.
This doesn't involve installing an boot loaders and can be reproduced by the following steps.
1. Normally build and load the MultiSerialMega project and verify that each character typed into the USB serial port is sent out on the UART output.
2. Now modified the linker script at one location:
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
to
FLASH (rx) : ORIGIN = 0x00008080, LENGTH = 256K
This shifts the code to start at 0x8080.
3. In mk20dx28.c comment out the watchdog unlock sequence (but not the wathdog disable).
/*
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
asm volatile ("nop");
asm volatile ("nop");*/
and change
SCB_VTOR = 0x0; // use vector table in flash
to
SCB_VTOR = 0x8080; // use vector table in flash
This means that the new interrupt vector location operates correctly. The reason for the watchdog unlock disable is explained below.
4. Build the project but don't load it to the Teensy yet (it can't run yet since it has no reset code at 0x00000000).
Now edit the hex file by adding these line at the very beginning (before the original code)
:10000000008000200900000044f205004fea004093
:1000100040f400504cf220524df62811c281c181ab
:1000200048f28000d0f800d0d0f804f0350000008d
:10040000FFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFD
This is a new reset vector that jumps to 0x00000008. At this address the code does the following:
asm("movw r0, #16389");
asm("lsl r0, r0, #16");
asm("orr r0, r0, #8192");
asm("movw r2, #50464");
asm("movw r1, #55592");
asm("strh R2, [r0, #14]");
asm("strh R1, [r0, #14]");
asm("movw r0, #32896");
asm("ldr sp, [r0]");
asm("ldr pc, [r0, #4]");
That is, it writes the watchdog unlock sequence and jumps to the code at 0x8080. [Also the flash config line is inserted into the HEX file so that the chip is left unsecured].
This is the minimum code needed to do this and it tests the offset without needing a boot loader installed. I found that I had to do the watchdog unlock here because the code would otherwise fail in the application, but the application is still disabling it (since it is unlocked and it has time to do it). The unlock sequence in the application seems otherwise to be too late and causes an immediate reset (there are a limited number of clock cycles after the reset in which it can be done).
With these simple modifications any Teensy project can be converted to a version that is offset and starts at the new offset.
5. Load the HEX file manually to the Teensy3.1 and test the project again and it will be seen that the USB enumerates correctly. The first character typed in also appears at the UART output.
The difference is however than no further characters are sent after that first one.
If the same is done with the blink project it is found that both HEX files work the same (with no offset of with the 0x8080 offset).
There is a definite behavioural difference with the MultiSerialMega project though.
This is quite consistent with results from production projects where everything looks fine until a certain change is made any then the behaviour deviates depending on the link address.
Therefore the question is still open as to why there is this behaviour with the Teensy/Arduino project code whereas it has never been experienced with a number of other projects used at offset addresses?
Regards
Mark