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 and PCW compiler: memory mapping
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

Bootloader and PCW compiler: memory mapping
PostPosted: Wed Jan 03, 2007 4:04 am     Reply with quote

Hi,

I'm trying to implement a bootloader.

I'm using the PCW compiler for the PIC16LF877A

What applies to this processor? PCM, PCH or none?

Code:
#if defined(__PCM__)             // PIC16 compiler
   #define LOADER_END   0x1FF    // 511
   #define LOADER_SIZE   0x1BF    // 447
#elif defined(__PCH__)
   #define LOADER_END   0x4FF
   #define LOADER_SIZE   0x3FF
#endif


tks


Last edited by Christophe on Mon Jan 08, 2007 2:50 am; edited 2 times in total
Ttelmah
Guest







PostPosted: Wed Jan 03, 2007 4:25 am     Reply with quote

PCM.
There are three 'core' compilers. PCB (12 chips), PCM (16 chips), and PCH (18 chips). The 'PCW' bit, is the windows IDE that goes on 'top' of the compiler.'PCW', is basically PCB, plus PCM, plus the windows
There is a 'slight' complexity, in that there are a few '12' chips, which require the PCM compiler, and the '14' chips which also use this compiler.
IDE. 'PCWH', is PCB, PCM, PCH, plus the IDE. Because you are selecting a '16' chip, the PCM compiler will be being used.
the code is written like this, so it'll work with any of the compilers, automatically scwitcing defintions, if you change processors.

Best Wishes
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Wed Jan 03, 2007 6:22 am     Reply with quote

Tks for your input. I'm trying to understand the CCS example. Can you guys help me?

bootloader.h:

Code:
//#if defined(__PCM__)             // PIC16 compiler
   #define LOADER_END   0x1FF    // 511
   #define LOADER_SIZE   0x1BF    // 447
//#elif defined(__PCH__)
//   #define LOADER_END   0x4FF
//   #define LOADER_SIZE   0x3FF
//#endif

#ifndef _bootloader              // Als bootloader ergens gedefinieerd is
                                 // reset en interrupt vectoren verplaatsen, anders worden ze overschreven
//#if defined(__PCM__)
   #build(reset=LOADER_END+1, interrupt=LOADER_END+5)
//#elif defined(__PCH__)
//   #build(reset=LOADER_END+2, interrupt=LOADER_END+8)
//#endif

#org 0, LOADER_END {}   // tussen geheugen 0 en LOADER_END => vrij anders wordt de bootloader overschreven

#endif


bootloader.c :

Code:
#include <16F877A.h>
#fuses XT, PUT, NOWDT, NOPROTECT, NOLVP, NOCPD, NOWRT, NOBROWNOUT, NODEBUG
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)

#define BUZZ PIN_C3
#define RESET_IN PIN_E2
#define _bootloader

#include <bootloader.h>
#include <loader.c>

//#if defined(__PCM__)                         // PCM : 14 bit compiler
 #org LOADER_END+1,LOADER_END+10             // Die functie start op loader_end + 1 tot loader_end + 10
//#elif defined(__PCH__)                       // PCH : PIC18 compiler
// #org LOADER_END+2,LOADER_END+20             // Die functie start op loader_end + 2 tot loader_end + 20
//#endif

void application(void) {
  while(TRUE);
}

//#if defined(__PCH__)                         // Als PIC18 comiler
//#org 0x40,0x7F
//#else                                        // 14 bit compiler
//#org 0x20,0x3F                               // De main staat tussen adres 0x20 en 0x3F
//#endif

void main(void) {
   if(!input(PIN_B5))
   {
      load_program();
   }

   application();
}
/*
void main ()
{

int8 i;

   delay_ms (1000);
   while (kbhit())                           // Zolang kbhit () FALSE is, lees een karakter van de seriële poort
   {                                         // kbhit () = TRUE : character has been received and is waiting in the hardware buffer for getc() to read
      getc();
   }
   
   //for ( i = 0 ; i < 3 ; i++ )               // Loop until 3 X 170 is received
  // {
      do
      {

      } while (getc() != 170);
//   }
   
//   putc ('K');             // Let the user know it is ready to accept a download

   // Load the program
   load_program();

   application();
}
*/
#ORG default   // Vanaf

//#if defined(__PCM__)
   #int_global
   void isr(void) {
     #asm
       goto LOADER_END+5
     #endasm
   }
//#elif defined(__PCH__)
//   #int_global
//   void isr(void) {
//     #asm
//       goto LOADER_END+7
//       nop
//       nop
//       nop
//       nop
//       nop
//       nop
//       goto LOADER_END+0x17
//     #endasm
//   }
//#endif


1. If pin B0 is low, this program will write a new program to the flash. However, in this program, if pin B0 is high, function application () is called. Function application is between LOADER_END + 1 and LOADER_END + 10. And function application () actually does nothing!

How can I change this that the real program is started? Isn't the real program located between adress LOADER_END( + 5) and 1FFFh ?

2. The triggerpoint is B0 low. I want to change the triggerpoint to: RECEIVE 2 times 170dec in 5 seconds. How can I change that? What is extra needed for this?

3. What does the #int_global do?

4. The SIOW program sends the hex file. Is it hard to write your own PC tool that does that? What's the algorythm?
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jan 03, 2007 9:02 am     Reply with quote

Quote:
How can I change this that the real program is started? Isn't the real program located between adress LOADER_END( + 5) and 1FFFh ?
The code as it is is correct, you don't have to change it. The real application starts at LOADER_END+1, and at LOADER_END+5 is your interrupt handler as defined in
Code:
   #build(reset=LOADER_END+1, interrupt=LOADER_END+5)


The application you see here is a dummy, it is there for two reasons:
1) To make the compiler happy. There should always be a main() or the compiler will refuse to compile the bootloader code.
2) The bootloader will be the first program to be flashed into a new chip. Yes, this application code is at the same memory location where your real application is going to be loaded, but who cares overwriting a dummy application. You could modify this dummy application to flash a LED or something so you can check the bootloader was programmed correctly.

Quote:
2. The triggerpoint is B0 low. I want to change the triggerpoint to: RECEIVE 2 times 170dec in 5 seconds. How can I change that? What is extra needed for this?
Have a look at the chapter 'How do I get getc() to timeout after a specified time? ' in the PICC manual. A small modification to that example should do the trick.

Quote:
3. What does the #int_global do?
When an interrupt is generated the processor always jumps to the code at hardware address 0x0004 for a PIC16 (0x0008 for a PIC18). What you see here is a trick to pass the interrupt call on to the interrupt handler of your application.

The following code does the same and is easier to understand:
Code:
#org 0x0005, 0x0009
void remap_interrupt()
{
  goto_address( LOADER_END+5 );
}


Quote:
4. The SIOW program sends the hex file. Is it hard to write your own PC tool that does that? What's the algorythm?
SIOW is just a standard terminal emulator. Any other program that is capable of sending a specified text file over RS232 will do. Examples are: Hyperterm, Procomm, Terminal, etc.

To call it an algorithm is too much praise, the only thing SIOW does is taking the *.hex file (just plain ASCII text) and transmitting it to the PIC over RS-232. In order to prevent buffer overflow the bootloader in the PIC will send standard XON/XOFF flow control characters.
Writing your own program should be a piece of cake.
Understanding the contents of the *.hex file is not really required but could help. Search Google for 'Intel hex format'.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 4:26 am     Reply with quote

Hi, thanks for the reply. I managed to get a little further. But It doesn't seem to download? This is my code:

bootloader.h:

Code:
//#if defined(__PCM__)             // PIC16 compiler
   #define LOADER_END   0x1FF    // 511
   #define LOADER_SIZE   0x1BF    // 447
//#elif defined(__PCH__)
//   #define LOADER_END   0x4FF
//   #define LOADER_SIZE   0x3FF
//#endif

#ifndef _bootloader              // Als bootloader ergens gedefinieerd is
                                 // reset en interrupt vectoren verplaatsen, anders worden ze overschreven
//#if defined(__PCM__)
   #build(reset=LOADER_END+1, interrupt=LOADER_END+5)
//#elif defined(__PCH__)
//   #build(reset=LOADER_END+2, interrupt=LOADER_END+8)
//#endif

#org 0, LOADER_END {}   // tussen geheugen 0 en LOADER_END => vrij anders wordt de bootloader overschreven

#endif


bootloader.c:

Code:
#include <16F877A.h>
#fuses XT, PUT, NOWDT, NOPROTECT, NOLVP, NOCPD, NOWRT, NOBROWNOUT, NODEBUG
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)

#define _bootloader

#include <bootloader.h>
#include <loader.c>
                   
#org LOADER_END+1,LOADER_END+10              // Die functie start op loader_end + 1 tot loader_end + 10

void application (void)                      // Dummy functie, eigenlijk staat hier de échte main
{                       
   putc ('A');
   while(TRUE);
}
                                   
#org 0x20,0x3F                                // De main staat tussen adres 0x20 en 0x3F

void main ()
{
long timeout = 0;

   while ( !kbhit() && (++timeout < 50000) ) // 5 seconds
      delay_us (100);

   if ( kbhit() )
   {
      if ( getc() == 170 )
      {
         timeout = 0;
         while ( !kbhit() && (++timeout < 50000)) // 5 seconds
            delay_us (100);

         if ( kbhit () )
            if ( getc() == 170 )
            {
               putc ('B');
               load_program();
            }
      }
   }
      application();             // Jump to real application
}

#ORG default   // Vanaf

   #int_global
   void isr(void)
   {
     #asm
       goto LOADER_END+5
     #endasm
   }

test.c:

Code:
#include <16F877A.h>
#device adc=10 *=16
#fuses XT, PUT, NOWDT, NOPROTECT, NOLVP, NOCPD, NOWRT, NOBROWNOUT, NODEBUG
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)

#define SIZE 25
#define LEESREGEL 0

#include "tones.c"
#include <bootloader.h>

const struct note
{
   long tone;
   long length;
} happy_bday[SIZE] = {
C_note[0],350, C_note[0],100, D_note[0],500, C_note[0],500, F_note[0],500, E_note[0],900,
C_note[0],350, C_note[0],100, D_note[0],500, C_note[0],500, G_note[0],500, F_note[0],900,
C_note[0],350, C_note[0],100, C_note[1],500, A_note[0],500, F_note[0],500, E_note[0],500, D_note[0],900,
Bb_note[0],350, Bb_note[0],100, A_note[0],500, F_note[0],500, G_note[0],500, F_note[0],1200};

void MAIN ()
{
int i;
//**************************** SIGNAAL BIJ RESET *****************************//
   if ( !LEESREGEL )                   // Als geen leesregel
      output_low (PIN_C2);             // - van de buzzer aan massa
   setup_adc_ports (NO_ANALOGS);       // ADC UIT
   setup_adc (ADC_OFF);
   setup_timer_1 (T1_DISABLED);        // T1 uit
   setup_timer_2 (T2_DISABLED,0,1);    // T2 uit
   setup_psp (PSP_DISABLED);           // PSP UIT
   setup_comparator (NC_NC_NC_NC);     // COMPARATOR UIT
   setup_vref (FALSE);
   enable_interrupts (INT_RDA);        // RDA interrupt enable
   enable_interrupts (GLOBAL);         // GLOBAL interrupt enable

   while (TRUE)
   {
      for(i=0; i<SIZE; ++i)
      {
         generate_tone(happy_bday[i].tone,happy_bday[i].length);
         delay_ms(75);
      }

      putc ('K');
      delay_ms (500);
   } //while (TRUE)
} //main


1. I get a compiler error: OUT of ROM, a segment is too large. Probably the main segment is too large. If I want to change the #org values, I get an invalid org range error. Anyone? compiler 3.226

2. About the entering download mode using timeouts; is my code elegant or can it be written shorter?

tks!


Last edited by Christophe on Thu Jan 04, 2007 10:02 am; edited 1 time in total
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 10:00 am     Reply with quote

That invalid org range is seriously breakin' my balls here. I really hope someone of the pros can solve this one..
BOB_SANTANA



Joined: 16 Oct 2006
Posts: 110
Location: HOVE, EAST SUSSEX

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 3:04 pm     Reply with quote

Try running the example programmes as they are and only change the application program example leave all the include file as they are this your bootloader.h

Code:

//#if defined(__PCM__)             // PIC16 compiler
   #define LOADER_END   0x1FF    // 511
   #define LOADER_SIZE   0x1BF    // 447
//#elif defined(__PCH__)
//   #define LOADER_END   0x4FF
//   #define LOADER_SIZE   0x3FF
//#endif

#ifndef _bootloader              // Als bootloader ergens gedefinieerd is
                                 // reset en interrupt vectoren verplaatsen, anders worden ze overschreven
//#if defined(__PCM__)
   #build(reset=LOADER_END+1, interrupt=LOADER_END+5)
//#elif defined(__PCH__)
//   #build(reset=LOADER_END+2, interrupt=LOADER_END+8)
//#endif

#org 0, LOADER_END {}   // tussen geheugen 0 en LOADER_END => vrij anders wordt de bootloader overschreven

#endif



This is the original

Code:


#if defined(__PCM__)
   #define LOADER_END   0x1FF
   #define LOADER_SIZE   0x1BF
#elif defined(__PCH__)
   #define LOADER_END   0x4FF
   #define LOADER_SIZE   0x3FF
#endif

#ifndef _bootloader

#if defined(__PCM__)
   #build(reset=LOADER_END+1, interrupt=LOADER_END+5)
#elif defined(__PCH__)
   #build(reset=LOADER_END+1, interrupt=LOADER_END+9)
#endif

#org 0, LOADER_END {}

#endif

_________________
BOB_Santana Smile
BOB_SANTANA



Joined: 16 Oct 2006
Posts: 110
Location: HOVE, EAST SUSSEX

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 3:16 pm     Reply with quote

I have just complied your code without any errors and i didn't change anything just see below

Code:

//#include <16F877A.h>
//#device adc=10 *=16
//#fuses XT, PUT, NOWDT, NOPROTECT, NOLVP, NOCPD, NOWRT, NOBROWNOUT, NODEBUG
//#use delay(clock=4000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)


#if defined(__PCM__)
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#elif defined(__PCH__)
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#define SIZE 25
#define LEESREGEL 0

#include "tones.c"
#include <bootloader.h>

const struct note
{
   long tone;
   long length;
} happy_bday[SIZE] = {
C_note[0],350, C_note[0],100, D_note[0],500, C_note[0],500, F_note[0],500, E_note[0],900,
C_note[0],350, C_note[0],100, D_note[0],500, C_note[0],500, G_note[0],500, F_note[0],900,
C_note[0],350, C_note[0],100, C_note[1],500, A_note[0],500, F_note[0],500, E_note[0],500, D_note[0],900,
Bb_note[0],350, Bb_note[0],100, A_note[0],500, F_note[0],500, G_note[0],500, F_note[0],1200};

void MAIN ()
{
int i;
//**************************** SIGNAAL BIJ RESET *****************************//
   if ( !LEESREGEL )                   // Als geen leesregel
      output_low (PIN_C2);             // - van de buzzer aan massa
   setup_adc_ports (NO_ANALOGS);       // ADC UIT
   setup_adc (ADC_OFF);
   setup_timer_1 (T1_DISABLED);        // T1 uit
   setup_timer_2 (T2_DISABLED,0,1);    // T2 uit
   setup_psp (PSP_DISABLED);           // PSP UIT
   setup_comparator (NC_NC_NC_NC);     // COMPARATOR UIT
   setup_vref (FALSE);
   enable_interrupts (INT_RDA);        // RDA interrupt enable
   enable_interrupts (GLOBAL);         // GLOBAL interrupt enable

   while (TRUE)
   {
      for(i=0; i<SIZE; ++i)
      {
         generate_tone(happy_bday[i].tone,happy_bday[i].length);
         delay_ms(75);
      }

      putc ('K');
      delay_ms (500);
   } //while (TRUE)
} //main

_________________
BOB_Santana Smile
BOB_SANTANA



Joined: 16 Oct 2006
Posts: 110
Location: HOVE, EAST SUSSEX

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 3:28 pm     Reply with quote

i used your bootloader.c and Test.c exactly as you have it and was able to complier the program
what version are you using ?
_________________
BOB_Santana Smile
ckielstra



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

View user's profile Send private message

PostPosted: Thu Jan 04, 2007 5:38 pm     Reply with quote

Christophe wrote:
That invalid org range is seriously breakin' my balls here. I really hope someone of the pros can solve this one..
It is possible that the use of TAB characters in the line containing the #org statement is causing your "Invalid ORG range" error message.
This is a known error in the v3.249 CCS preprocessor, check also the last few messages in thread http://www.ccsinfo.com/forum/viewtopic.php?t=20971

This compiler error would explain why a copy/paste of the code from the forum (no TABs) is working while your original but identical code (with TABs) fails.
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Fri Jan 05, 2007 2:02 am     Reply with quote

Tks for the support. Still I don't manage to compile. My compiler version is 3.226 and I removed all tabs and comments after #org. Any help? Can somebody try to compile this?

bootloader.h:

Code:
#define LOADER_END   0x1FF
#define LOADER_SIZE   0x1BF

#ifndef _bootloader
#build ( reset = LOADER_END+1 , interrupt = LOADER_END+5 )
#org 0, LOADER_END {}
#endif


bootloader.c

Code:
#include <16F877A.h>
#fuses XT, PUT, NOWDT, NOPROTECT, NOLVP, NOCPD, NOWRT, NOBROWNOUT, NODEBUG
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, ERRORS)

#define _bootloader

#include "bootloader.h"
#include "loader.c"

#org LOADER_END+1,LOADER_END+10
void application (void)                      // Dummy functie, eigenlijk staat hier de échte main
{
   putc ('A');
   while(TRUE);
}

#org 0x20, 0x80
void main (){

long timeout = 0;

   while ( !kbhit() && (++timeout < 50000) ) // 5 seconds
      delay_us (100);

   if ( kbhit() )
   {
      if ( getc() == 170 )
      {
         timeout = 0;
         while ( !kbhit() && (++timeout < 50000)) // 5 seconds
            delay_us (100);

         if ( kbhit () )
            if ( getc() == 170 )
            {
               putc ('B');
               load_program();
            }
      }
   }
      application();             // Jump to real application
}

#ORG default
   #int_global
   void isr(void)
   {
     #asm
       goto LOADER_END+5
     #endasm
   }
Guest








PostPosted: Fri Jan 05, 2007 3:41 am     Reply with quote

What version of Mplab are you using?
Try re-installing CCS and the CCS software that calls Mplab
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Fri Jan 05, 2007 3:43 am     Reply with quote

Anonymous wrote:
What version of Mplab are you using?
Try re-installing CCS and the CCS software that calls Mplab


I'm using CCS pcwh v3.226. I don't think reinstalling would help honestly.
Guest








PostPosted: Fri Jan 05, 2007 4:54 am     Reply with quote

Suit Youeself

BTW the code complies here
Christophe



Joined: 10 May 2005
Posts: 323
Location: Belgium

View user's profile Send private message

PostPosted: Fri Jan 05, 2007 4:55 am     Reply with quote

Anonymous wrote:
Suit Youeself

BTW the code complies here


thanks, version?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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