Aqui estoy de nuevo..parece que ya se va viendo la luz......Despues de peinar el foro de CCS parece claro que la ubicacion del bootloader en el final de la memoria es mejor que ponerlo en el principio por muchas razones (no tener que reubicar el vector de reset ni el de interrupcion, mejor eficiencia de las interrupciones, etc). Con esta premisa y dando muchas vueltas he modificado el bootloader del CCS (si , ese que siempre da error...) como sigue:
//bootloader code
//#ifndef __BOOTLOADER_H__
//#define __BOOTLOADER_H__
//#define __BOOTLOADER_INCLUDED__ TRUE
//#if defined(__PCM__)
#define LOADER_SIZE 0x1FF //antes 0x1FF
//#elif defined(__PCH__)
// #define LOADER_SIZE 0x3FF
//#endif
//#endif
//BOOTLOADER AT END
// LOADER_END - This is the end of the general purpose bootload code.
//#ifndef LOADER_END
#define LOADER_END getenv("PROGRAM_MEMORY")-1
#define LOADER_ADDR LOADER_END-LOADER_SIZE
//#endif
// For 16F88
#define BUFFER_LEN_LOD 64
#define ACKLOD 0x06
#define XON 0x11
#define XOFF 0x13
#define OK 0x14
int buffidx;
char buffer[BUFFER_LEN_LOD];
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];
#SEPARATE
unsigned int atoi_b16(char *s);
#SEPARATE
void escribe(){
// 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);
#if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE") // 32-word > 4-word
#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);
}
#ORG LOADER_ADDR+10, LOADER_END auto=0 default
void real_load_program (void)
{
#use rs232(baud=9600, xmit=PIN_B4, rcv=PIN_B5,PARITY=E,ERRORS)
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
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);
checksum = 0xFF - checksum + 1;
if (checksum != atoi_b16 (&buffer[buffidx-3]))
do_ACKLOD = FALSE;
else {
if (line_type == 0) {
escribe();
}
else if (line_type == 4)
h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer[11]));
}
}
}
if (do_ACKLOD)
putchar ('.'); // Linea OK
else
putchar ('_'); // Linea chunga
putchar('\r');
putchar('\n');
//putchar (ACKLOD);
//putchar(XON);
}
putchar(OK);
//putchar (ACKLOD);
//putchar(XON);
#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);
}
#ORG default
#ORG LOADER_ADDR, LOADER_ADDR+9
void load_program(void)
{
real_load_program();
}
De esta manera no da el maldito error de "Out of ROM". Por otra parte el "#ORG default" es imprescindible para que el compilador siga poniendo el codigo del Main al principio de la ROM. La funcion load_program tambien es imprescindible para que puedan hacerse los saltos entre el main y el bootloader. De momento estoy haciendo la aplicacion del PC para volcar el Hex pero pinta muy bien. Por lo menos compila e inicia que no es poco.
Espero que esto le sirva alguien, estoy seguro de que si.. Ya os contare.
Saludos!!....
Jesus.