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 for PIC16F886

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



Joined: 23 Feb 2011
Posts: 2

View user's profile Send private message

Bootloader for PIC16F886
PostPosted: Wed Feb 23, 2011 7:14 am     Reply with quote

I was wondering is anyone has any clue as to why the program below for a bootloader wouldnt compile on CCS compiler. The error I get is "The segment or program is too large real_load_program". The program is just a modification of the example program from the CCS examples. Please help me.
Code:

#include <16F886.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#define _bootloader


////                       BOOTLOADER.H                                ////

#define LOADER_END   0x2FF
#define LOADER_SIZE   0x1BF

////                         loader.c                                  ////

#define LOADER_ADDR LOADER_END-LOADER_SIZE
#define BUFFER_LEN_LOD 64

int  buffidx;
char buffer[BUFFER_LEN_LOD];

#define ACKLOD 0x06
#define XON    0x11
#define XOFF   0x13

#SEPARATE
unsigned int atoi_b16(char *s);

#ORG LOADER_ADDR+10, LOADER_END auto=0 default
void real_load_program (void)
{
   int1  do_ACKLOD, done=FALSE;
   int8  checksum, line_type;
   int16 l_addr,h_addr=0;
   int32 addr;
   #if getenv("FLASH_ERASE_SIZE")>2
      int32 next_addr;
   #endif
   int8  dataidx, i, count;
   int8  data[32];

   while (!done)  // Loop until the entire program is downloaded
   {
      buffidx = 0;  // Read into the buffer until 0x0D ('\r') is received or the buffer is full
      do {
         buffer[buffidx] = getc();
      } while ( (buffer[buffidx++] != 0x0D) && (buffidx <= BUFFER_LEN_LOD) );

      putchar (XOFF);  // Suspend sender

      if(input(PIN_B2)) output_low(PIN_B2); else output_high(PIN_B2);

      do_ACKLOD = TRUE;

      // Only process data blocks that start with ':'
      if (buffer[0] == ':') {
         count = atoi_b16 (&buffer[1]);  // Get the number of bytes from the buffer

         // Get the lower 16 bits of address
         l_addr = make16(atoi_b16(&buffer[3]),atoi_b16(&buffer[5]));

         line_type = atoi_b16 (&buffer[7]);

         addr = make32(h_addr,l_addr);

         addr /= 2;

         // If the line type is 1, then data is done being sent
         if (line_type == 1)
         {
            done = TRUE;
         }
         else
         if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x2000)
         {
            checksum = 0;  // Sum the bytes to find the check sum value
            for (i=1; i<(buffidx-3); i+=2)
               checksum += atoi_b16 (&buffer[i]);
            checksum = 0xFF - checksum + 1;

            if (checksum != atoi_b16 (&buffer[buffidx-3]))
               do_ACKLOD = FALSE;
            else   {
               if (line_type == 0) {
                  // Loops through all of the data and stores it in data
                  // The last 2 bytes are the check sum, hence buffidx-3
                  for (i = 9,dataidx=0; i < buffidx-3; i += 2)
                     data[dataidx++]=atoi_b16(&buffer[i]);

                  #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
                 
                     if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")-1)!=0))
                        erase_program_eeprom(addr);
                       
                     next_addr = addr + 1;
                  #endif
                  write_program_memory(addr, data, count);
               }
               else if (line_type == 4)
                  h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
            }
         }
      }

      if (do_ACKLOD)
         putchar (ACKLOD);

      putchar(XON);
   }

   putchar (ACKLOD);
   putchar(XON);
}

unsigned int atoi_b16(char *s) {  // Convert two hex characters to a int8
   unsigned int result = 0;
   int i;

   for (i=0; i<2; i++,s++)  {
      if (*s >= 'A')
         result = 16*result + (*s) - 'A' + 10;
      else
         result = 16*result + (*s) - '0';
   }

   return(result);
}

#ORG default


#ORG LOADER_ADDR, LOADER_ADDR+9
void load_program(void)
{
   real_load_program();
}

////////////////////

#org LOADER_END+1, LOADER_END+10
void application(void)
{
  while(TRUE);
}

#org 0x20,0x3F
void main(void)
{
   if(!input(PIN_B5))
   {
      load_program();
   }

   application();
}

#ORG default

#int_global
void isr(void) {
   jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Feb 23, 2011 5:05 pm     Reply with quote

I started to analyze your code but then I stopped. Why can't you leave
the code in the same basic format that CCS uses in Ex_bootloader.c ?
In other words, you shoulde have #include files, and a small main program.

The way you have it posted, I have to pull up each include file and set up
two windows in an editor, side by side, and try to figure out what you have
changed.

If you follow the CCS format, it would be easier for us (me) to debug.
kameshward



Joined: 23 Feb 2011
Posts: 2

View user's profile Send private message

PostPosted: Thu Feb 24, 2011 7:53 am     Reply with quote

Thanks for your reply.

You will have the compilation error even if you have the original format of the ex_bootloader.c source code and change the device ID.

It seems that the compilation of the PIC16F886 is different from the PIC16F877 though the specification might look the same. Somehow, the code is bigger in case of 16F886 as compared with 16F877.

Therefore all i had to do was to change the LOADER_END and LOADER_SIZE values as well as the #ORG addresses in front of the void main(void) and all is well. It compiles.

I got the code to compile with the help of the CCS compiler support staff.

But now I have another problem. When I use this bootloader to upload an application, it doesnt store the content in the locations specified. I am still trying to debug it.

Thanks once again.

PCM programmer wrote:
I started to analyze your code but then I stopped. Why can't you leave
the code in the same basic format that CCS uses in Ex_bootloader.c ?
In other words, you shoulde have #include files, and a small main program.

The way you have it posted, I have to pull up each include file and set up
two windows in an editor, side by side, and try to figure out what you have
changed.

If you follow the CCS format, it would be easier for us (me) to debug.
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