View previous topic :: View next topic |
Author |
Message |
Nepersky
Joined: 10 May 2011 Posts: 15
|
Strange behavior when combining a bootloader and application |
Posted: Fri Apr 27, 2012 3:09 pm |
|
|
Hello all,
I am facing a very strange problem when trying to incorporate a USB bootloader into my PIC based firmware and am hoping to find some ideas on how to solve it from more experienced programmers.
I am using a version 4.125 CCS compiler and a PIC18F47J53.
I have a firmware for the PIC which does what it is supposed to do and I have a USB bootloader which also works. Combining the two and programming the PIC with both also works (in a way as you will see) but a strange thing happens. I have a variable (SkipBTL) which is located at a specific address (I use #locate SkipBTL = 0xfb in bootloader and in the firmware/application). At the beginning of the bootloader this variable is checked and if it is set to 1 the whole bootloader is skipped.
All good so far.
The problem appears if I set this variable to 1 at the beginning of my application (so after exiting the bootloader). If I do this, the bootloader can no longer be entered after a power-on reset- It can not even be entered by erasing and reprogramming the PIC. The problem is, that right after programming, when running the whole program (bootloader+application) the SkipBTL variable is somehow already set to 1 and the bootloader is therefore skipped (I checked this by lighting an LED right at the beginning of the bootloader if SkipBTL is set to one).
If I comment out the line in my application where I set the SkipBTL variable to 1, everything works as expected.
And now for the strangest thing, if I add a compiler's delay_ms() function right before setting SkipBTL to 1, everything works again. This leads me to believe that compiler is "messing something up".
As if things weren't strange enough, compiling the firmware without the SkipBTL=1; line and programming the PIC makes everything work. Then compiling it with the line in place and reprogramming the PIC makes everything work the first time the PIC is programmed but after all other reprogrammings the bootloader is skipped after the programming is finished. It is the same the other way around: compiling with the SkipBTL=1; results in always skipping the bootloader. Then comipling without the line and programming the PIC results in skipping the bootloader after the first programming and makes everything work OK after all other reprogrammings. It is as if the memory of SkipBTL's value reaches one programming back. Weird. Doing a FLASH erase of course did not help. Even removing power and thus making sure all RAM is cleared did not help.
I do use the #INT_GLOBAL directive and have my own interrupt handler. It says in the CCS manual that this directive should be used with care so I'm thinking this may be the root of the problem. But I skimmed down the interrupt handler as much as I could and the problem was still there. Here is the interrupt handler:
Code: | #INT_GLOBAL
void GLOBAL_ISR(void)
{
#ASM
MOVWF W_save
SWAPF STATUS, w
MOVWF STATUS_save
MOVF BSR, w
MOVWF BSR_save
#ENDASM
if(bit_test(PIR1,2)){interrupts_pending|=0b10000001;bit_clear(PIR1,2);}
if(bit_test(PIR4,0)){interrupts_pending|=0b10000010;bit_clear(PIR4,0)}
if(bit_test(INTCON,2)){interrupts_pending|=0b10000100;bit_clear(INTCON,2)}
if(bit_test(PIR3,3)){interrupts_pending|=0b10001000;bit_clear(PIR3,3)}
#ASM
MOVF BSR_save, w
MOVWF BSR
SWAPF STATUS_save, w
MOVWF status
SWAPF W_save, f
SWAPF W_save, w
#ENDASM
} |
Tomorrow I plan on trying to replace the #INT_GLOBAL with individual interrupts such as #INT_TIMER0,... I have been avoiding it as I need 2 of the four interrupts I use to be fast.
Does anyone have any ideas what could be causing such a strange problem that adding one delay in a non time critical part of the code would affect a variable being set or not?
Thanks in advance for all the help!
Cheers! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 27, 2012 7:06 pm |
|
|
Show us the SkipBTL variable declaration and the code that uses it. |
|
|
Nepersky
Joined: 10 May 2011 Posts: 15
|
|
Posted: Sat Apr 28, 2012 4:47 am |
|
|
The following declaration is located both in the bootloader and in the application:
Code: | int8 SkipBTL; #locate Skip BTL = 0xfb |
The whole code is too extensive to post but usage of the variable is nothing special. it is a simple:
in the application and:
Code: | if((f_SkipEntireBootloader==1)
{
restart_wdt();
SkipBTL=0;
#asm
GOTO APP_START_ADDRESS
#endasm
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Wed May 02, 2012 4:15 am |
|
|
Nepersky wrote: | The following declaration is located both in the bootloader and in the application:
Code: | int8 SkipBTL; #locate Skip BTL = 0xfb |
The whole code is too extensive to post but usage of the variable is nothing special. it is a simple:
in the application and:
Code: | if((f_SkipEntireBootloader==1)
{
restart_wdt();
SkipBTL=0;
#asm
GOTO APP_START_ADDRESS
#endasm
} |
|
Er. You do realise the space between 'Skip', and 'BTL' will stop the #locate from working.....
Best Wishes |
|
|
Nepersky
Joined: 10 May 2011 Posts: 15
|
|
Posted: Sun May 13, 2012 9:42 am |
|
|
Sorry about that. I have no idea how the space got in there. There is of course no space in my code. But the problem is still there. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sun May 13, 2012 1:04 pm |
|
|
I'm using similar constructs (persistent flags that are kept during reboot) in many applications. They generally work. If not, it's mostly a simple thing, usually lack of understanding what the code actually does in contrast to what it's meant to do.
You didn't show the full flag handling code, thus I won't guess what's going on in this case. If you don't understand what happens, trace the code at the assembly level, e.g. using MPLAB. In many cases, MPLAB SIM will already show the problem. |
|
|
|