|
|
View previous topic :: View next topic |
Author |
Message |
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
Bootloader Questions/Problems |
Posted: Thu Jan 18, 2007 8:43 am |
|
|
Preface: I'm writing a bootloader and all applications loaded with it do not run, I've exhausted my tallent for finding the error, can you help
Any help on how to track down the error would be great.
At this point there are 9 posts mainly myself pusuing lines of attack and failing, but could offer information to anyone trying to help.
Original post here on down
Hi,
I'm currently trying to write a bootloader but have got stuck 90% of the way there...
Hoping you can help.
I've included the source files and the list file for the loader, and a memory map of where the application sits.
These are all modifications to the Loader.c ex_bootloader.c ex_bootload.c and bootloader.h files. I first copied loader.c into the file and modified from there. The bootloader works fine, in that I can re-program memory in the program eeprom and data eeprom sections at will. The PC software interprets the application HEX file, checks the check sum, ensures that it will not overwrite the bootloader etc. There are no inturupts used in the bootloader, and even after a "non-working application" has been downloaded the bootloader if triggered still functions. You'll see (if you read through the code) that there are several options for triggering the bootload, at the moment it's pin A4 held low when reset. All the other options work, RS232 Escape Key, and EEPROM (DATA and PROGRAM) strorage of decision. Though the latter two require the application to write to this memory and reboot to trigger bootloading, so not useful yet!
So I'm happy that I can bootload a program, but I can't get the application loaded to run (I can write the values to memory but they don't function). Any ideas as to why the "dummy" application flashed with the bootloader works but anything else does not.
The only thing I can see is in the memory map there is a gap of 4 bytes which the bootloader writes which I thought would be empty prior to the interupt vector.
Though niether bootloader or application use interupts I suspect this is where my problems lie, my applications will eventually use interupts.
I'm a little unsure of this section of code, used unchanged from loader.c
Code: |
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
the code in bootloader.c different
Code: |
void isr(void) {
#asm
goto LOADER_END+9
goto LOADER_END+9
goto LOADER_END+9
goto LOADER_END+9
goto LOADER_END+0x19
#endasm
}
|
I think they are trying to do the same thing? Which is better/correct?
I'm also a little puzzled by the LOADER_END+5*(16/8) - Is this not missing a plus one. Again this is copied code, which I've not had the confidence to alter.
Quick question
I had to move the "#use delay" and "#use RS232" from immediately after the "#fuses" statement until after first "#ORG# statement or else the "subroutines" created by these statements are located outside of the bootloader. The example did not seem to require this code order?
Here are the files
The loader/application header
Code: |
///////////////////////////////////////////////////////////////////////////
//// my_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. ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2004 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
//// ////
//// 2006-11-29 Modified by bairds to test PIC18F258 (PCH options only)////
//// 2006-01-16 Modified by bairds to match bootloader ////
//// ////
//// _bootloader set when compiling the bootloader (obviously realy!) ////
//// ////
//// THEREFORE BUILD/ORG STATEMENTS IN THIS FILE ARE COMPILED INTO THE ////
//// APPLICATION. ////
//// ////
///////////////////////////////////////////////////////////////////////////
#DEFINE LOADER_END 0x7FF
#DEFINE LOADER_SIZE 0x6FF // 0x100 LESS THAN ABOVE
// THE FOLLOWING TWO HASH DEFINE STATMENTS ARE REQUIRED ONLY IF USING THE
// PROG_EEPROM BOOTLOADER DECISION.
//
// THIS USES A CHUNK OF PROGRAM MEMORY STORE BOOTLOAD/APP DECISION
//
// THIS REQUIRES 0x40 (64) BYTES BECAUSE OF THE ERASE_PROGRAM_EEPROM
// AND ALSO SHOULD BE AT A 0x40 BOUNDARY
#DEFINE LOADER_DECISION 0x00000780
// SETS EPPROM LOCATIONS IN THE PROGRAM MEMORY TO ALLOW THE BOOTLOADER
// TO DECIDE WHETHER TO START THE APPLICATION OR RUN THE BOOTLOADER.
// THIS MUST CALLED IN THE APPLICATION SOMEWHERE OTHERWISE THE BOOTLOADER
// WILL NEVER FUNCTION
#DEFINE R_AND_B erase_program_eeprom(LOADER_DECISION); write_program_eeprom(LOADER_DECISION,0x0000 ); reset_cpu();
#IFNDEF _bootloader
// THIS WILL PUT THE APPLICATION RESET 4 BYTES
// FOLLOWED BY FOUR BLANKS
// FOLLOWED BY THE INTERUPTS
#BUILD(reset=LOADER_END+1, interrupt=LOADER_END+9)
// NO FUNCTIONS WILL BE IN THE MEMORY RANGE 0 TO LOADER END
// THEREFORE THE COMPILER WILL NOT PUT FUNCTIONS OVER THE BOOT LOADER
// THIS ALLOWS THE COMPILER TO PUT THE APPLICATIONS FUNCTIONS WHERE IT LIKES
#ORG 0, LOADER_END {}
#ENDIF
|
The Application
Code: |
// TINY APP
#include <18F258.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
//#define _bootloader
#include "..\include\my_bootloader.h"
void main(void)
{
while(true)
{
delay_ms(500);
output_high(PIN_B0) ;
delay_ms(500);
output_low(PIN_B0);
}
}
|
The memory map at 0x800.
The single digits after the 16 Hex values denote
1 - FLASHED with bootloader - reset to FF when application is loaded.
2 - Application
3 - Both, the application overwrites the bootloader
Code: |
0x000800 19 EF 04 F0 07 0E 00 6E EA 6A 07 0E E9 6E EF 50 3 3 3 3 1 1 1 1 3 3 3 3 3 3 3 3
0x000810 0F E0 03 0E 01 6E 00 6A 00 2E FE D7 01 2E FB D7 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
0x000820 3C 0E 00 6E 00 2E FE D7 00 00 00 00 EF 2E F1 D7 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
0x000830 00 0C F8 6A D0 9E EA 6A E9 6A C1 80 C1 82 C1 84 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
0x000840 C1 96 02 0E 06 6E FA 0E 07 6E DE DF 06 2E FB D7 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
0x000850 93 90 8A 80 02 0E 06 6E FA 0E 07 6E D5 DF 06 2E 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
0x000860 FB D7 93 90 8A 90 ED D7 03 00 FF 00 D4 D7 00 0C 3 3 3 3 3 3 3 3 3 3 1 1 1 1 1 1
|
The Bootloader
Code: |
///////////////////////////////////////////////////////////////////////////
//// EX_BOOTLOADER.C ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2004 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
//// ////
//// 2006-11-29 Modified by bairds to test PIC18F258 (PCH options) ////
//// 2007-01-09 Modified by bairds one file ////
//// 2007-01-13 Modified by bairds to suit purpose ////
//// ////
///////////////////////////////////////////////////////////////////////////
#include <18F258.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#define _bootloader
#include </include>
#define LOADER_ADDR LOADER_END-LOADER_SIZE
#define BUFFER_LEN_LOD 64
// ============================================================================
// FUNCTION DECLARATIONS
// ============================================================================
// DO NOT INLINE THESE FUNCTION (SPACE SAVING)
// CONVERT TWO HEX CHARACTERS TO int8
#SEPARATE
unsigned int atoi_b16(char *s);
// READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
#SEPARATE
void read2RS232( int32 a, char c );
// READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
#SEPARATE
void REPP2RS232( int a, char c );
// real_load_program
// ============================================================================
#ORG LOADER_ADDR+10, LOADER_END auto=0 default
// THESE USE STATEMENTS HAVE TO BE AFTER THE ORG OR ELSE THE COMPILER PUTS THE
// SUBROUTINES IN APPLICATION MEMORY SPACE.
#use delay(clock=10000000)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void real_load_program (void)
{
int1 done=FALSE;
int1 gotcom;
char c;
int32 addr;
int8 i;
int8 data[16];
int buffidx;
char buffer[BUFFER_LEN_LOD];
while (!done) // Loop until the entire program is downloaded
{
// QUICK TEST FOR CHIP
// printf("ES [%lX]",getenv("FLASH_ERASE_SIZE")); // 0x40 for PIC18F258
// printf("WS [%lX]",getenv("FLASH_WRITE_SIZE")); // 0x08 for PIC18F258
putc('b');
buffidx = 0; // READ INTO THE BUFFER UNTIL ']' IS RECIEVED OR THE BUFFER IS FULL
gotcom=FALSE; // RECEIPT OF GOOD MESSAGE...
do
{
c = getc();
if( c=='[' ) // 0x5B
// START OF COMMAND
{
buffidx = 0;
}
else if( c==']' ) // 0x5D
// END OF COMMAND
{
gotcom=TRUE;
}
else if( (47<c&&c<58) || (64<c&&c<71) || c=='w' || c=='r' || c=='e' || c=='t' || c=='d' )
// UPPERCASE HEX CHARACTERS OR COMMAND CHARACTERS
{
buffer[buffidx] = c;
buffidx++;
}
} while ( !gotcom && (buffidx <= BUFFER_LEN_LOD) );
// READ 16 BYTES FROM PROGRAM EEPROM FROM ADDRESS (LAST 4 BIT OF ADDRESS NOT SENT AND ALWAYS ZERO)
// EXAMPLE COMMAND "[r0050]"
if(buffer[0] == 'r' && buffidx==5 )
{
addr=((int32)atoi_b16(&buffer[1])<<12) + ((int32)atoi_b16(&buffer[3])<<4);
read2RS232(addr, 'R' );
}// END - if(buffer[0] == 'r')
// READ 1 BYTE FROM DATA EEPROM FROM ADDRESS (FULL 8 BIT ADDRESS SENT)
// EXAMPLE COMMAND "[t50]"
else if(buffer[0] == 't' && buffidx==3 )
{
i=atoi_b16(&buffer[1]);
REPP2RS232(i, 'T' );
}// END - else if(buffer[0] == 't')
// WRITE 16 BYTES TO PROGRAM EEPROM AT ADDRESS (LAST 4 BIT OF ADDRESS NOT SENT AND ALWAYS ZERO)
// EXAMPLE COMMAND "[w0098AD6E70D6000CFFFFFFFFFFFFFFFF0000]"
// EXAMPLE COMMAND "[w0098AD6E70D6000CFFFFFFFFFFFFFFFFFFFF]"
// EXAMPLE COMMAND "[w0098FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]"
// EXAMPLE COMMAND "[w009800112233445566778899AABBCCDDEEFF]"
// EXAMPLE COMMAND "[w009800112233445566778899AABBCC11FFFF]"
// EXAMPLE COMMAND "[w009800112233445566778899AABBCC223344]"
// EXAMPLE COMMAND "[r0090]" // HERE FOR CONVIENIENCE
// EXAMPLE COMMAND "[r0091]" // HERE FOR CONVIENIENCE
// EXAMPLE COMMAND "[r0092]" // HERE FOR CONVIENIENCE
// EXAMPLE COMMAND "[w009000112233445566778899AABBCCDDEEFF]"
// EXAMPLE COMMAND "[w0091FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]"
// EXAMPLE COMMAND "[w0092FFEEDDCCBBAA99887766554433221100]"
else if(buffer[0] == 'w' && buffidx==37 )
{
addr=((int32)atoi_b16(&buffer[1])<<12) + ((int32)atoi_b16(&buffer[3])<<4);
for( i=0; i<16; i++)data[i]=atoi_b16(&buffer[(i*2)+5]);
i=atoi_b16(&buffer[3])&0x30;
if( i==0 )erase_program_eeprom(addr);
write_program_memory(addr,data,16);
read2RS232(addr, 'W' );
}// END - else if(buffer[0] == 'w')
// WRITE 1 BYTE TO DATA EEPROM AT ADDRESS (FULL 8 BIT ADDRESS SENT)
// EXAMPLE COMMAND "[e50FF]"
else if(buffer[0] == 'e' && buffidx==5 )
{
i=atoi_b16(&buffer[1]);
data[0]=atoi_b16(&buffer[3]);
write_eeprom(i,data[0]);
REPP2RS232(i, 'E' );
}// END - else if(buffer[0] == 'w')
// DONE FINISH AND RUN APPLICATION
// EXAMPLE COMMAND "[d]"
else if(buffer[0] == 'd')
{
done=TRUE;
}// END - else if(buffer[0] == 'd')
// PRINT ERROR MESSAGE
else
{
printf("Err%u<s>",buffidx,buffer);
}
}
}
// atoi_b16
// ============================================================================
// CONVERT TWO HEX CHARACTERS TO int8
unsigned int atoi_b16(char *s)
{
unsigned int result = 0;
int i;
for (i=0; i<2>= 'A') result = (result<<4) + (*s) - 'A' + 10;
else result = (result<<4) + (*s) - '0';
}
return result;
}
// read2RS232
// ============================================================================
// READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
void read2RS232( int32 a, char c )
{
int d[16];
int i;
read_program_memory(a,d,16);
printf("[%c<lX>",c,a);
for( i=0; i<16; i++)printf("%X",d[i]);
printf("]");
}
// REPP2RS232
// ============================================================================
// READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
void REPP2RS232( int a, char c )
{
int v;
v = read_eeprom(a);
printf("[%c<X>%X]",c,a,v);
}
// load_program
// ============================================================================
#ORG LOADER_ADDR, LOADER_ADDR+9
void load_program(void)
{
real_load_program();
}
// application
// ============================================================================
// THE BOOT LOADED PROGRAM WILL OVER WRITE THIS
// THIS REPEAT SENDS THE 'a' CHARACTER
// THIS NEEDS TO HAVE SOME SORT OF REBOOT COMMAND - TO GO TO BOOTLOADER
#ORG LOADER_END+2,LOADER_END+800
void application(void)
{
while(TRUE)
{
delay_ms(100);
putc('a');
if( kbhit() )
{
char c;
c = getc();
if( c==0x1B )
{
R_AND_B // RECIEVE ESCAPE
}
}
}
}
// main
// ============================================================================
// THE DECISION TO BOOTLOAD OR NOT TO BOOT LOAD GOES HERE
#ORG 0x50,0x0FF
void main(void)
{
#DEFINE DECISION_PINA4
//#DEFINE DECISION_RS232_ESC // LARGER PROGRAM!!! NEED TO MODIFY MY_BOOTLOADER.H FILE.
//#DEFINE DECISION_DATA_EEPROM
//#DEFINE DECISION_PROG_EEPROM
#IFDEF DECISION_PINA4
if(!input(PIN_A4))
{
#ENDIF
#IFDEF DECISION_RS232_ESC
char c;
int16 icount=0;
int1 bload=FALSE;
while( ++icount<10000 && !bload )
{
if( kbhit() )
{
c = getc();
if( c==0x1B )bload=TRUE;
}
}
if(bload)
{
#ENDIF
#IFDEF DECISION_DATA_EEPROM
int8 imem=0;
imem = read_eeprom(LOADER_DECISION);
if( imem!=0xFF )
{
write_eeprom(LOADER_DECISION,0xFF );
#ENDIF
#IFDEF DECISION_PROG_EEPROM
int16 imem=0;
imem = read_program_eeprom(LOADER_DECISION);
if( imem!=0xFFFF )
{
erase_program_eeprom(LOADER_DECISION);
write_program_eeprom(LOADER_DECISION,0xFFFF);
#ENDIF
load_program();
}
application();
}
// isr
// ============================================================================
// THIS INTERUPT COLLECTS ALL INTERUPTS AND MOVES THEM TO THE END + TEN
// THE LOACTION OF THE INTERUPTS FROM THE APPLICATION
#ORG default
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
The Bootloader List File
Code: |
CCS PCH C Compiler, Version 3.249, 31363 18-Jan-07 13:45
Filename: ex_bootloader.lst
ROM used: 1826 bytes (6%)
Largest free fragment is 29920
RAM used: 7 (0%) at main() level
124 (8%) worst case
Stack: 5 worst case (4 in main + 1 for interrupts)
*
0000: GOTO 0050
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// EX_BOOTLOADER.C ////
.................... //// ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2004 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS ////
.................... //// C compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, ////
.................... //// reproduction or distribution is permitted without written ////
.................... //// permission. Derivative programs created using this software ////
.................... //// in object code form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// ////
.................... //// 2006-11-29 Modified by bairds to test PIC18F258 (PCH options) ////
.................... //// 2007-01-09 Modified by bairds one file ////
.................... //// 2007-01-13 Modified by bairds to suit purpose ////
.................... //// ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #include <18F258.h>
.................... //////// Standard Header file for the PIC18F258 device ////////////////
.................... #device PIC18F258
.................... #list
....................
.................... #fuses HS,NOWDT,NOPROTECT,NOLVP
....................
.................... #define _bootloader
.................... #include </include>
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// my_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. ////
.................... //// ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2004 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS ////
.................... //// C compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, ////
.................... //// reproduction or distribution is permitted without written ////
.................... //// permission. Derivative programs created using this software ////
.................... //// in object code form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// ////
.................... //// 2006-11-29 Modified by bairds to test PIC18F258 (PCH options only)////
.................... //// 2006-01-16 Modified by bairds to match bootloader ////
.................... //// ////
.................... //// _bootloader set when compiling the bootloader (obviously realy!) ////
.................... //// ////
.................... //// THEREFORE BUILD/ORG STATEMENTS IN THIS FILE ARE COMPILED INTO THE ////
.................... //// APPLICATION. ////
.................... //// ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #DEFINE LOADER_END 0x7FF
.................... #DEFINE LOADER_SIZE 0x6FF // 0x100 LESS THAN ABOVE
....................
.................... // THE FOLLOWING TWO HASH DEFINE STATMENTS ARE REQUIRED ONLY IF USING THE
.................... // PROG_EEPROM BOOTLOADER DECISION.
.................... //
.................... // THIS USES A CHUNK OF PROGRAM MEMORY STORE BOOTLOAD/APP DECISION
.................... //
.................... // THIS REQUIRES 0x40 (64) BYTES BECAUSE OF THE ERASE_PROGRAM_EEPROM
.................... // AND ALSO SHOULD BE AT A 0x40 BOUNDARY
.................... #DEFINE LOADER_DECISION 0x00000780
.................... // SETS EPPROM LOCATIONS IN THE PROGRAM MEMORY TO ALLOW THE BOOTLOADER
.................... // TO DECIDE WHETHER TO START THE APPLICATION OR RUN THE BOOTLOADER.
.................... // THIS MUST CALLED IN THE APPLICATION SOMEWHERE OTHERWISE THE BOOTLOADER
.................... // WILL NEVER FUNCTION
.................... #DEFINE R_AND_B erase_program_eeprom(LOADER_DECISION); write_program_eeprom(LOADER_DECISION,0x0000 ); reset_cpu();
....................
.................... #IFNDEF _bootloader
....................
.................... // THIS WILL PUT THE APPLICATION RESET 4 BYTES
.................... // FOLLOWED BY FOUR BLANKS
.................... // FOLLOWED BY THE INTERUPTS
.................... #BUILD(reset=LOADER_END+1, interrupt=LOADER_END+9)
....................
.................... // NO FUNCTIONS WILL BE IN THE MEMORY RANGE 0 TO LOADER END
.................... // THEREFORE THE COMPILER WILL NOT PUT FUNCTIONS OVER THE BOOT LOADER
.................... // THIS ALLOWS THE COMPILER TO PUT THE APPLICATIONS FUNCTIONS WHERE IT LIKES
.................... #ORG 0, LOADER_END {}
....................
.................... #ENDIF
....................
....................
.................... #define LOADER_ADDR LOADER_END-LOADER_SIZE
.................... #define BUFFER_LEN_LOD 64
....................
.................... // ============================================================================
.................... // FUNCTION DECLARATIONS
.................... // ============================================================================
.................... // DO NOT INLINE THESE FUNCTION (SPACE SAVING)
....................
.................... // CONVERT TWO HEX CHARACTERS TO int8
.................... #SEPARATE
.................... unsigned int atoi_b16(char *s);
....................
.................... // READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
.................... #SEPARATE
.................... void read2RS232( int32 a, char c );
....................
.................... // READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
.................... #SEPARATE
.................... void REPP2RS232( int a, char c );
....................
....................
.................... // real_load_program
.................... // ============================================================================
.................... #ORG LOADER_ADDR+10, LOADER_END auto=0 default
.................... // THESE USE STATEMENTS HAVE TO BE AFTER THE ORG OR ELSE THE COMPILER PUTS THE
.................... // SUBROUTINES IN APPLICATION MEMORY SPACE.
.................... #use delay(clock=10000000)
*
074A: CLRF FEA
074C: MOVLW 08
074E: MOVWF FE9
0750: MOVF FEF,W
0752: BZ 0772
0754: MOVLW 03
0756: MOVWF 01
0758: CLRF 00
075A: DECFSZ 00,F
075C: BRA 075A
075E: DECFSZ 01,F
0760: BRA 0758
0762: MOVLW 3C
0764: MOVWF 00
0766: DECFSZ 00,F
0768: BRA 0766
076A: NOP
076C: NOP
076E: DECFSZ FEF,F
0770: BRA 0754
0772: RETLW 00
.................... #use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
*
011C: BTFSS F9E.5
011E: BRA 011C
0120: MOVFF FAB,06
0124: MOVFF FAE,01
0128: BTFSS 06.1
012A: BRA 0130
012C: BCF FAB.4
012E: BSF FAB.4
0130: NOP
0132: RETLW 00
.................... void real_load_program (void)
.................... {
.................... int1 done=FALSE;
*
0404: BCF 07.0
.................... int1 gotcom;
.................... char c;
.................... int32 addr;
.................... int8 i;
.................... int8 data[16];
.................... int buffidx;
.................... char buffer[BUFFER_LEN_LOD];
....................
.................... while (!done) // Loop until the entire program is downloaded
.................... {
0406: BTFSC 07.0
0408: BRA 0748
.................... // QUICK TEST FOR CHIP
.................... // printf("ES [%lX]",getenv("FLASH_ERASE_SIZE")); // 0x40 for PIC18F258
.................... // printf("WS [%lX]",getenv("FLASH_WRITE_SIZE")); // 0x08 for PIC18F258
....................
.................... putc('b');
040A: MOVLW 62
040C: BTFSS F9E.4
040E: BRA 040C
0410: MOVWF FAD
.................... buffidx = 0; // READ INTO THE BUFFER UNTIL ']' IS RECIEVED OR THE BUFFER IS FULL
0412: CLRF 1E
.................... gotcom=FALSE; // RECEIPT OF GOOD MESSAGE...
0414: BCF 07.1
.................... do
.................... {
.................... c = getc();
0416: RCALL 011C
0418: MOVFF 01,08
.................... if( c=='[' ) // 0x5B
041C: MOVF 08,W
041E: SUBLW 5B
0420: BNZ 0426
.................... // START OF COMMAND
.................... {
.................... buffidx = 0;
0422: CLRF 1E
.................... }
.................... else if( c==']' ) // 0x5D
0424: BRA 047A
0426: MOVF 08,W
0428: SUBLW 5D
042A: BNZ 0430
.................... // END OF COMMAND
.................... {
.................... gotcom=TRUE;
042C: BSF 07.1
.................... }
.................... else if( (47<c&&c<58) || (64<c&&c<71) || c=='w' || c=='r' || c=='e' || c=='t' || c=='d' )
042E: BRA 047A
0430: MOVF 08,W
0432: SUBLW 2F
0434: BC 043C
0436: MOVF 08,W
0438: SUBLW 39
043A: BC 0466
043C: MOVF 08,W
043E: SUBLW 40
0440: BC 0448
0442: MOVF 08,W
0444: SUBLW 46
0446: BC 0466
0448: MOVF 08,W
044A: SUBLW 77
044C: BZ 0466
044E: MOVF 08,W
0450: SUBLW 72
0452: BZ 0466
0454: MOVF 08,W
0456: SUBLW 65
0458: BZ 0466
045A: MOVF 08,W
045C: SUBLW 74
045E: BZ 0466
0460: MOVF 08,W
0462: SUBLW 64
0464: BNZ 047A
.................... // UPPERCASE HEX CHARACTERS OR COMMAND CHARACTERS
.................... {
.................... buffer[buffidx] = c;
0466: CLRF 03
0468: MOVF 1E,W
046A: ADDLW 1F
046C: MOVWF FE9
046E: MOVLW 00
0470: ADDWFC 03,W
0472: MOVWF FEA
0474: MOVFF 08,FEF
.................... buffidx++;
0478: INCF 1E,F
.................... }
.................... } while ( !gotcom && (buffidx <= BUFFER_LEN_LOD) );
047A: BTFSC 07.1
047C: BRA 0484
047E: MOVF 1E,W
0480: SUBLW 40
0482: BC 0416
....................
.................... // READ 16 BYTES FROM PROGRAM EEPROM FROM ADDRESS (LAST 4 BIT OF ADDRESS NOT SENT AND ALWAYS ZERO)
.................... // EXAMPLE COMMAND "[r0050]"
.................... if(buffer[0] == 'r' && buffidx==5 )
0484: MOVF 1F,W
0486: SUBLW 72
0488: BNZ 0534
048A: MOVF 1E,W
048C: SUBLW 05
048E: BNZ 0534
.................... {
.................... addr=((int32)atoi_b16(&buffer[1])<<12) + ((int32)atoi_b16(&buffer[3])<<4);
0490: CLRF x69
0492: MOVLW 20
0494: MOVWF x68
0496: RCALL 0134
0498: CLRF x62
049A: CLRF x61
049C: CLRF x60
049E: MOVFF 01,5F
04A2: CLRF x64
04A4: RLCF 01,W
04A6: MOVWF x65
04A8: RLCF x60,W
04AA: MOVWF x66
04AC: RLCF x61,W
04AE: MOVWF x67
04B0: RLCF x65,F
04B2: RLCF x66,F
04B4: RLCF x67,F
04B6: RLCF x65,F
04B8: RLCF x66,F
04BA: RLCF x67,F
04BC: RLCF x65,F
04BE: RLCF x66,F
04C0: RLCF x67,F
04C2: MOVLW F0
04C4: ANDWF x65,F
04C6: CLRF x69
04C8: MOVLW 22
04CA: MOVWF x68
04CC: RCALL 0134
04CE: CLRF x6B
04D0: CLRF x6A
04D2: CLRF x69
04D4: MOVFF 01,68
04D8: RLCF 01,W
04DA: MOVWF 00
04DC: RLCF x69,W
04DE: MOVWF 01
04E0: RLCF x6A,W
04E2: MOVWF 02
04E4: RLCF x6B,W
04E6: MOVWF 03
04E8: RLCF 00,F
04EA: RLCF 01,F
04EC: RLCF 02,F
04EE: RLCF 03,F
04F0: RLCF 00,F
04F2: RLCF 01,F
04F4: RLCF 02,F
04F6: RLCF 03,F
04F8: RLCF 00,F
04FA: RLCF 01,F
04FC: RLCF 02,F
04FE: RLCF 03,F
0500: MOVLW F0
0502: ANDWF 00,F
0504: MOVF 00,W
0506: ADDWF x64,W
0508: MOVWF 09
050A: MOVF 01,W
050C: ADDWFC x65,W
050E: MOVWF 0A
0510: MOVF 02,W
0512: ADDWFC x66,W
0514: MOVWF 0B
0516: MOVF 03,W
0518: ADDWFC x67,W
051A: MOVWF 0C
.................... read2RS232(addr, 'R' );
051C: MOVFF 0C,62
0520: MOVFF 0B,61
0524: MOVFF 0A,60
0528: MOVFF 09,5F
052C: MOVLW 52
052E: MOVWF x63
0530: RCALL 01F6
.................... }// END - if(buffer[0] == 'r')
....................
.................... // READ 1 BYTE FROM DATA EEPROM FROM ADDRESS (FULL 8 BIT ADDRESS SENT)
.................... // EXAMPLE COMMAND "[t50]"
.................... else if(buffer[0] == 't' && buffidx==3 )
0532: BRA 0746
0534: MOVF 1F,W
0536: SUBLW 74
0538: BNZ 0558
053A: MOVF 1E,W
053C: SUBLW 03
053E: BNZ 0558
.................... {
.................... i=atoi_b16(&buffer[1]);
0540: CLRF x69
0542: MOVLW 20
0544: MOVWF x68
0546: RCALL 0134
0548: MOVFF 01,0D
.................... REPP2RS232(i, 'T' );
054C: MOVFF 0D,5F
0550: MOVLW 54
0552: MOVWF x60
0554: RCALL 0296
.................... }// END - else if(buffer[0] == 't')
....................
.................... // WRITE 16 BYTES TO PROGRAM EEPROM AT ADDRESS (LAST 4 BIT OF ADDRESS NOT SENT AND ALWAYS ZERO)
.................... // EXAMPLE COMMAND "[w0098AD6E70D6000CFFFFFFFFFFFFFFFF0000]"
.................... // EXAMPLE COMMAND "[w0098AD6E70D6000CFFFFFFFFFFFFFFFFFFFF]"
.................... // EXAMPLE COMMAND "[w0098FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]"
.................... // EXAMPLE COMMAND "[w009800112233445566778899AABBCCDDEEFF]"
.................... // EXAMPLE COMMAND "[w009800112233445566778899AABBCC11FFFF]"
.................... // EXAMPLE COMMAND "[w009800112233445566778899AABBCC223344]"
.................... // EXAMPLE COMMAND "[r0090]" // HERE FOR CONVIENIENCE
.................... // EXAMPLE COMMAND "[r0091]" // HERE FOR CONVIENIENCE
.................... // EXAMPLE COMMAND "[r0092]" // HERE FOR CONVIENIENCE
.................... // EXAMPLE COMMAND "[w009000112233445566778899AABBCCDDEEFF]"
.................... // EXAMPLE COMMAND "[w0091FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF]"
.................... // EXAMPLE COMMAND "[w0092FFEEDDCCBBAA99887766554433221100]"
.................... else if(buffer[0] == 'w' && buffidx==37 )
0556: BRA 0746
0558: MOVF 1F,W
055A: SUBLW 77
055C: BTFSS FD8.2
055E: BRA 0692
0560: MOVF 1E,W
0562: SUBLW 25
0564: BTFSS FD8.2
0566: BRA 0692
.................... {
.................... addr=((int32)atoi_b16(&buffer[1])<<12) + ((int32)atoi_b16(&buffer[3])<<4);
0568: CLRF x69
056A: MOVLW 20
056C: MOVWF x68
056E: RCALL 0134
0570: CLRF x62
0572: CLRF x61
0574: CLRF x60
0576: MOVFF 01,5F
057A: CLRF x64
057C: RLCF 01,W
057E: MOVWF x65
0580: RLCF x60,W
0582: MOVWF x66
0584: RLCF x61,W
0586: MOVWF x67
0588: RLCF x65,F
058A: RLCF x66,F
058C: RLCF x67,F
058E: RLCF x65,F
0590: RLCF x66,F
0592: RLCF x67,F
0594: RLCF x65,F
0596: RLCF x66,F
0598: RLCF x67,F
059A: MOVLW F0
059C: ANDWF x65,F
059E: CLRF x69
05A0: MOVLW 22
05A2: MOVWF x68
05A4: RCALL 0134
05A6: CLRF x6B
05A8: CLRF x6A
05AA: CLRF x69
05AC: MOVFF 01,68
05B0: RLCF 01,W
05B2: MOVWF 00
05B4: RLCF x69,W
05B6: MOVWF 01
05B8: RLCF x6A,W
05BA: MOVWF 02
05BC: RLCF x6B,W
05BE: MOVWF 03
05C0: RLCF 00,F
05C2: RLCF 01,F
05C4: RLCF 02,F
05C6: RLCF 03,F
05C8: RLCF 00,F
05CA: RLCF 01,F
05CC: RLCF 02,F
05CE: RLCF 03,F
05D0: RLCF 00,F
05D2: RLCF 01,F
05D4: RLCF 02,F
05D6: RLCF 03,F
05D8: MOVLW F0
05DA: ANDWF 00,F
05DC: MOVF 00,W
05DE: ADDWF x64,W
05E0: MOVWF 09
05E2: MOVF 01,W
05E4: ADDWFC x65,W
05E6: MOVWF 0A
05E8: MOVF 02,W
05EA: ADDWFC x66,W
05EC: MOVWF 0B
05EE: MOVF 03,W
05F0: ADDWFC x67,W
05F2: MOVWF 0C
.................... for( i=0; i<16; i++)data[i]=atoi_b16(&buffer[(i*2)+5]);
05F4: CLRF 0D
05F6: MOVF 0D,W
05F8: SUBLW 0F
05FA: BNC 063A
05FC: CLRF 03
05FE: MOVF 0D,W
0600: ADDLW 0E
0602: MOVWF 01
0604: MOVLW 00
0606: ADDWFC 03,F
0608: MOVFF 01,5F
060C: MOVFF 03,60
0610: BCF FD8.0
0612: RLCF 0D,W
0614: ADDLW 05
0616: CLRF 03
0618: ADDLW 1F
061A: MOVWF x63
061C: MOVLW 00
061E: ADDWFC 03,W
0620: MOVWF x64
0622: MOVWF x69
0624: MOVFF 63,68
0628: RCALL 0134
062A: MOVFF 60,FEA
062E: MOVFF 5F,FE9
0632: MOVFF 01,FEF
0636: INCF 0D,F
0638: BRA 05F6
.................... i=atoi_b16(&buffer[3])&0x30;
063A: CLRF x69
063C: MOVLW 22
063E: MOVWF x68
0640: RCALL 0134
0642: MOVF 01,W
0644: ANDLW 30
0646: MOVWF 0D
.................... if( i==0 )erase_program_eeprom(addr);
0648: MOVF 0D,F
064A: BNZ 0662
064C: BSF FD0.6
064E: MOVFF 0B,FF8
0652: MOVFF 0A,FF7
0656: MOVFF 09,FF6
065A: BSF FA6.4
065C: BCF FA6.6
065E: RCALL 02EC
0660: CLRF FF8
.................... write_program_memory(addr,data,16);
0662: MOVFF 0B,FF8
0666: MOVFF 0A,FF7
066A: MOVFF 09,FF6
066E: CLRF FEA
0670: MOVLW 0E
0672: MOVWF FE9
0674: MOVLW 10
0676: MOVWF 5F
0678: RCALL 030C
.................... read2RS232(addr, 'W' );
067A: MOVFF 0C,62
067E: MOVFF 0B,61
0682: MOVFF 0A,60
0686: MOVFF 09,5F
068A: MOVLW 57
068C: MOVWF x63
068E: RCALL 01F6
.................... }// END - else if(buffer[0] == 'w')
....................
.................... // WRITE 1 BYTE TO DATA EEPROM AT ADDRESS (FULL 8 BIT ADDRESS SENT)
.................... // EXAMPLE COMMAND "[e50FF]"
.................... else if(buffer[0] == 'e' && buffidx==5 )
0690: BRA 0746
0692: MOVF 1F,W
0694: SUBLW 65
0696: BNZ 06EE
0698: MOVF 1E,W
069A: SUBLW 05
069C: BNZ 06EE
.................... {
.................... i=atoi_b16(&buffer[1]);
069E: CLRF x69
06A0: MOVLW 20
06A2: MOVWF x68
06A4: RCALL 0134
06A6: MOVFF 01,0D
.................... data[0]=atoi_b16(&buffer[3]);
06AA: CLRF x69
06AC: MOVLW 22
06AE: MOVWF x68
06B0: RCALL 0134
06B2: MOVFF 01,0E
.................... write_eeprom(i,data[0]);
06B6: MOVFF 0D,FA9
06BA: MOVFF 0E,FA8
06BE: BCF FA6.6
06C0: BCF FA6.7
06C2: BSF FA6.2
06C4: MOVFF FF2,00
06C8: BCF FF2.7
06CA: MOVLB F
06CC: MOVLW 55
06CE: MOVWF FA7
06D0: MOVLW AA
06D2: MOVWF FA7
06D4: BSF FA6.1
06D6: BTFSC FA6.1
06D8: BRA 06D6
06DA: BCF FA6.2
06DC: MOVF 00,W
06DE: IORWF FF2,F
.................... REPP2RS232(i, 'E' );
06E0: MOVFF 0D,5F
06E4: MOVLW 45
06E6: MOVLB 0
06E8: MOVWF x60
06EA: RCALL 0296
.................... }// END - else if(buffer[0] == 'w')
....................
.................... // DONE FINISH AND RUN APPLICATION
.................... // EXAMPLE COMMAND "[d]"
.................... else if(buffer[0] == 'd')
06EC: BRA 0746
06EE: MOVF 1F,W
06F0: SUBLW 64
06F2: BNZ 06F8
.................... {
.................... done=TRUE;
06F4: BSF 07.0
.................... }// END - else if(buffer[0] == 'd')
....................
.................... // PRINT ERROR MESSAGE
.................... else
06F6: BRA 0746
.................... {
.................... printf("Err%u<s>",buffidx,buffer);
06F8: MOVLW 45
06FA: BTFSS F9E.4
06FC: BRA 06FA
06FE: MOVWF FAD
0700: MOVLW 72
0702: BTFSS F9E.4
0704: BRA 0702
0706: MOVWF FAD
0708: MOVLW 72
070A: BTFSS F9E.4
070C: BRA 070A
070E: MOVWF FAD
0710: MOVFF 1E,5F
0714: MOVLW 1B
0716: MOVWF x60
0718: RCALL 0398
071A: MOVLW 3C
071C: BTFSS F9E.4
071E: BRA 071C
0720: MOVWF FAD
0722: CLRF FEA
0724: MOVLW 1F
0726: MOVWF FE9
0728: MOVLW 00
072A: IORWF FEF,W
072C: BZ 073E
072E: BTFSS F9E.4
0730: BRA 072E
0732: MOVFF FEF,FAD
0736: INCF FE9,F
0738: BTFSC FD8.2
073A: INCF FEA,F
073C: BRA 0728
073E: MOVLW 3E
0740: BTFSS F9E.4
0742: BRA 0740
0744: MOVWF FAD
.................... }
.................... }
0746: BRA 0406
.................... }
0748: RETLW 00
.................... // atoi_b16
.................... // ============================================================================
.................... // CONVERT TWO HEX CHARACTERS TO int8
.................... unsigned int atoi_b16(char *s)
.................... {
.................... unsigned int result = 0;
*
0134: CLRF x6A
.................... int i;
.................... for (i=0; i<2>= 'A') result = (result<<4) + (*s) - 'A' + 10;
013E: MOVFF 69,03
0142: MOVFF 68,FE9
0146: MOVFF 69,FEA
014A: MOVF FEF,W
014C: SUBLW 40
014E: BC 016C
0150: SWAPF x6A,W
0152: MOVWF x6C
0154: MOVLW F0
0156: ANDWF x6C,F
0158: MOVFF 68,FE9
015C: MOVFF 69,FEA
0160: MOVF FEF,W
0162: ADDWF x6C,W
0164: ADDLW BF
0166: ADDLW 0A
0168: MOVWF x6A
.................... else result = (result<<4) + (*s) - '0';
016A: BRA 0184
016C: SWAPF x6A,W
016E: MOVWF x6C
0170: MOVLW F0
0172: ANDWF x6C,F
0174: MOVFF 68,FE9
0178: MOVFF 69,FEA
017C: MOVF FEF,W
017E: ADDWF x6C,W
0180: ADDLW D0
0182: MOVWF x6A
.................... }
0184: MOVF x6B,W
0186: INCF x6B,F
0188: INCF x68,F
018A: BTFSC FD8.2
018C: INCF x69,F
018E: BRA 0138
.................... return result;
0190: MOVFF 6A,01
.................... }
0194: RETLW 00
.................... // read2RS232
.................... // ============================================================================
.................... // READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
.................... void read2RS232( int32 a, char c )
.................... {
.................... int d[16];
.................... int i;
.................... read_program_memory(a,d,16);
*
01F6: MOVFF 61,FF8
01FA: MOVFF 60,FF7
01FE: MOVFF 5F,FF6
0202: CLRF FEA
0204: MOVLW 64
0206: MOVWF FE9
0208: CLRF x76
020A: MOVLW 10
020C: MOVWF x75
020E: RCALL 0196
.................... printf("[%c<lX>",c,a);
0210: MOVLW 5B
0212: BTFSS F9E.4
0214: BRA 0212
0216: MOVWF FAD
0218: MOVF x63,W
021A: BTFSS F9E.4
021C: BRA 021A
021E: MOVWF FAD
0220: MOVLW 3C
0222: BTFSS F9E.4
0224: BRA 0222
0226: MOVWF FAD
0228: MOVFF 62,76
022C: MOVLW 37
022E: MOVWF x77
0230: RCALL 01B4
0232: MOVFF 61,76
0236: MOVLW 37
0238: MOVWF x77
023A: RCALL 01B4
023C: MOVFF 60,76
0240: MOVLW 37
0242: MOVWF x77
0244: RCALL 01B4
0246: MOVFF 5F,76
024A: MOVLW 37
024C: MOVWF x77
024E: RCALL 01B4
0250: MOVLW 3E
0252: BTFSS F9E.4
0254: BRA 0252
0256: MOVWF FAD
.................... for( i=0; i<16; i++)printf("%X",d[i]);
0258: CLRF x74
025A: MOVF x74,W
025C: SUBLW 0F
025E: BNC 0280
0260: CLRF 03
0262: MOVF x74,W
0264: ADDLW 64
0266: MOVWF FE9
0268: MOVLW 00
026A: ADDWFC 03,W
026C: MOVWF FEA
026E: MOVFF FEF,75
0272: MOVFF 75,76
0276: MOVLW 37
0278: MOVWF x77
027A: RCALL 01B4
027C: INCF x74,F
027E: BRA 025A
.................... printf("]");
0280: CLRF x75
0282: MOVF x75,W
0284: RCALL 010A
0286: IORLW 00
0288: BZ 0294
028A: INCF x75,F
028C: BTFSS F9E.4
028E: BRA 028C
0290: MOVWF FAD
0292: BRA 0282
.................... }
0294: RETLW 00
.................... // REPP2RS232
.................... // ============================================================================
.................... // READ PROGRAM EEPROM AND OUTPUT TO RS232 PORT
.................... void REPP2RS232( int a, char c )
.................... {
.................... int v;
.................... v = read_eeprom(a);
0296: MOVFF FF2,62
029A: BCF FF2.7
029C: MOVFF 5F,FA9
02A0: BCF FA6.6
02A2: BCF FA6.7
02A4: BSF FA6.0
02A6: MOVF FA8,W
02A8: BTFSC x62.7
02AA: BSF FF2.7
02AC: MOVWF x61
.................... printf("[%c<X>%X]",c,a,v);
02AE: MOVLW 5B
02B0: BTFSS F9E.4
02B2: BRA 02B0
02B4: MOVWF FAD
02B6: MOVF x60,W
02B8: BTFSS F9E.4
02BA: BRA 02B8
02BC: MOVWF FAD
02BE: MOVLW 3C
02C0: BTFSS F9E.4
02C2: BRA 02C0
02C4: MOVWF FAD
02C6: MOVFF 5F,76
02CA: MOVLW 37
02CC: MOVWF x77
02CE: RCALL 01B4
02D0: MOVLW 3E
02D2: BTFSS F9E.4
02D4: BRA 02D2
02D6: MOVWF FAD
02D8: MOVFF 61,76
02DC: MOVLW 37
02DE: MOVWF x77
02E0: RCALL 01B4
02E2: MOVLW 5D
02E4: BTFSS F9E.4
02E6: BRA 02E4
02E8: MOVWF FAD
.................... }
02EA: RETLW 00
....................
.................... // load_program
.................... // ============================================================================
.................... #ORG LOADER_ADDR, LOADER_ADDR+9
.................... void load_program(void)
.................... {
.................... real_load_program();
*
0100: RCALL 0404
.................... }
0102: RETLW 00
....................
.................... // application
.................... // ============================================================================
.................... // THE BOOT LOADED PROGRAM WILL OVER WRITE THIS
.................... // THIS REPEAT SENDS THE 'a' CHARACTER
.................... // THIS NEEDS TO HAVE SOME SORT OF REBOOT COMMAND - TO GO TO BOOTLOADER
.................... #ORG LOADER_END+2,LOADER_END+800
.................... void application(void)
.................... {
.................... while(TRUE)
.................... {
.................... delay_ms(100);
*
0816: MOVLW 64
0818: MOVWF 08
081A: RCALL 074A
.................... putc('a');
081C: MOVLW 61
081E: BTFSS F9E.4
0820: BRA 081E
0822: MOVWF FAD
.................... if( kbhit() )
0824: BTFSS F9E.5
0826: BRA 086C
.................... {
.................... char c;
.................... c = getc();
0828: RCALL 011C
082A: MOVFF 01,07
.................... if( c==0x1B )
082E: MOVF 07,W
0830: SUBLW 1B
0832: BNZ 086C
.................... {
.................... R_AND_B // RECIEVE ESCAPE
0834: BSF FD0.6
0836: CLRF FF8
0838: MOVLW 07
083A: MOVWF FF7
083C: MOVLW 80
083E: MOVWF FF6
0840: BSF FA6.4
0842: BCF FA6.6
0844: RCALL 02EC
0846: CLRF FF8
0848: BSF FD0.6
084A: CLRF FF8
084C: MOVLW 07
084E: MOVWF FF7
0850: MOVLW 80
0852: MOVWF FF6
0854: RCALL 0800
0856: MOVLW 80
0858: MOVWF FF6
085A: CLRF FF5
085C: TBLWT*+
085E: CLRF FF5
0860: TBLWT*
0862: BCF FA6.6
0864: RCALL 02EC
0866: CLRF FF8
0868: CLRF FF8
086A: RESET
.................... }
.................... }
.................... }
086C: BRA 0816
.................... }
086E: RETLW 00
.................... // main
.................... // ============================================================================
.................... // THE DECISION TO BOOTLOAD OR NOT TO BOOT LOAD GOES HERE
.................... #ORG 0x50,0x0FF
.................... void main(void)
.................... {
*
0050: CLRF FF8
0052: BCF FD0.7
0054: CLRF FEA
0056: CLRF FE9
0058: MOVLW 03
005A: MOVWF FAF
005C: MOVLW 22
005E: MOVWF FAC
0060: MOVLW 90
0062: MOVWF FAB
0064: BSF FC1.0
0066: BSF FC1.1
0068: BSF FC1.2
006A: BCF FC1.3
006C: CLRF 06
.................... #DEFINE DECISION_PINA4
.................... //#DEFINE DECISION_RS232_ESC // LARGER PROGRAM!!! NEED TO MODIFY MY_BOOTLOADER.H FILE.
.................... //#DEFINE DECISION_DATA_EEPROM
.................... //#DEFINE DECISION_PROG_EEPROM
....................
.................... #IFDEF DECISION_PINA4
.................... if(!input(PIN_A4))
006E: BSF F92.4
0070: BTFSC F80.4
0072: BRA 0076
.................... {
.................... #ENDIF
.................... #IFDEF DECISION_RS232_ESC
.................... char c;
.................... int16 icount=0;
.................... int1 bload=FALSE;
.................... while( ++icount<10000 && !bload )
.................... {
.................... if( kbhit() )
.................... {
.................... c = getc();
.................... if( c==0x1B )bload=TRUE;
.................... }
.................... }
.................... if(bload)
.................... {
.................... #ENDIF
.................... #IFDEF DECISION_DATA_EEPROM
.................... int8 imem=0;
.................... imem = read_eeprom(LOADER_DECISION);
.................... if( imem!=0xFF )
.................... {
.................... write_eeprom(LOADER_DECISION,0xFF );
.................... #ENDIF
.................... #IFDEF DECISION_PROG_EEPROM
.................... int16 imem=0;
.................... imem = read_program_eeprom(LOADER_DECISION);
.................... if( imem!=0xFFFF )
.................... {
.................... erase_program_eeprom(LOADER_DECISION);
.................... write_program_eeprom(LOADER_DECISION,0xFFFF);
.................... #ENDIF
.................... load_program();
0074: RCALL 0100
.................... }
.................... application();
0076: RCALL 0816
.................... }
.................... // isr
.................... // ============================================================================
.................... // THIS INTERUPT COLLECTS ALL INTERUPTS AND MOVES THEM TO THE END + TEN
.................... // THE LOACTION OF THE INTERUPTS FROM THE APPLICATION
.................... #ORG default
.................... #int_global
0078: SLEEP
.................... void isr(void) {
.................... jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
*
0008: GOTO 0808
000C: NOP
000E: NOP
0010: NOP
0012: NOP
0014: NOP
0016: NOP
0018: GOTO 0818
.................... }
001C: RETFIE 0
Configuration Fuses:
Word 1: 2200 HS NOOSCSEN
Word 2: 0E0F BROWNOUT WDT128 NOWDT BORV20 NOPUT
Word 3: 0000
Word 4: 0081 STVREN NODEBUG NOLVP
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: E00F NOWRT NOWRTD NOWRTB NOWRTC
Word 7: 400F NOEBTR NOEBTRB
|
What am I missing?
Thanks Scott
Edit: preface added to make the thread readable...
Last edited by ferrumvir on Sun Jan 21, 2007 4:11 pm; edited 1 time in total |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Thu Jan 18, 2007 8:49 am |
|
|
Also,
I can't find any reference to "jump_to_isr" in the manual at all!
I've got PCB, PCM, PCH version 3.249
Cheers Scott |
|
|
Ttelmah Guest
|
|
Posted: Thu Jan 18, 2007 4:02 pm |
|
|
It is identical to a normal address jump. Undocumented, but used in the examples...
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Thu Jan 18, 2007 6:32 pm |
|
|
Quote: | I'm a little unsure of this section of code, used unchanged from loader.c
Code:
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
the code in bootloader.c different
Code:
void isr(void) {
#asm
goto LOADER_END+9
goto LOADER_END+9
goto LOADER_END+9
goto LOADER_END+9
goto LOADER_END+0x19
#endasm
}
I think they are trying to do the same thing? Which is better/correct? | The best way to know the differences is to compile them both and compare the list files.
I didn't notice the jump_to_isr() function before so I investigated it and it turns out to be a smart tricky bastard function.
On a PIC18 it compiles to Code: | .................... jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
*
0008: GOTO 0408 // LOADER_END+0x09
000C: NOP
000E: NOP
0010: NOP
0012: NOP
0014: NOP
0016: NOP
0018: GOTO 0418 // LOADER_END+0x19
.................... } | Notice how there are two jump instructions generated, for both the low and high priority interrupt vector. It is a correct implementation and equal to the other given example code but I didn't expect this behaviour from the function name.
Compiled on a PIC16 this same function is more tricky Code: | .................... jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
*
0004: MOVWF 7F
0005: SWAPF 03,W
0006: CLRF 03
0007: MOVWF 21
0008: MOVF 0A,W // Save PCLATH
0009: MOVWF 20
000A: CLRF 0A
000B: MOVLW 02
000C: MOVWF 0A
000D: GOTO 20B // Jump to ISR
000E: RETFIE | The PIC16 has a problem here when compared to the PIC18. At the start of an ISR all important working registers are saved for later restoration on interrupt exit. Especially the PCLATH register is important as it contains the highest 3 address bits. A chicken/egg problem: the relocated ISR will save these registers, but we can only jump to the relocated ISR after modification of these registers. That's why this smart CCS function comes in handy, it knows the working of the ISR and creates equal saving code here as in the ISR.
Conclusion: For a PIC18 you can use either of the given code examples. For a PIC16 use the jump_to_isr() function.
Knowing this difference I think we have found the problem cause in Christophe's bootloader: http://www.ccsinfo.com/forum/viewtopic.php?t=29503 |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Jan 19, 2007 2:40 am |
|
|
Thank you ckielstra, Ttelmeh and PCM Programmer,
The relocation of the interupt vector would appear to be correct, jumping from 0x08 to 0x0808 and from 0x18 to 0x0818.
However my applications (none of which work, with or without interrupts) puts non-interupt code accros this memory location. Here is the list file for the TINY application (c code in my original post).
Code: |
CCS PCH C Compiler, Version 3.249, 31363 18-Jan-07 13:39
Filename: ex_bootload.lst
ROM used: 102 bytes (0%)
Largest free fragment is 30614
RAM used: 6 (0%) at main() level
7 (0%) worst case
Stack: 1 locations
*
0800: GOTO 0832
.................... // TINY APP
....................
.................... #include <18F258.h>
.................... //////// Standard Header file for the PIC18F258 device ////////////////
.................... #device PIC18F258
.................... #list
....................
.................... #fuses HS,NOWDT,NOPROTECT,NOLVP
.................... #use delay(clock=10000000)
*
0808: CLRF FEA
080A: MOVLW 07
080C: MOVWF FE9
080E: MOVF FEF,W
0810: BZ 0830
0812: MOVLW 03
0814: MOVWF 01
0816: CLRF 00
0818: DECFSZ 00,F
081A: BRA 0818
081C: DECFSZ 01,F
081E: BRA 0816
0820: MOVLW 3C
0822: MOVWF 00
0824: DECFSZ 00,F
0826: BRA 0824
0828: NOP
082A: NOP
082C: DECFSZ FEF,F
082E: BRA 0812
0830: RETLW 00
....................
.................... //#define _bootloader
.................... #include "..\include\my_bootloader.h"
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// my_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. ////
.................... //// ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2004 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS ////
.................... //// C compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, ////
.................... //// reproduction or distribution is permitted without written ////
.................... //// permission. Derivative programs created using this software ////
.................... //// in object code form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// ////
.................... //// 2006-11-29 Modified by bairds to test PIC18F258 (PCH options only)////
.................... //// 2006-01-16 Modified by bairds to match bootloader ////
.................... //// ////
.................... //// _bootloader set when compiling the bootloader (obviously realy!) ////
.................... //// ////
.................... //// THEREFORE BUILD/ORG STATEMENTS IN THIS FILE ARE COMPILED INTO THE ////
.................... //// APPLICATION. ////
.................... //// ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #DEFINE LOADER_END 0x7FF
.................... #DEFINE LOADER_SIZE 0x6FF // 0x100 LESS THAN ABOVE
....................
.................... // THE FOLLOWING TWO HASH DEFINE STATMENTS ARE REQUIRED ONLY IF USING THE
.................... // PROG_EEPROM BOOTLOADER DECISION.
.................... //
.................... // THIS USES A CHUNK OF PROGRAM MEMORY STORE BOOTLOAD/APP DECISION
.................... //
.................... // THIS REQUIRES 0x40 (64) BYTES BECAUSE OF THE ERASE_PROGRAM_EEPROM
.................... // AND ALSO SHOULD BE AT A 0x40 BOUNDARY
.................... #DEFINE LOADER_DECISION 0x00000780
.................... // SETS EPPROM LOCATIONS IN THE PROGRAM MEMORY TO ALLOW THE BOOTLOADER
.................... // TO DECIDE WHETHER TO START THE APPLICATION OR RUN THE BOOTLOADER.
.................... // THIS MUST CALLED IN THE APPLICATION SOMEWHERE OTHERWISE THE BOOTLOADER
.................... // WILL NEVER FUNCTION
.................... #DEFINE R_AND_B erase_program_eeprom(LOADER_DECISION); write_program_eeprom(LOADER_DECISION,0x0000 ); reset_cpu();
....................
.................... #IFNDEF _bootloader
....................
.................... // THIS WILL PUT THE APPLICATION RESET 4 BYTES
.................... // FOLLOWED BY FOUR BLANKS
.................... // FOLLOWED BY THE INTERUPTS
.................... #BUILD(reset=LOADER_END+1, interrupt=LOADER_END+9)
....................
.................... // NO FUNCTIONS WILL BE IN THE MEMORY RANGE 0 TO LOADER END
.................... // THEREFORE THE COMPILER WILL NOT PUT FUNCTIONS OVER THE BOOT LOADER
.................... // THIS ALLOWS THE COMPILER TO PUT THE APPLICATIONS FUNCTIONS WHERE IT LIKES
.................... #ORG 0, LOADER_END {}
....................
.................... #ENDIF
....................
....................
.................... void main(void)
.................... {
0832: CLRF FF8
0834: BCF FD0.7
0836: CLRF FEA
0838: CLRF FE9
083A: BSF FC1.0
083C: BSF FC1.1
083E: BSF FC1.2
0840: BCF FC1.3
.................... while(true)
.................... {
.................... delay_ms(500);
0842: MOVLW 02
0844: MOVWF 06
0846: MOVLW FA
0848: MOVWF 07
084A: RCALL 0808
084C: DECFSZ 06,F
084E: BRA 0846
.................... output_high(PIN_B0) ;
0850: BCF F93.0
0852: BSF F8A.0
.................... delay_ms(500);
0854: MOVLW 02
0856: MOVWF 06
0858: MOVLW FA
085A: MOVWF 07
085C: RCALL 0808
085E: DECFSZ 06,F
0860: BRA 0858
.................... output_low(PIN_B0);
0862: BCF F93.0
0864: BCF F8A.0
.................... }
0866: BRA 0842
.................... }
0868: SLEEP
Configuration Fuses:
Word 1: 2200 HS NOOSCSEN
Word 2: 0E0F BROWNOUT WDT128 NOWDT BORV20 NOPUT
Word 3: 0000
Word 4: 0081 STVREN NODEBUG NOLVP
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: E00F NOWRT NOWRTD NOWRTB NOWRTC
Word 7: 400F NOEBTR NOEBTRB
|
This appears to put the "#use delay" instructions at this location. I know this is not an interupt vector because the 0x0808 instruction is called from the main routine.
It also occurs to me that the bootloader is not generating an interupt vector at 0x0808 but as I never plan to enable interupts (in the bootloader) this, I assume, is correct and not a problem.
Am I heading in the correct direction trying to discover why my applications don't work or is there a mistake somewhere else
Thanks for your help, and quick responses.
Scott |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Jan 19, 2007 3:27 am |
|
|
Here's some more info.
I've just compiled and both the "Tiny App" and a test application with interupts.
They both put the same intructions over the 0x0008 and 0x0018 locations when compiled for direct flashing as they put over the 0x0808 and 0x0818 locations when compiled for the bootloader (offset 0x0800, and offseting GOTOs etc.) which is correct.
So now I think maybe I'm looking in the wrong place for my problem.
Cheers Scott |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Jan 19, 2007 3:51 am |
|
|
I think there is a problem with the location of the application in the bootloader, i.e. it's not at 0x0800...
This is part of the list file, the "dummy" application is located at 0x0816 and this is what is called when the bootloader finishes and runs the application.
But this is not where the loaded application starts
The line "0854: RCALL 0800" is in this file, but nowhere in the bootloader list file can I find the instruction 0800 (the full list file is in my original post)
FYI, The R_AND_B macro is in my_bootloader.h, which is what generates this instruction.
Still puzzled , but think I'm getting closer
Code: |
.................... // application
.................... // ============================================================================
.................... // THE BOOT LOADED PROGRAM WILL OVER WRITE THIS
.................... // THIS REPEAT SENDS THE 'a' CHARACTER
.................... // THIS NEEDS TO HAVE SOME SORT OF REBOOT COMMAND - TO GO TO BOOTLOADER
.................... #ORG LOADER_END+1,LOADER_END+200
.................... void application(void)
.................... {
.................... while(TRUE)
.................... {
.................... delay_ms(100);
*
0816: MOVLW 64
0818: MOVWF 08
081A: RCALL 074A
.................... putc('a');
081C: MOVLW 61
081E: BTFSS F9E.4
0820: BRA 081E
0822: MOVWF FAD
.................... if( kbhit() )
0824: BTFSS F9E.5
0826: BRA 086C
.................... {
.................... char c;
.................... c = getc();
0828: RCALL 011C
082A: MOVFF 01,07
.................... if( c==0x1B )
082E: MOVF 07,W
0830: SUBLW 1B
0832: BNZ 086C
.................... {
.................... R_AND_B // RECIEVE ESCAPE
0834: BSF FD0.6
0836: CLRF FF8
0838: MOVLW 07
083A: MOVWF FF7
083C: MOVLW 80
083E: MOVWF FF6
0840: BSF FA6.4
0842: BCF FA6.6
0844: RCALL 02EC
0846: CLRF FF8
0848: BSF FD0.6
084A: CLRF FF8
084C: MOVLW 07
084E: MOVWF FF7
0850: MOVLW 80
0852: MOVWF FF6
0854: RCALL 0800
.................... application();
0076: RCALL 0816
|
Cheers Scott
Edit: I also meant to say that there intruction in the bootloader hex file for 0x0800? but that is generating them I don't know? |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Jan 19, 2007 10:36 am |
|
|
More info... can anyone help?
The function Write_program_EEPROM puts 14 words infront of the "dummy" application.
Here are sections frmo two list files.
Code: |
.................... #ORG LOADER_END+2,LOADER_END+200
.................... void application(void)
.................... {
.................... while(TRUE)
.................... {
.................... putc('a');
*
0816: MOVLW 61
0818: BTFSS F9E.4
081A: BRA 0818
081C: MOVWF FAD
.................... if( kbhit() )
081E: BTFSS F9E.5
0820: BRA 0866
.................... {
.................... char c;
.................... c = getc();
0822: RCALL 011C
0824: MOVFF 01,07
.................... if( c==0x1B ) // RECIEVE ESCAPE
0828: MOVF 07,W
082A: SUBLW 1B
082C: BNZ 0866
.................... {
.................... // R_AND_B MACRO COPIED IN
.................... erase_program_eeprom(LOADER_DECISION);
082E: BSF FD0.6
0830: CLRF FF8
0832: MOVLW 07
0834: MOVWF FF7
0836: MOVLW 80
0838: MOVWF FF6
083A: BSF FA6.4
083C: BCF FA6.6
083E: RCALL 02EC
0840: CLRF FF8
.................... write_program_eeprom(LOADER_DECISION,0x0000 );
0842: BSF FD0.6
0844: CLRF FF8
0846: MOVLW 07
0848: MOVWF FF7
084A: MOVLW 80
084C: MOVWF FF6
084E: RCALL 0800
0850: MOVLW 80
0852: MOVWF FF6
0854: CLRF FF5
0856: TBLWT*+
0858: CLRF FF5
085A: TBLWT*
085C: BCF FA6.6
085E: RCALL 02EC
0860: CLRF FF8
0862: CLRF FF8
.................... reset_cpu();
0864: RESET
.................... }
.................... }
.................... delay_ms(100);
0866: MOVLW 64
0868: MOVWF 08
086A: RCALL 074A
.................... }
086C: BRA 0816
.................... }
086E: RETLW 00
|
and now with the write_program_eeprom commented out.
Code: |
.................... #ORG LOADER_END+2,LOADER_END+200
.................... void application(void)
.................... {
.................... while(TRUE)
.................... {
.................... putc('a');
*
0800: MOVLW 61
0802: BTFSS F9E.4
0804: BRA 0802
0806: MOVWF FAD
.................... if( kbhit() )
0808: BTFSS F9E.5
080A: BRA 082E
.................... {
.................... char c;
.................... c = getc();
080C: RCALL 011C
080E: MOVFF 01,07
.................... if( c==0x1B ) // RECIEVE ESCAPE
0812: MOVF 07,W
0814: SUBLW 1B
0816: BNZ 082E
.................... {
.................... // R_AND_B MACRO COPIED IN
.................... erase_program_eeprom(LOADER_DECISION);
0818: BSF FD0.6
081A: CLRF FF8
081C: MOVLW 07
081E: MOVWF FF7
0820: MOVLW 80
0822: MOVWF FF6
0824: BSF FA6.4
0826: BCF FA6.6
0828: RCALL 02EC
082A: CLRF FF8
.................... // write_program_eeprom(LOADER_DECISION,0x0000 );
.................... reset_cpu();
082C: RESET
.................... }
.................... }
.................... delay_ms(100);
082E: MOVLW 64
0830: MOVWF 08
0832: RCALL 074A
.................... }
0834: BRA 0800
.................... }
0836: RETLW 00
|
These additoinal instructions are not in the list file at all? If I comment out the #nolist in the device header the list file shows the instructions are generated by "#device PIC18F258". The compiler is storing setup functions which is "lists" here should they be required.
The application still does not run, these program_eeprom fuctions are not required to run the bootloader, so have been commented out for the time being. Now, even with the application starting at 0x0800 and the bootloaded aplication starting at 0x0800 it still does not run.
Any help would be appreciated. Thanks
Cheers Scott
edit: more info on instruction generation. |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
Bootloaded program does not run |
Posted: Sat Jan 20, 2007 4:06 pm |
|
|
Hi,
Can anyone help?
I've exhausted all my knowledge on investigating why the bootloaded program does not run. Even a pointer - have you checked X would be useful. I'm at a dead end.
Thanks Scott |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
bump |
Posted: Sun Jan 21, 2007 4:13 pm |
|
|
Sorry to bump this, but I need to resolve this asap, and for that I need help!
Thanks Scott |
|
|
|
|
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
|