|
|
View previous topic :: View next topic |
Author |
Message |
surfer0815
Joined: 10 Sep 2010 Posts: 7 Location: Germany
|
18f8722 Bootloader RAM array Issues |
Posted: Sun Apr 17, 2011 3:12 am |
|
|
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: 19554
|
|
Posted: Sun Apr 17, 2011 8:17 am |
|
|
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
|
|
Posted: Tue Apr 19, 2011 5:19 am |
|
|
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! |
|
|
|
|
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
|