View previous topic :: View next topic |
Author |
Message |
wirelessage
Joined: 08 Aug 2012 Posts: 34
|
bootloader memory stomping issue |
Posted: Tue Apr 16, 2013 5:50 am |
|
|
Hi all:
I got my bootloader application to work, but with a main tweek. I had to disable my high priority interrupt in the updated code and change all handlers to same LOWER priority. If I have HIGH priority interrupt enabled, RAM data keeps getting stomped over and I see junk values.
Any reasons why this could be happening?
Some questions:
a) Do I have to do anything special about saving restoring ISR contexts? I didn't think so.. because CCS does that right?
b) I do see some forums talk about not using MOVFF with fast interrupts... but this was working with my original code when there was no bootloader.
My goal is to download all the code as is without having to make these tweeks (such as changing interrupt priority as it will change the timing of the software running).
Setup:
--------
Compiler: tested with both 4.092 and 4.118, but no luck.
PIC18F2680.
Using ccs client for download.
Here is my "bootloader.h" file
Code: |
#define LOADER_END 0x7FF
#define LOADER_SIZE 0x4FF
#ifndef _bootloader
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
#org 0, LOADER_END {}
#endif
int bootLoad;
#locate bootLoad=0x900
|
My ex_bootloader.c has the following make-up:
Code: |
void main(void) {
unsigned char myTemp;
//read sticky byte from an used location.
//If sticky byte is NOT Set, then run bootloader application.
myTemp = read_eeprom(0x600);
if( myTemp != 0x3) //set by loader once firmware update is done.
bootLoad = 1;
else
bootLoad = 0;
if( bootLoad == 1)
{
my_main();
load_program();
goto_address(NEW_APP_LOCATION); //0x800
}
else
{
goto_address(NEW_APP_LOCATION); //0x800
}
}
#ORG default
#int_global
void isr(void) {
if( bootLoad == 0)
{
jump_to_isr(LOADER_END+9);
}
else
{
goto_address(RS-485-RX-INT); //RDA ISR in bootloader mode.
}
}
|
Let me know if you need any other information. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 16, 2013 9:53 am |
|
|
Quote: | PIC18F2680
//read sticky byte from an used location.
//If sticky byte is NOT Set, then run bootloader application.
myTemp = read_eeprom(0x600);
|
The 18F2680 data sheet says it has only 1K of data eeprom.
That means the highest data eeprom address is 0x3FF.
It probably ignores the upper bits in your 0x600 address
and is actually reading address 0x200, but it's not the
address that you intend and it may not be unused. |
|
|
wirelessage
Joined: 08 Aug 2012 Posts: 34
|
|
Posted: Tue Apr 16, 2013 10:58 am |
|
|
Thanks for the catch! I got lucky there.
I am using less than half of the eeprom right now... till about 0x120.
So, 0x200 should not be the issue... I just verified it! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Wed Apr 17, 2013 8:33 am |
|
|
Your #int_global is destroying the way this is meant to work....
You can't have a test in the routine, and vector 'round' the jump_to_isr. This jump must be at exact addresses, the very first address in the handler routine. It re-vectors both the low priority handler at 0x08, and the high priority handler at 0x018, in the single instruction. By having the test, the whole routine is being incorrectly located....
You have to switch to doing the re-vectoring in assembler if you want a jump like this. So:
Code: |
#INT_GLOBAL
void isr(void) {
if( bootLoad == 0)
{
#ASM
goto LOADER_END+9
#ENDASM
}
else
{
goto_address(RS-485-RX-INT); //RDA ISR in bootloader mode.
}
#ASM
NOP
goto LOADER_END+0x19
#ENDASM
}
|
If you look at the assembler generated, you will find that the second jump, is then at address 0x18, and jumps to where the high priority handlers should sit.
Best Wishes |
|
|
wirelessage
Joined: 08 Aug 2012 Posts: 34
|
|
Posted: Thu Apr 18, 2013 11:22 am |
|
|
Thanks for the response Ttelmah!
I had not understood the workings of #int_global properly. Seems like I understand it better now.. ideally if I can get rid of the RDA_ISR in bootloader mode it would solve my problem, but since I already have that part working well I am trying to see if I can get it to work with interrupts in both bootloader mode and non-bootloader mode. I have seen some threads related to this, but nothing that is specific to my situation.
I tried some permutation/combinations to get it right so that the high priority falls on (loader_end + 0x9) and low priority on (loader_end + 0x19), but I am unable to get that happen. Any pros who can help me a bit on this to speeden things up??
Here is the .lst file generated with one of those combinations:
Code: |
.................... #int_global
.................... void isr(void) {
....................
.................... if( bootLoad == 0)
*
0008: MOVLB 1
000A: MOVF x00,F
000C: BNZ 0016
.................... {
.................... #asm
.................... GOTO (LOADER_END+9)
000E: MOVLB 0
0010: GOTO 0808
.................... #endasm
.................... }
.................... else
0014: BRA 001C
.................... goto_address(0x3c8); //where RDA-ISR is located in bootloader mode.
0016: MOVLB 0
0018: GOTO 03C8
.................... #asm
.................... NOP
001C: NOP
.................... GOTO (LOADER_END+0x19)
001E: GOTO 0818
.................... #endasm
.................... }
....................
....................
....................
0022: RETFIE 0
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19540
|
|
Posted: Thu Apr 18, 2013 2:54 pm |
|
|
The code as I posted it would work, it the flag 'bootload' is an int1, and in the first page of memory.
Otherwise it is impossible, since the test takes too many instructions.....
Best Wishes |
|
|
|