|
|
View previous topic :: View next topic |
Author |
Message |
kameshward
Joined: 23 Feb 2011 Posts: 2
|
Bootloader for PIC16F886 |
Posted: Wed Feb 23, 2011 7:14 am |
|
|
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
|
|
Posted: Wed Feb 23, 2011 5:05 pm |
|
|
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
|
|
Posted: Thu Feb 24, 2011 7:53 am |
|
|
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. |
|
|
|
|
|
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
|