Hi,
i'm working on a custom bootloader for qe64/qe32. I need to use an interrupt (timer overflow, a timer that I need when interfacing with a radio) in bootloader program. I need that interrupt also in the application. How two ISR could live togehter (the one I use in bootloader and latter I use in application)?
Thank you
Roberto.
Hello Roberto,
Even though automatic vector redirection is available for the 'QE64, it cannot be used whenever the bootloader itself requires interrupt usage. Therefore the bootloader will need to implement vector redirection from the normal vector range. I would suggest the following criteria for this process.
A small function within the bootloader would be required for every interrupt vector available within the MCU. For the interrupts that are applicable to both the bootloader and the user program, the function would need to ascertain whether bootloader mode was current or not, and direct execution to the appropriate ISR function within the bootloader or user code. For the other interrupts applicable to only the user code, the function would always redirect execution to the address contained within the specific entry of the shifted user vector table.
For HCS08 devices, the redirection process is complicated by the fact that the H-register is not automatically saved to the stack when an interrupt occurs. Therefore, the redirection process must not corrupt the H-register value, and when the true ISR function commences, the stack pointer must be identical to when the redirection function was first entered (since the true ISR function will terminate with a RTI instruction). It is not possible to achieve this with a conventional indexed jump, but is possible with a bit of stack manipulation.
The attached code snippet I hope will demonstrate the suggested process a little more clearly.
Regards,
Mac
Hi Bigmac, thank you.
Even though automatic vector redirection is available for the 'QE64,
For qe32 vector redirection is possible but for qe64 is not.
bigmac ha scritto:
2. The user code should not require "special" ISR functions, and should operate correctly if directly loaded using BDM, without the presence of the bootloader code. In this case, the user vector table would be situated within the normal range.
If user code does not require special ISR function and should opertate correctly if directly loaded using BDM, in your file when I have an interrupt in bootloading sequence I fall in
__interrupt void boot_ISR_TPM1CH0( void)
{
// Bootloader ISR code here
}
Here I never fall in, correct?
void ISR_TPM1CH0( void)
{
if (!bootctrl) { // Finished with bootloader
__asm {
ais #-2; // Create space on stack
pshh; // Save register value
ldhx (Vtpm1ch0 - BOOTSIZE); // User ISR address - shifted vector table
sthx 2,sp; // Place on stack
pulh; // Restore register value
rts; // Execute user ISR
}
}
__asm jmp boot_ISR_TPM1C0); // Jump to bootloader ISR
}
Hello Roberto,
There are potentially a number of different scenarios with respect to the programming of the user program code.
Within my earlier post, I attermpted to cover the first two scenarios. I did not address the last scenario. The code snippet provided was part of the bootloader code only, and would not be present for the first scenario above.
Regards,
Mac
1) You can make bootloader vectors pointing to jump table entries in RAM. Bootloader and application could then initialize this jump table for their own needs.
2) You can define one ISR in bootloader, which reads function pointer from fixed address and calls it. Bootloader and application initialize this function pointer with address of function that will service interrupt.
2) In case your app ISR and boot ISR are supposed to do exactly the same thing like incrementing some timer counter, then you may define your counter variable at fixed address, known to both application and bootloader...
Thank you, now I try your first second option and then I will tell you.
Roberto