CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Bootloader changes application behavior

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Keith
Guest







Bootloader changes application behavior
PostPosted: Sat Dec 02, 2006 4:34 pm     Reply with quote

My application (written using PCH v 4.014) for PIC 18F4580 behaves differently when run with my bootloader than without. Can someone tell me how the bootloader is changing the execution context of the application?

<< NOTE: As best I can tell, the application behaves as expected when INT_RDA and INT_TBE are not used, but when they are used, it behaves anomalously. When I run it without the bootloader, it always behaves as expected. In both tests, I'm comparing the exact same application hex file, once loaded via a programmer, and once loaded via the bootloader. The bootloader and application have the same FUSES. >>

My bootloader is checking the value in a byte of EEPROM to decide whether or not to execute the application. Here are the instructions:

Code:

    ORG    0000
    GOTO  decision
   ...
decision:
    MOVFF  INTCON,@@C0
    BCF    INTCON.GIE/GIEH
    CLRF   EEADR
    BCF    EECON1.CFGS
    BCF    EECON1.EEPGD
    BSF    EECON1.RD
    MOVF   EEDATA,W
    BTFSC  @@xC0.7
    BSF    INTCON.GIE/GIEH
    SUBLW  11
    BNZ     skip
    GOTO   1000    ; Application Main
skip:
    GOTO   0872    ; Bootloader Main


The bootloader does not use interrupts, but the application does. The bootloader remaps the interrupt vector to 0x1008, which is what the application expects. [i.e. #build(reset=0x1000, interrupt=0x1008) ]

Any suggestions would be appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Dec 02, 2006 5:13 pm     Reply with quote

I did a bootloader for a project several years ago. I haven't done one
since then, so I'm not completely up-to-date on it. But I remember
taking care to make sure that the bootloader code didn't use any CCS
library functions. That's because you can't guarantee that the library
code will be in the same place when you install a new user program.

I didn't use any code that comes from explicitly invoked libraries such
as #use rs232(), and I also didn't use any code from implicit libraries,
such as integer math operations. This means library routines such as
@MUL88, etc. You can see that code in the .LST file if you comment
out the #nolist statement in the PIC's .H file.
So I wrote my own putc() and getc() routines, and other ones as well,
to reside in the bootloader area.

To solve your problem, I would look for any functions or RAM that are
used in common between the user code and the bootloader.
Somewhere, there will be a conflict. It might be in library functions,
or perhaps user functions, or maybe scratch variables in RAM, or user
RAM. I don't know the structure of your program, but I would guess
that somehow, one part of your program is "stepping on" another part
(in terms of RAM) or that some function is no longer at the expected
address.
Keith
Guest







PostPosted: Sat Dec 02, 2006 9:53 pm     Reply with quote

Thanks for your response. I should have noted that the bootloader program resides between 0x0000 and 0x0FFF, and that the application program resides between 0x1000 abd 0x7FFF -- so the only code they share is the few instructions I quoted.

CCS library functions are duplicated -- the bootloader has a "putc" and the application has a "putc", but they do not reside at the same place, and only one is ever used after a reset. It's like a dual-boot PC -- you can have Linux and Windows on the same PC. They both use RAM, but they don't conflict with each other because you have to reset the computer to change to the other.

--- Therefore, the only possible interaction is that the instructions I listed change the cpu's execution state before starting the application program. Or somehow the configuration registers are different (but I think they should be the same because I'm using the same FUSES).

I think the solution must be to understand what assumptions the C-compiler makes about the CPU's initial execution state.
Ttelmah
Guest







PostPosted: Sun Dec 03, 2006 4:47 am     Reply with quote

You need to add an interrupt relocation 'jump' to the bootloader.
In the _bootloader_, you need:
Code:

#int_global
void relocate(void) {
   jump_to_isr(0x1008);
}

The 'build' statement, tells the compiler to write the ISR handler at the specified address. However you also need code to 'reserve' the hardware location from being overwritten by the bootloader, and to physically 'jump' to the new ISR handler. The declaration above does this. Unless you do this, part of the bootloader code can sit over the hardware interrupt jump location, giving totally unpredictable results, and you will never actually call the required routines...

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group