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

CCS Bootloader Problem

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



Joined: 21 Feb 2008
Posts: 24

View user's profile Send private message

CCS Bootloader Problem
PostPosted: Thu Sep 18, 2008 3:44 pm     Reply with quote

I'm using processor 18LF6722
Clock is 4MHz
compiler version is PCH V4.066

I'm trying to implement a bootloader in my project but I've had little luck so far. The program just doesn't run. When I take the bootload stuff out, things function.

Here is my program stripped down as much as possible:
Main program - bootloader.c
Code:

#include "C:\Documents and Settings\kerrj\My Documents\Firmware\Bootloader\bootloader.h"
#include "C:\Documents and Settings\kerrj\My Documents\Firmware\Bootloader\bootloader_bootloader.h"


//BOOTLOADER AT START - Include Bootloader.h in your application - See sample application Ex_Bootload.c 
//BOOTLOADER AT END - Always include the projectname_bootloader.h file in future versions of the project

void application(void) {
 
  while(TRUE){
     fprintf(DEBUG232, "Version 1.00\r\n");
     delay_ms(1000);
     
   if(!input(PushButton)){
      write_eeprom(EE_ENTER_BOOTLOADER, 0xAA);
      reset_CPU();
   }
  }
}
void main()
{
     setup_adc_ports(NO_ANALOGS|VSS_VDD);
     setup_adc(ADC_OFF|ADC_TAD_MUL_0);
     setup_psp(PSP_DISABLED);
     setup_spi(SPI_SS_DISABLED);
     setup_spi2(SPI_SS_DISABLED);
     setup_wdt(WDT_OFF);
     setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);          // 524mS /tick
     setup_timer_1(T1_DISABLED);
      setup_timer_2(T2_DISABLED,0,1);
     setup_timer_3(T3_DISABLED|T3_DIV_BY_1);         
      setup_timer_4(T4_DIV_BY_16,240,13);      //50.1 mS timer
     setup_comparator(NC_NC_NC_NC);
     setup_vref(FALSE);

     setup_low_volt_detect(FALSE);
     setup_oscillator(false);
   
     SET_TRIS_A(TRIS_A_SETTING);
     SET_TRIS_B(TRIS_B_SETTING); 
     SET_TRIS_C(TRIS_C_SETTING);
     SET_TRIS_D(TRIS_D_SETTING);
     SET_TRIS_E(TRIS_E_SETTING);
     SET_TRIS_F(TRIS_F_SETTING);
     SET_TRIS_G(TRIS_G_SETTING);

   enable_interrupts(GLOBAL);       
   
     ext_int_edge( 2, H_TO_L);
     ext_int_edge( 3, H_TO_L);

      output_bit(XMIT_PWR_ON,1);  // xmitter on
      output_bit(LED1_ON,1);  // xmitter on
      delay_ms(2000);
     
   if(read_eeprom(EE_ENTER_BOOTLOADER) == 0xAA)
   {
      output_bit(LED1_ON,0);  // xmitter on
      fprintf(DEBUG232, "Bootloader!!!\r\n");
      real_load_program();
   }

      application();
}

bootloader.h
Code:

#include <18F6722.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES IESO                     //Internal External Switch Over mode enabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES LPT1OSC                  //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#FUSES BBSIZ1K                  //1K words Boot Block size

#use delay(clock=4000000)

#define EE_ENTER_BOOTLOADER                  357

#define TRIS_A_SETTING            0xcF
#define TRIS_B_SETTING            0x7F
#define TRIS_C_SETTING            0x90
#define TRIS_D_SETTING            0x08
#define TRIS_E_SETTING            0x18
#define TRIS_F_SETTING            0x00
#define TRIS_G_SETTING            0x24

#define PushButton         PIN_B4   // input 1
#define MESH_TX            PIN_C6   // output 0
#define MESH_RX            PIN_C7   // input 1
#define SATGSM_TX          PIN_G1   // input  0
#define SATGSM_RX          PIN_G2   // input  1
#define DEBUG_TX           PIN_E2   // output 0
#define DEBUG_RX           PIN_E3   // input 1 
#define XMIT_PWR_ON        PIN_D1   // output 0
#define LED1_ON            PIN_F3   // output 0

#use rs232(baud=9600,parity=N,xmit=MESH_TX,rcv=MESH_RX,bits=8,restart_wdt,STREAM=MESH232,errors)
#use rs232(baud=9600,parity=N,xmit=SATGSM_TX,rcv=SATGSM_RX,bits=8,restart_wdt,STREAM=SATGSM232,errors)
#use rs232(baud=9600,parity=N,xmit=DEBUG_TX,rcv=DEBUG_RX,bits=8,restart_wdt,STREAM=DEBUG232, DISABLE_INTS)

bootloader_bootloader.h
Code:

//bootloader code
// APPLICATION_ISR_VECTOR - Where the compiler is going to put the ISR
#define FIRMWARE_UPGRADE_VECTOR  0          // Bootloader at Start of memory
#define MAX_UPGRADE_AREA         (0x500)    // Space required by bootloader
#define MIN_FIRMWARE_UPGRADE_MEMORY_AREA   (0x20)   // Start of bootloder code
#define MAX_FIRMWARE_UPGRADE_MEMORY_AREA   (MAX_UPGRADE_AREA-1) // End of bootloder code
#define APPLICATION_RESET_VECTOR 0x500     // New RESET Vector
#define APPLICATION_ISR_VECTOR   0x508     // New Interrupt Vector

// Re-vectored RESET vector from 0x0000 to 0x0500
// Re-vectored Interrupt vector from 0x0008 to 0x0508
#build(reset=APPLICATION_RESET_VECTOR, interrupt=APPLICATION_ISR_VECTOR)


#define LOADER_END   MAX_UPGRADE_AREA -1
#define LOADER_ADDR  MIN_FIRMWARE_UPGRADE_MEMORY_AREA


#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(SATGSM232);
      } while ( (buffer[buffidx++] != 0x0D) && (buffidx <= BUFFER_LEN_LOD) );

      putchar (XOFF, SATGSM232);  // Suspend sender

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

         #if defined(__PCM__)  // PIC16 uses word addresses
            addr /= 2;
         #endif

         // If the line type is 1, then data is done being sent
         if (line_type == 1) {
            done = TRUE;
         #if defined(__PCM__)
         } else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x2000){
         #elif defined(__PCH__)
         } else if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < 0x300000){
         #endif
            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 defined(__PCM__)
                        if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")-1)!=0))
                     #else
                        if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
                     #endif
                           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, SATGSM232);

      putchar(XON, SATGSM232);
   }

   putchar (ACKLOD, SATGSM232);
   putchar(XON, SATGSM232);
   write_eeprom(EE_ENTER_BOOTLOADER, 0x00);
   #ifndef _bootloader
   reset_cpu();
   #endif
}

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


I assume the issue is how I have the RESET vector and the Interrupt vector "re-vectored". The bootload portion of the code came directly from the CCS PIC Wizard.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Sep 18, 2008 4:12 pm     Reply with quote

Quote:
#FUSES LVP

I didn't look at your code in detail, but the line above will cause problems.

Change it to NOLVP.
ntgcp_08



Joined: 21 Feb 2008
Posts: 24

View user's profile Send private message

PostPosted: Thu Sep 18, 2008 4:19 pm     Reply with quote

Oops, somehow my #fuses changed... here is what I'm using. The program still does not function

Code:

#FUSES HS                       //External Oscillator using HS
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOIESO                   //Internal External Switch Over mode enabled
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV25                   //Brownout reset at 2.0V
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG
#FUSES NOLVP                    //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTC                   //configuration registers not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOFCMEN                  //Fail-safe clock monitor enabled
#FUSES NOLPT1OSC                //Timer1 configured for low-power operation
#FUSES MCLR                     //Master Clear pin enabled
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode enabled
#FUSES BBSIZ1K             
ckielstra



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

View user's profile Send private message

PostPosted: Thu Sep 18, 2008 6:37 pm     Reply with quote

Your code has only one line with #org in it. There is at least a second #org required to mark the end of the bootloader section.
I don't have time to look into it now but if you compare the original generated code to what you have now you should easily spot the now missing '#org', or '#org default'.
ntgcp_08



Joined: 21 Feb 2008
Posts: 24

View user's profile Send private message

PostPosted: Fri Sep 19, 2008 8:34 am     Reply with quote

Using the PIC Wizard the #ORG that is in bootloader_bootloader.h is the only #ORG that was added.

I went through ex_bootloader.c to see where it has #ORG statements.

My bootloader.c now looks like this:
Code:

#ORG 0x0640, 0xFFFF
void application(void) {
 
  while(TRUE){
     fprintf(DEBUG232, "Version 1.00\r\n");
     delay_ms(1000);
     
   if(!input(PushButton)){
      write_eeprom(EE_ENTER_BOOTLOADER, 0xAA);
      reset_CPU();
   }
  }
}

#org 0x528, 0x63F
void main()
{
     setup_adc_ports(NO_ANALOGS|VSS_VDD);
     setup_adc(ADC_OFF|ADC_TAD_MUL_0);
     setup_psp(PSP_DISABLED);
     setup_spi(SPI_SS_DISABLED);
     setup_spi2(SPI_SS_DISABLED);
     setup_wdt(WDT_OFF);
     setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);          // 524mS /tick
     setup_timer_1(T1_DISABLED);
      setup_timer_2(T2_DISABLED,0,1);
     setup_timer_3(T3_DISABLED|T3_DIV_BY_1);         
      setup_timer_4(T4_DIV_BY_16,240,13);      //50.1 mS timer
     setup_comparator(NC_NC_NC_NC);
     setup_vref(FALSE);

     setup_low_volt_detect(FALSE);
     setup_oscillator(false);
   
     SET_TRIS_A(TRIS_A_SETTING);
     SET_TRIS_B(TRIS_B_SETTING); 
     SET_TRIS_C(TRIS_C_SETTING);
     SET_TRIS_D(TRIS_D_SETTING);
     SET_TRIS_E(TRIS_E_SETTING);
     SET_TRIS_F(TRIS_F_SETTING);
     SET_TRIS_G(TRIS_G_SETTING);

   enable_interrupts(GLOBAL);       
   
     ext_int_edge( 2, H_TO_L);
     ext_int_edge( 3, H_TO_L);

      output_bit(XMIT_PWR_ON,1);  // 5V Power On
      output_bit(LED1_ON,1);  // LED on
      delay_ms(2000);

   if(read_eeprom(EE_ENTER_BOOTLOADER) == 0xAA)
   {
      output_bit(LED1_ON,0);  // LED off
      fprintf(DEBUG232, "Bootloader!!!\r\n");
      real_load_program();
   }

      application();
}

#ORG default


I also added an #ORG Default to the end of bootloader_bootloader.h

However, I still have no luck.

So now, I believe my memory map looks like the following... correct?
0x0000 to 0x0029 - Nothing
0x002A to 0x04FF - Bootloader
0x0500 to 0x0507 - Reset Vector
0x0508 to 0x0527 - Interrupt Service Routine
0x0528 to 0x063F - Main
0x0640 to 0xFFFF - Application
ntgcp_08



Joined: 21 Feb 2008
Posts: 24

View user's profile Send private message

PostPosted: Fri Sep 19, 2008 10:33 am     Reply with quote

OK, I've got it working...

How I got it working??? I followed the ex_bootloader.c exacty how it was written. I didn't try using the PIC Wizard.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Sep 25, 2008 1:28 am     Reply with quote

As a late comment:
Code:
0x0000 to 0x0029 - Nothing

can't be correct. The region has to hold the primary reset and interrupt handler.
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