Friday, 05 December 2008
 
  Home arrow PIC arrow General arrow Modifying bootloader-compatible C18 code for MPLAB SIM simulator  
Main Menu
Home
Car PC
PIC
Electronics
Brewing
Links
Contact Me
FAQs
Forums
eXtplorer
PayPal Donation

Enter Amount:

Modifying bootloader-compatible C18 code for MPLAB SIM simulator PDF Print E-mail
Written by Evan   
Monday, 23 October 2006

This is a quick guide on what it takes to get C18 code that is intended for use with a bootloader to be compatible with the MPLAB SIM simulator.  In this case, I am modifying code written for the 18F4550 that is meant for use with the Microchip standard USB bootloader.  There should also be enough information here to get you started if you need modify code for other purposes - such as making normal code work with a bootloader, or with in-circuit debugging.

For bootloader compatibility, the code is shifted a bit; instead of starting at 0x0000, the reset and interrupt vectors are shifted up by 0x0800, to 0x0800 (reset), 0x0808 (high priority interrupt), and 0x0818 (low priority interrupt).  The linker file is responsible for reserving the first 0x0800 bytes for the bootloader code, with a couple lines like this:

CODEPAGE   NAME=boot       START=0x0            END=0x7FF          PROTECTED
CODEPAGE   NAME=vectors    START=0x800          END=0x0x829 


In addition, the three vectors are remapped in the code like so:

extern void _startup (void);        // See c018i.c in your C18 compiler dir
#pragma code _RESET_INTERRUPT_VECTOR = 0x000800
void _reset (void)
{
    _asm goto _startup _endasm
}
#pragma code

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000808
void _high_ISR (void)
{
    user_interrupt();
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000818
void _low_ISR (void)
{
    ;
}

 So the problem here is that the code that is compiled this way is only meant to exist from 0x0800 up, with the bootloader code that is already in place taking up the first part.  When you are trying to run the simulator, that bootloader code is not in place and things don't work properly; in my case, this resulted in it giving repeated stack overflows and being completely unusable.  The problem is that the file c018i.o mentioned in the linker file has a reference to address 0x000000 for the reset vector.  (You can view the C file, it's somewhere in the MCC18 directory)  The simple solution is to just use some preprocessor directives to determine whether the reset vector is actually placed at 0x0000 or 0x0800.  The code is as follows:

#define SIM
#ifndef SIM
    #pragma code _RESET_INTERRUPT_VECTOR = 0x000800
#endif
void _reset (void)
{
    _asm goto _startup _endasm

 Quite simply, if you have the #define SIM at the top, it does not remap the reset vector to 0x0800, and instead it goes to its default location of 0x0000, and MPLAB simulation works fine; and if you just comment out the #define SIM, it goes to 0x0800 for use with the bootloader.  The interrupt vectors don't need to be remapped, since they're not pointed to in any unexpected files, so MPLAB takes care of them just fine.

As a sidenote, you also might want to put in some #ifdef SIM statements around some of the calls to USB-specific functions, such as USBTasks() and mInitializeUSBDriver(), since none of the USB stuff is going to work in the simulation anyway, to clean up the simulation so you're only looking at your user code.

 

Last Updated ( Monday, 23 October 2006 )
 
< Prev   Next >
Partner Site
Visit my friends over at Dream-Technology, producing radio controlled and switch adapted toys for children with physical disabilities.
Creative Commons License
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.5 License.
For usage outside the terms of this license, contact me by email to discuss.

© 2008 eegeek.net
Joomla! is Free Software released under the GNU/GPL License.

Get The Best Free Joomla Templates at www.joomla-templates.com