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 woes / Invalid ORG range

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



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

Bootloader woes / Invalid ORG range
PostPosted: Fri May 12, 2006 9:02 am     Reply with quote

I am getting an “Invalid ORG range” error during compile when I believe I should not be. I am using a PIC18F8722 and compiler 3.249.

For reference, the code I am posting here is loosely based on code posted by “ckielstra” and originates from http://www.ccsinfo.com/forum/viewtopic.php?p=62993.

The application program complies correctly, and puts its interrupts in the correct place. It is the bootloader that has the ORG errors.

Com-Atlanta-Bootloader.h:
Code:
////////////////////////////////////////////////////////////////////////////////
// Some defines for the bootloader:                                           //
//                                                                            //
// Include this file from the bootloader with ATL_BOOTLOADER defined.         //
// Include this file from the application with ATL_BOOTLOADER not defined.    //
////////////////////////////////////////////////////////////////////////////////

#define RESET_VECTOR            0x0000                           // Defined by hardware
#define HIGH_INT_VECTOR         0x0008                           // Defined by hardware
#define NORMAL_INT_VECTOR       0x0018                           // Defined by hardware
#define INTERRUPT_END           0x00a3                         // End of the interrupt area

#define LOADER_START            INTERRUPT_END + 1
#define LOADER_END              0x01FFE // Reserve 8K for the big bootloader
#define LOADER_RESET            RESET_VECTOR
#define LOADER_HIGH_INT         LOADER_START
#define LOADER_NORMAL_INT       LOADER_START + 0x10

#define APPLICATION_START       LOADER_END + 2
#define APPLICATION_RESET       APPLICATION_START + RESET_VECTOR
#define APPLICATION_HIGH_INT    APPLICATION_START + HIGH_INT_VECTOR
#define APPLICATION_NORMAL_INT  APPLICATION_START + NORMAL_INT_VECTOR

#ifdef ATL_BOOTLOADER
  #build(reset=LOADER_RESET, interrupt=LOADER_HIGH_INT) // Move the reset and interrupt vectors
#else
  #build(reset=APPLICATION_RESET, interrupt=APPLICATION_HIGH_INT) // Move the reset and interrupt vectors
  #org 0, LOADER_END {}                                             // Reserve the bootlader memory area
#endif

// Below is a global flag byte, indicating if the bootloader is active or not.  This flag must be present
// in both the bootloader and the application at the same RAM address, hence we place it here with a #locate
// to lock its address for both programs.
unsigned int8   giBootloaderActive;
//#locate         giBootloaderActive=0xF5F   <== this won't work because the ISR can't use bank 15; it can only use bank 0
#locate            giBootloaderActive=0x0FF
// 05/11/06 - Kyle chose 0xFF because it is the highest ram location in bank 0 of the 18F8722.  The ISR
// relocator cannot change ram banks, so the giBootloaderActive flag must exist in bank 0.  The CCS compiler
// uses a variable number of @scratch locations (see sym file) and program variable cannot interfere with the
// scratch locations.  If one #locate's a RAM variable where the scratch needs to be, then the compiler will
// refuse to compile the program.  If we have a bootloader which uses a location that the application requires
// for scratch, then they will become incompatible.  Therefore, Kyle left the maximum amount of room for the
// scratch area to grow, still process the ISRs, and satisfy both programs' memory models.

Test-Bootloader.c:
Code:
#include "18F8722.h"
#fuses HS,NOWDT,NOLVP,PUT,BROWNOUT
#define ATL_BOOTLOADER
#include "Com-Atlanta-Bootloader.h"
#define SYSTEMCLOCK 11059200                           //11.0592 MHz Oscillator

////////////////////////////////////////////////////////////////////////////////
// Relocate the interrupt vectors.  Depending on whether the bootloader or    //
// application is active different interrupt dispatchers are called.          //
////////////////////////////////////////////////////////////////////////////////
#org HIGH_INT_VECTOR, INTERRUPT_END
void isr_relocate(void) {
#asm
   // Address 0x0008 is the hardware High priority interrupt
   TSTFSZ giBootloaderActive       // if bootloader active
   GOTO  LOADER_HIGH_INT         // then jump to bootloader ISR
   GOTO  APPLICATION_HIGH_INT    // else jump to application ISR
   NOP                           // Just filling memory
   NOP
   NOP

   // Address 0x0018 is the hardware Low priority interrupt
   TSTFSZ giBootloaderActive       // if bootloader active
   GOTO   LOADER_NORMAL_INT      // then jump to bootloader ISR
   GOTO   APPLICATION_NORMAL_INT // else jump to application ISR
#endasm
}

#org LOADER_START, LOADER_END default

#int_timer0
void timer0_isr(void) { output_toggle(PIN_J2); }

void main() {
   int16   TMR0Period = SYSTEMCLOCK/4/16/80;
   giBootloaderActive = TRUE;

   set_timer0(TMR0Period);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4);
   enable_interrupts(INT_TIMER0);
   enable_interrupts(GLOBAL);

   // Do your bootloader things here
   while(1) {
      output_toggle(PIN_J0);
   }
   
   // Exit the bootloader and go to the Real Application
   goto_address(APPLICATION_START);
}

Which produces the following compiler output:
Quote:
Executing: "C:\Program files\Picc\CCSC.exe" "Test-Bootloader.c" +FH +DF +LN +T +A +M +Z +Y=9 +P01 +EA I="S:\Devel\Pic-C\Lib;C:\Program Files\PICC\Devices;C:\Program Files\PICC\Drivers"
>>> Warning 203 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 44(1,1): Condition always TRUE
--- Info 300 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): More info: Segment at 00000-00006 (0004 used) Priv
--- Info 300 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): More info: Segment at 00008-000A2 (0000 used) Priv
--- Info 300 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): More info: Segment at 000A4-01FFE (0000 used) Priv
--- Info 300 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): More info: Segment at 02000-0FFFE (0000 used)
--- Info 300 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): More info: Segment at 10000-1FFFE (0000 used)
--- Info 300 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): More info: Attempted to create: 000A4-0013E for ISR
*** Error 126 "S:\Devel\Pic-C\Proj\Experimental\Test-Bootloader\Test-Bootloader.c" Line 53(0,1): Invalid ORG range
1 Errors, 1 Warnings.
Halting build on first failure as requested.
BUILD FAILED: Fri May 12 10:27:48 2006


I tried changing the #build command to put the interrupt at several different locations inside the bootloader area. No matter where I put the interrupts, I got this error. Then I noticed that it shows the segment I am using (A4-1FFE) as “Priv”. Yes, it's private, because it was reserved for this function! Just out of curiousity (desperation), I moved the interrupts outside of the bootloader area and it worked!!! Shocked

I found that when I move the interrupts for the bootloader into the application code's space, that the program compiles and works. For instance like this:
Code:
#build(reset=LOADER_RESET, interrupt=0x2000)           // Move the reset and interrupt vectors

But, obviously, it is unacceptable to put the remapped interrupt vectors outside the area we have allocated for them!

As far as I can tell from all the research I've done, I'm supposed to #ORG the area I want to keep my bootloader in, remap the interrupt vectors, use #BUILD to put in remapped interrupt vectors in the #ORG I have defined, but located after the vector re-mapper. When I do this, it does not work. PLEASE tell me what I'm doing wrong!

-Kyle
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon May 15, 2006 4:48 pm     Reply with quote

It seems like my example code isn't flexible enough.
A quick-and-dirty fix is to remove the next line from Test-Bootloader.c
Code:
#org LOADER_START, LOADER_END default

and restore
Code:
#define INTERRUPT_END           0x00a3                         // End of the interrupt area
to 0x0023


Disadvantage is that you don't have section overflow checking when implementing it like this. I'll look into a better solution but don't have time for the next couple of days.
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

PostPosted: Tue May 23, 2006 8:00 am     Reply with quote

I agree that taking the #org out allows the program to compile. We "get lucky" and the program ends up in the space between LOADER_START and LOADER_END. It seems to me like the #org should work and should be in the code.

-Kyle
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