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

18f8722 Bootloader RAM array Issues

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



Joined: 10 Sep 2010
Posts: 7
Location: Germany

View user's profile Send private message

18f8722 Bootloader RAM array Issues
PostPosted: Sun Apr 17, 2011 3:12 am     Reply with quote

Hi!
I´m working now for long time on a Bootloader for a 18f8722.
This loader is reading FW Update file (compiled hex file) from an SD card, and updates the PIC FW.
All is working well, update is successful, pic starts working normally to that Point, I start to use Interrupts in my main app.

If I use just 1 Interrupt (RB0), and this occurs first time, one of my Global RAM Array Vars get the value of \0 (NULL).

Before first Interrupt occurs, all is working fine.

I think that the jump to isr would overwrite my Ram variable, but why does it?

If I load main hex without bootloader to chip, everything is ok with Interrupts Enabled or without.

I hope somebody had same Problems and could tell me how to solve it.

There must be something with my loader adresses....but what...

Here is my Bootloader main:

Code:

///////////////////////////////////////////////////////////////////////////
////                      EX_BOOTLOADER.C                              ////
////                                                                   ////
////  This program is an example stand alone bootloader.               ////
////                                                                   ////
////  This program must be loaded into a target chip using a device    ////
////  programmer.  Afterwards this program may be used to load new     ////
////  versions of the application program.                             ////
////                                                                   ////
////  This bootloader is designed to detect pin B5 low on reset.  It   ////
////  will then use the RS232 link to download a new program.          ////
////  Otherwise the application program is started.                    ////
////                                                                   ////
////  Use an RS232 link and the SIOW.EXE program to load a new HEX     ////
////  file into the target chip.                                       ////
////                                                                   ////
////  This example will work with the PCM and PCH compilers.  The      ////
////  following conditional compilation lines are used to include a    ////
////  valid device for each compiler.  Change the device, clock and    ////
////  RS232 pins for your hardware if needed.                          ////


#include "18F8722.h"
#FUSES NOWDT,WDT128,H4,NOPROTECT,NOIESO,NOBROWNOUT,NOPUT,NOCPD,noSTVREN,nODEBUG,NOLVP,NOWRT,NOCPB,NOEBTRB,NOEBTR,CCP2C1,NOWRTD,NOWRTC,NOWRTB,NOFCMEN,LPT1OSC,MCLR,NOXINST,MCU

#use delay(clock=40000000)
#use rs232(UART2,baud=57600,parity=N,bits=8,stream=pc,errors,DISABLE_INTS)//9600


#define _bootloader

#include "Bootloader.h"//include this in main app
#include "sd-loader.c"

 #org LOADER_END+2,LOADER_END+20
void application(void) { //main loop
  while(1){
   output_toggle(led);
   delay_ms(200);
   }
}
#org 0x40,0x7F
void main(void) {
      load_program();//Check for FW File
      application();
}

#ORG default
   #int_global
   void isr(void) {
     #asm
       goto LOADER_END+7
       nop
       nop
       nop
       nop
       nop
       nop
       goto LOADER_END+0x17
     #endasm
   }


Bootloader.h (include file for main app)
Code:

///////////////////////////////////////////////////////////////////////////
////                       BOOTLOADER.H                                ////
////                                                                   ////
////  This include file must be included by any application loaded     ////
////  by the example bootloader (ex_bootloader.c).                     ////
////                                                                   ////
////  The directives in this file relocate the reset and interrupt     ////
////  vectors as well as reserving space for the bootloader.           ////
////                                                                   ////
////  LOADER_END and LOADER_SIZE may need to be adjusted for a         ////
////  specific chip and bootloader.                                    ////

   #define LOADER_END   0x14FF //0x4FF //1000
   #define LOADER_SIZE  0x13FF //0x3FF //F00

#ifndef _bootloader

   #build(reset=LOADER_END+1, interrupt=LOADER_END+9)

#org 0, LOADER_END {}

#endif


sd-loader.c:
Code:

#define LED pin_f3
//--------- SD --------
#define SD_select_pin PIN_E0
#define SD_Reset_pin PIN_J4
#define SD_card_detect pin_E2
//#define SD_busy_bit PIN_D5

//Defines Edip lcd :
#define edip_reset_pin PIN_D1
#define edip_select_pin PIN_D0
#define spi_clock pin_c3

#define Mode_0 0x4000// SPI
#define Mode_1 0x0000
#define Mode_2 0x0010
#define Mode_3 0x4010


//#define LOADER_SIZE   0x13FF
#define LOADER_ADDR LOADER_END-LOADER_SIZE
#define BUFFER_LEN_LOD 64 // RAM buffer

unsigned int  buffidx;
char buffer[BUFFER_LEN_LOD];
//#USE STANDARD_IO (d)

#SEPARATE
unsigned int atoi_b16(char *s);

#ORG LOADER_ADDR+10, LOADER_END auto=0 default
#include "SD_lib.c"

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];
   int16 zeile=1,buf;
   int32 ptr=0,ptr2=0;
   port_b_pullups(TRUE);
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF|ADC_TAD_MUL_0);
   setup_psp(PSP_DISABLED);
   setup_spi2(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DIV_BY_16,249,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_ccp1(CCP_PWM);setup_ccp2(CCP_PWM);setup_ccp3(CCP_PWM);setup_ccp4(CCP_PWM);setup_ccp5(CCP_PWM);
   set_pwm1_duty(0);set_pwm2_duty(0);set_pwm3_duty(0);set_pwm4_duty(0);set_pwm5_duty(0);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_low_volt_detect(FALSE);
   setup_spi(SPI_MASTER|Mode_3|SPI_CLK_DIV_16);//SPI Mode 3,div 16 bei 10 Mhz * 4 = Clock von 2,5 Mhz, 64 = 625 Khz
   if(input(pin_d4)==1){}

fprintf(pc,"\r######FW loader V1.0 Start ######\r");delay_ms(1000);

if (open_fw_update_file()==0){//check if FW File exists
set_pwm3_duty(1000);
Zeile=1;
//led_blink();

   while (!done)  // Loop until the entire program is downloaded
   {

//############# START beginn to fill RAM ########################
buffidx=0;
set_byte_pos(ptr);

Zeichen_von_sd_lesen(64,debug_off);

delay_ms(10);
do{
buf=spi_read_sd();

}while(buf!=':');//wait for ':'
buffer[buffidx]=buf;//write ':' to buffer
fprintf(pc,"%c",buffer[buffidx]);
do{
buffidx++;
buffer[buffidx]=spi_read_sd();
fprintf(pc,"%c",buffer[buffidx]);

}while((buffer[buffidx]!=13) && (buffidx <= BUFFER_LEN_LOD));
del_sd_buf();

ptr2=buffidx;
ptr=ptr+ptr2+2;//set Pointer to ':'
Zeile ++;

buffidx++;

      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 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]));
            }
         }
      }
   }
   file_close();//close file
   delete_fw_update_file();delay_ms(100);

   #ifndef _bootloader
   reset_cpu();
   #endif
}
Else{
fprintf(pc,"\rNo FW file (8722.txt) found... \r");
}
fprintf(pc,"\r###### FW loader V1.0 END ######\r");
}

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



Joined: 11 Mar 2010
Posts: 19247

View user's profile Send private message

PostPosted: Sun Apr 17, 2011 8:17 am     Reply with quote

Personally, I prefer to have an extra #define.
#define MAIN_CODE_START (LOADER_END+1)

Then everything in the main program can be referenced to this. So

#build(reset=MAIN_CODE_START, interrupt=MAIN_CODE_START+8)

and your interrupt relocater can be referenced to this +8 as:
Code:

#int_global
void isr(void) {
    jump_to_isr(MAIN_CODE_START+8);
}

It would appear to me, that your current relocater, is jumping to the wrong location. Two addresses short of where it should be going....
Also the jump_to_isr function automatically handles relocating both high and low priority ISR's, so why not use it.....

Best Wishes

Best Wishes
surfer0815



Joined: 10 Sep 2010
Posts: 7
Location: Germany

View user's profile Send private message

PostPosted: Tue Apr 19, 2011 5:19 am     Reply with quote

Thanks a lot! That did it!
I added your define and Jump_to_isr and now my Ram array seem to stay stable!
Greetings from Germany!
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