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 support@ccsinfo.com

bootloader problem

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



Joined: 07 Mar 2017
Posts: 10

View user's profile Send private message

bootloader problem
PostPosted: Thu May 25, 2017 2:16 am     Reply with quote

Hi
I'm playing with ccs bootloader example and i can run it with pic16f887 in proteus but the example doesn't work with pic18f45k22.
I use SIOW.exe to load ex_bootload.hex into mcu and in both mcus i can load the file but after loading,the ex_bootload works fine in pic16f887 but in pic18f45k22, proteus messages "stack overflow is forcing device reset" and the message refers to isr routine.
I searched the forums but i can't find a proper answer.

ccs: 5.049
Thanks in advance

ex_bootloader.c
Code:

#if defined(__PCM__)
#include <16F887.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define PUSH_BUTTON PIN_A0

#elif defined(__PCH__)
#include <18F45K22.h>
#fuses NOWDT
#use delay(crystal=16MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,errors)
#define PUSH_BUTTON PIN_A0
#endif


#define _bootloader
//#define BOOTLOADER_MODE2X

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

#if defined(__PCM__)
 #org LOADER_END+1,LOADER_END+2
#elif defined(__PCH__)
 #org LOADER_END+2,LOADER_END+4
#endif
void application(void) {
  while(TRUE);
}

void main(void) {
   if(!input(PUSH_BUTTON))
   {
      printf("\r\nBootloader Version 1.0\r\n");
   
      // Let the user know it is ready to accept a download
      printf("\r\nWaiting for download...");
      load_program();
   }

   application();
}

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

bootloader.h
Code:

#ifndef __BOOTLOADER_H__
#define __BOOTLOADER_H__

#ifndef LOADER_END
 #if defined(__PCM__)
  #ifdef BOOTLOADER_MODE2X
   #define LOADER_END 0x4BF
  #else
   #define LOADER_END 0x33F
  #endif
 #elif defined(__PCH__)
  #define FLASH_SIZE getenv("FLASH_ERASE_SIZE")
  #if ((0x500 % FLASH_SIZE) == 0)         //IF 0x500 is even flash boundary
   #define LOADER_END   0x4FF
  #else                                  //ELSE, goto next even boundary
   #define LOADER_END   ((0x500+FLASH_SIZE-(0x500 % FLASH_SIZE))-1)
  #endif
 #else
  #error Bootloader only works with PCM or PCH compiler
 #endif
#endif

#define LOADER_SIZE   LOADER_END

#ifndef BOOTLOADER_AT_START
 #define BOOTLOADER_AT_START
#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 {}
#else         
 #ifdef __PCM__
  #if getenv("PROGRAM_MEMORY") <= 0x800
   #org LOADER_END+3, (getenv("PROGRAM_MEMORY") - 1) {}
  #else
   #org LOADER_END+3, 0x7FF {}
   #if getenv("PROGRAM_MEMORY") <= 0x1000
    #org 0x800, (getenv("PROGRAM_MEMORY") - 1) {}
   #else
    #org 0x800, 0xFFF{}
    #if getenv("PROGRAM_MEMORY") <= 0x1800
     #org 0x1000, (getenv("PROGRAM_MEMORY") - 1) {}
    #else
     #org 0x1000, 0x17FF {}
     #if getenv("PROGRAM_MEMORY") <= 0x2000
      #org 0x1800, (getenv("PROGRAM_MEMORY") - 1) {}
     #else
      #org 0x1800, 0x1FFF {}
      #if getenv("PROGRAM_MEMORY") <= 0x2800
       #org 0x2000, (getenv("PROGRAM_MEMORY") - 1) {}
      #else
       #org 0x2000, 0x27FF {}
       #if getenv("PROGRAM_MEMORY") <= 0x3000
        #org 0x2800, (getenv("PROGRAM_MEMORY") - 1) {}
       #else
        #org 0x2800, 0x2FFF {}
        #if getenv("PROGRAM_MEMORY") <= 0x3800
         #org 0x3000, (getenv("PROGRAM_MEMORY") - 1) {}
        #else
         #org 0x3000, 0x37FF {}
         #org 0x3800, 0x3FFF {}
        #endif
       #endif
      #endif
     #endif
    #endif
   #endif
  #endif
 #else
  #if getenv("PROGRAM_MEMORY") <= 0x10000
   #org LOADER_END+5, (getenv("PROGRAM_MEMORY") - 1) {}
  #else
   #org LOADER_END+5, 0xFFFE {}
   #org 0x10000, (getenv("PROGRAM_MEMORY") - 1) {}
  #endif
 #endif
#endif

#endif

ex_bootload.c
Code:

#if defined(__PCM__)
#include <16F887.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#elif defined(__PCH__)
#include <18F45K22.h>
#fuses NOWDT
#use delay(crystal=16MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif

#include <bootloader.h>

void main(void)
{

   int8 i;

   delay_ms(100);
   printf("\r\nApplication Version 1.0\r\n");

   while(TRUE)
      printf("%3u ",++i);
}

loader.c
Code:

#ifndef LOADER_END
 #define LOADER_END      getenv("PROGRAM_MEMORY")-1

 #if defined(__PCM__)
  #define LOADER_SIZE   0x27F
 #elif defined(__PCH__)
  #if (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")) == 0
   #define LOADER_SIZE   0x3FF
  #else
   #define LOADER_SIZE   (getenv("PROGRAM_MEMORY") % (getenv("FLASH_ERASE_SIZE")) - 1)
  #endif
 #endif
#endif

#define LOADER_ADDR LOADER_END-LOADER_SIZE

#ifndef BOOTLOADER_AT_START
 #ORG LOADER_ADDR+4, LOADER_END auto=0 default
#endif

#ifndef BUFFER_LEN_LOD
 #define BUFFER_LEN_LOD    64
#endif

#ifdef BOOTLOADER_MODE2X
 #define BUFFER_COUNT   2
#else
 #define BUFFER_COUNT   1
#endif

#if defined(__PCM__) && !getenv("ENH16") && (BUFFER_COUNT == 2)
 struct
 {
   int8 idx;
   char *buffer;
 } rBuffer[BUFFER_COUNT];

 char Buffer1[BUFFER_LEN_LOD];
 char Buffer2[BUFFER_LEN_LOD];
#else
 struct
 {
   int8 idx;
   char buffer[BUFFER_LEN_LOD];
 } rBuffer[BUFFER_COUNT];
#endif

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

unsigned int atoi_b16(char *s);

#ifdef BOOTLOADER_STREAM
 #define BootLoaderGetc()     fgetc(BOOTLOADER_STREAM)
 #define BootLoaderPutc(c)    fputc(c, BOOTLOADER_STREAM)
#else
 #define BootLoaderGetc()     getc()
 #define BootLoaderPutc(c)    putc(c)
#endif

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") != getenv("FLASH_WRITE_SIZE")
   int32 next_addr;
  #endif
   int8  dataidx, i, count;
   int8  data[BUFFER_LEN_LOD / 2];
  #ifdef BOOTLOADER_MODE2X
   int8  buffidx;
  #endif
   
  #if defined(__PCM__) && !getenv("ENH16") && (BUFFER_COUNT == 2)
   rBuffer[0].buffer = &Buffer1[0];
   rBuffer[1].buffer = &Buffer2[0];
  #endif
   
  #ifdef BOOTLOADER_MODE2X
   buffidx = 0;

   while (!done)  // Loop until the entire program is downloaded
   {
      rBuffer[buffidx].idx = 0;     // Read into the buffer until 0x0D ('\r') is received or the buffer is full
     
      do {
         rBuffer[buffidx].buffer[rBuffer[buffidx].idx] = BootLoaderGetc();
         
      } while ((rBuffer[buffidx].buffer[rBuffer[buffidx].idx++] != 0x0D) && (rBuffer[buffidx].idx <= BUFFER_LEN_LOD));
     
      if(++buffidx >= BUFFER_COUNT)
      {
  #else
   while (!done)  // Loop until the entire program is downloaded
   {
      rBuffer[0].idx = 0;
     
      do {
         rBuffer[0].buffer[rBuffer[0].idx] = BootLoaderGetc();
         
      } while ((rBuffer[0].buffer[rBuffer[0].idx++] != 0x0D) && (rBuffer[0].idx <= BUFFER_LEN_LOD));
  #endif
 
         BootLoaderPutc(XOFF);  // Suspend sender
   
         do_ACKLOD = TRUE;
         
        #ifdef BOOTLOADER_MODE2X
         if(rBuffer[0].idx != rBuffer[1].idx)
            do_ACKLOD = FALSE;
         else
         {
            for(i=0;i<(rBuffer[0].idx-1);i++)
            {
               if(rBuffer[0].buffer[i] != rBuffer[1].buffer[i])
               {
                  do_ACKLOD = FALSE;
                  break;
               }
            }
           
            if(do_ACKLOD)
            {
        #endif   
               // Only process data blocks that start with ':'
               if (rBuffer[0].buffer[0] == ':')
               {
                  count = atoi_b16 (&rBuffer[0].buffer[1]);  // Get the number of bytes from the buffer
         
                  // Get the lower 16 bits of address
                  l_addr = make16(atoi_b16(&rBuffer[0].buffer[3]),atoi_b16(&rBuffer[0].buffer[5]));
         
                  line_type = atoi_b16 (&rBuffer[0].buffer[7]);
         
                  addr = make32(h_addr,l_addr);
         
                 #if defined(__PCM__)  // PIC16 uses word addresses
                  addr /= 2;
                 #endif
                 
                  checksum = 0;  // Sum the bytes to find the check sum value
                  for (i=1; i<(rBuffer[0].idx-3); i+=2)
                     checksum += atoi_b16 (&rBuffer[0].buffer[i]);
                  checksum = 0xFF - checksum + 1;
         
                  if (checksum != atoi_b16 (&rBuffer[0].buffer[rBuffer[0].idx-3]))
                     do_ACKLOD = FALSE;
                  else
                  {
                     // If the line type is 1, then data is done being sent
                     if (line_type == 1)
                        done = TRUE;
                     else if (line_type == 4)
                        h_addr = make16(atoi_b16(&rBuffer[0].buffer[9]), atoi_b16(&rBuffer[0].buffer[11]));
                     else if (line_type == 0)
                     {
                        if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < getenv("PROGRAM_MEMORY"))
                        {
                           // 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 < rBuffer[0].idx-3; i += 2)
                              data[dataidx++]=atoi_b16(&rBuffer[0].buffer[i]);
         
                           #if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
                              if ((addr!=next_addr) && (addr > (next_addr + (getenv("FLASH_ERASE_SIZE") - (next_addr % getenv("FLASH_ERASE_SIZE"))))) && ((addr & (getenv("FLASH_ERASE_SIZE")-1)) != 0))
                              {
                                 #if defined(__PCH__) && defined(BOOTLOADER_AT_START)
                                    #if ((getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")) != 0)
                                       if (addr > (getenv("PROGRAM_MEMORY") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE"))))
                                       {
                                          read_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
                                          erase_program_eeprom(addr);
                                          write_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
                                       }
                                       else
                                    #endif
                                 #endif
                                          erase_program_eeprom(addr);
                              }
                              #if defined(__PCM__)
                                 next_addr = addr + count/2;
                              #else
                                 next_addr = addr + count;
                              #endif
                           #endif
                           
                           #if defined(__PCH__) && defined(BOOTLOADER_AT_START)
                              #if ((getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")) != 0)
                                 if (addr == (getenv("PROGRAM_MEMORY") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE"))))
                                 {
                                    read_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
                                    write_program_memory(addr, data, count);
                                    write_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
                                 }
                                 else
                              #endif
                           #endif
                                    write_program_memory(addr, data, count);
                        }
                     }
                  }
               }
        #ifdef BOOTLOADER_MODE2X
            }
         }
         
         buffidx = 0;
        #endif

         if (do_ACKLOD)
            BootLoaderPutc(ACKLOD);
         
         BootLoaderPutc(XON);
         
     #ifdef BOOTLOADER_MODE2X
      }
     #endif
   }

   BootLoaderPutc(ACKLOD);
   BootLoaderPutc(XON);

   reset_cpu();
}

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);
}

#ifndef BOOTLOADER_AT_START
 #ORG default
 #ORG LOADER_ADDR, LOADER_ADDR+3
#endif
void load_program(void)
{
   real_load_program();
}
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu May 25, 2017 4:53 am     Reply with quote

Well I can see a couple of things (#1 Proteus is BUSTED) but it's a real 'challenge' to decode your code. I'm 'old school' and don't like a lot of conditionals (if-then-elses) based on compiler or PIC type. I prefer 'clean' code, cut for ONE PIC not 2 or 3.
Since you're only using two PICs, have two separate projects and eliminate the mess of the if-then-elses.

It's very easy to have one too many or wrongly placed brace and while the code 'looks' OK, it's actually wrong.

Maybe others (younger ?) are OK with the flow but my old eyes get sore easily these days.

Jay
saeed



Joined: 07 Mar 2017
Posts: 10

View user's profile Send private message

PostPosted: Thu May 25, 2017 5:36 am     Reply with quote

temtronic wrote:
Well I can see a couple of things (#1 Proteus is BUSTED) but it's a real 'challenge' to decode your code. I'm 'old school' and don't like a lot of conditionals (if-then-elses) based on compiler or PIC type. I prefer 'clean' code, cut for ONE PIC not 2 or 3.
Since you're only using two PICs, have two separate projects and eliminate the mess of the if-then-elses.

It's very easy to have one too many or wrongly placed brace and while the code 'looks' OK, it's actually wrong.

Maybe others (younger ?) are OK with the flow but my old eyes get sore easily these days.

Jay

It's not my code!
It's CCS example for bootloader
Smile
newguy



Joined: 24 Jun 2004
Posts: 1903

View user's profile Send private message

PostPosted: Thu May 25, 2017 6:15 am     Reply with quote

saeed wrote:
It's not my code!
It's CCS example for bootloader
Smile


You're not supposed to post the CCS examples or drivers.
saeed



Joined: 07 Mar 2017
Posts: 10

View user's profile Send private message

PostPosted: Thu May 25, 2017 6:45 am     Reply with quote

newguy wrote:
saeed wrote:
It's not my code!
It's CCS example for bootloader
Smile


You're not supposed to post the CCS examples or drivers.

Thats right but i send the full code to show that it works with pic16f887 and doesn't have any problem.
temtronic



Joined: 01 Jul 2010
Posts: 9125
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu May 25, 2017 6:45 am     Reply with quote

If it's 100% CCS code, then that confirms Proteus is BUSTED !!
Oreminclutch



Joined: 31 May 2017
Posts: 2

View user's profile Send private message

PostPosted: Wed May 31, 2017 6:56 am     Reply with quote

If it's an example code and it's not working then you know what the problem is. Especially if it's working for something else.

Proteus sucks

top 3 best roulette chat sites
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