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

Help with bootloader, PIC24FJ32

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



Joined: 03 Mar 2009
Posts: 24

View user's profile Send private message

Help with bootloader, PIC24FJ32
PostPosted: Thu Aug 20, 2009 12:41 pm     Reply with quote

It is my first project with “C” and CCS. Application is very complex system and after 4 month everything is working just fine. Before releasing this product I have to implement the bootloader, so updates can be performed globally on all the units. I am using PIC24FJ32GA004 and put modified bootloader functions in the memory area 0x5000 and up. Host is sending many different commands were unit is performing predefined functions and idea was to set one of the commands (“#BTL” for example) to jump to the bootloader area, erase everything below 0x5000 and then write line by line the HEX code. I tried to use only local functions located in bootload area, but for some reason controller getting stuck when erasing block 0x1800. I found that in different compilation it gets stuck erasing different memory area. Looking in disassembly windows I found that in erase loop code calling for address in 0~0x400 range. Here is the code I modified for bootloader, (I know it is long, sorry).
Code:

int1 bl_err;      //BootLoad error
int1   bl_to;      //BootLoader UART time out
#org 0x5000,0x5038
char bl_getc()      //Receive USART character with 0.5 Sec. time-out Size 0x36
{
   long timeout;
   bl_to=0;
   timeout=0;
   while(!kbhit()&&(++timeout<50000)) // 1/2 second
          delay_us(10);
   if(kbhit())
          return(fgetc(PC));
   else {
          bl_to=1;
          return(0);
   }
}
#org 0x5040,0x508F
char bl_gets(*s, unsigned int8 max_char)   //Receive string from UART with time-out. Size 0x003A
{
   unsigned int8   icnt;
   char d_byte;
   if(max_char == 0)
      max_char = 127;   //Limit of FTDA Rx buffer
   for(icnt = 0;icnt < max_char;++icnt)
   {
      d_byte = bl_getc();
      if(bl_to != 0)
         {
            host_step = 0;
            return;
         }
      if(d_byte == 0x0D)
         return;
      else
         s[icnt] = d_byte;
   }   
}
#org 0x5090,0x50EF
unsigned int8 atoi_b16(char *s)      //Size 0x0044
{  // Convert two hex characters to a int8
   unsigned int8 result = 0;
   unsigned int8 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 0x50F0,0x512F
signed int8 bl_strcmp(char *s1, char *s2)   //Size 0x0032
{
   for (; *s1 == *s2; s1++, s2++)
      if (*s1 == '\0')
         return(0);
   return((*s1 < *s2) ? -1: 1);
}
#org default
#org 0x5130,0x5500
void process_bl()   //Size 0x02D4
{
   char   bl_buffer[64];
   unsigned int8  bl_data[32];
   
   unsigned int16 l_addr,h_addr=0;
   unsigned   int8   bl_counter=0;
   unsigned   int32   bl_address=0;
   unsigned int16  buffidx;
   unsigned int8  bl_checksum, line_type, bli,bl_dataidx;
   char   bl_cmd[5] = "0000";
   char   bl_key[5] = "1234";
   disable_interrupts(int_timer3);
   disable_interrupts(int_timer5);
   disable_interrupts(int_rda);
   puts("OK");
bl_loop1:
   bl_gets(bl_cmd,0);                              //Get bootloader key
   if((bl_to != 0) || (bl_strcmp(bl_cmd,bl_key) != 0))      //Loop until key is in
   {
      goto bl_loop1;
      puts("ERR");
   }
   //bl_address=getenv("FLASH_ERASE_SIZE");
   //Erase flash 0x0000~0x4FFF
   
   for(bl_address=0x1000;bl_address < 0x3800;bl_address += 0x400) //getenv("FLASH_ERASE_SIZE"))
   {
      //bl_address = 0x0000;
       erase_program_memory(bl_address);
   }
   
   puts("OK");
bl_loop2:
   buffidx = bl_gets(bl_buffer,64);   //Get first line of the bootfile
   if (bl_buffer[0] != ':')
   {
      puts("ERR");
      goto   bl_loop2;   //First key of the line should be ":"
   }
   puts("OK"); ///////TEMP
   bl_counter = atoi_b16 (&bl_buffer[1]);  // Get the number of bytes from the buffer
   l_addr = make16(atoi_b16(&bl_buffer[3]),atoi_b16(&bl_buffer[5])); // Get the lower 16 bits of address
   line_type = atoi_b16(&bl_buffer[7]);      //Get type of data
   bl_address = make32(h_addr,l_addr) / 2;
   if (line_type == 1)
      goto   bl_complete;
   else if ((bl_address < 0x4FFF))
   {
      bl_checksum = 0;  // Sum the bytes to find the check sum value
         for (bli=1; bli<((bl_counter*2) + 8); bli+=2)
            bl_checksum += atoi_b16 (&bl_buffer[bli]);
         bl_checksum = 0xFF - bl_checksum + 1;
        if (bl_checksum != atoi_b16 (&bl_buffer[(bl_counter * 2) +9]))
      {
           puts("ERR");
         goto   bl_loop2;
      }
          else   
      {
           if (line_type == 0)
         {
              // Loops through all of the data bytes and stores it in bl_data
              // The last 2 bytes are the check sum, hence buffidx-3
               for (bli = 9,bl_dataidx=0; bli < ((bl_counter*2) + 8); bli += 2)
                   bl_data[bl_dataidx++]=atoi_b16(&bl_buffer[bli]);
            write_program_memory(bl_address, bl_data, bl_counter);
            puts("OK");
         }
            else if (line_type == 4)
               h_addr = make16(atoi_b16(&bl_buffer[9]), atoi_b16(&bl_buffer[11]));
            puts("OK");
       }
   }
   goto bl_loop2;     
bl_complete:
   puts("OK");
   reset_cpu();
}



Here is disassembly snapshot in erase loop showing call to 0x000346:

Code:

102:                  {
103:                     //bl_address = 0x0000;
104:                      erase_program_memory(bl_address);
  51E8  807F30     mov.w 0x0fe6,0x0000
  51EA  807F41     mov.w 0x0fe8,0x0002
  51EC  880191     mov.w 0x0002,0x0032
  51EE  BB0801     tblwtl.w 0x0002,[0x0000]
  51F0  240421     mov.w #0x4042,0x0002
  51F2  020346     call 0x000346
105:                  }


Please help, what am I doing wrong?
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Thu Aug 20, 2009 3:58 pm     Reply with quote

I don't understand your bootloader layout. If the loader is located starting from 0x5000, how can it call flash write code at 0x346 (the main application area).
gilavar



Joined: 03 Mar 2009
Posts: 24

View user's profile Send private message

PostPosted: Thu Aug 20, 2009 4:55 pm     Reply with quote

FvM wrote:
I don't understand your bootloader layout. If the loader is located starting from 0x5000, how can it call flash write code at 0x346 (the main application area).

Thank you for reply. I added "default" and "#ORG default" to keep compilers library within the functions and it appears I can erase all the memory blocks below 0x5000.
Now I have to find out how to write there. Is that normal procedure to write to the memory blocks below?
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