|
|
View previous topic :: View next topic |
Author |
Message |
saeed
Joined: 07 Mar 2017 Posts: 10
|
bootloader problem |
Posted: Thu May 25, 2017 2:16 am |
|
|
Hi
I'm playing with ccs bootloader example and i can run it with pic16f887 in proteus but the example doesn't work with pic18f45k22.
I use SIOW.exe to load ex_bootload.hex into mcu and in both mcus i can load the file but after loading,the ex_bootload works fine in pic16f887 but in pic18f45k22, proteus messages "stack overflow is forcing device reset" and the message refers to isr routine.
I searched the forums but i can't find a proper answer.
ccs: 5.049
Thanks in advance
ex_bootloader.c
Code: |
#if defined(__PCM__)
#include <16F887.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#define PUSH_BUTTON PIN_A0
#elif defined(__PCH__)
#include <18F45K22.h>
#fuses NOWDT
#use delay(crystal=16MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,errors)
#define PUSH_BUTTON PIN_A0
#endif
#define _bootloader
//#define BOOTLOADER_MODE2X
#include <bootloader.h>
#include <loader.c>
#if defined(__PCM__)
#org LOADER_END+1,LOADER_END+2
#elif defined(__PCH__)
#org LOADER_END+2,LOADER_END+4
#endif
void application(void) {
while(TRUE);
}
void main(void) {
if(!input(PUSH_BUTTON))
{
printf("\r\nBootloader Version 1.0\r\n");
// Let the user know it is ready to accept a download
printf("\r\nWaiting for download...");
load_program();
}
application();
}
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
bootloader.h
Code: |
#ifndef __BOOTLOADER_H__
#define __BOOTLOADER_H__
#ifndef LOADER_END
#if defined(__PCM__)
#ifdef BOOTLOADER_MODE2X
#define LOADER_END 0x4BF
#else
#define LOADER_END 0x33F
#endif
#elif defined(__PCH__)
#define FLASH_SIZE getenv("FLASH_ERASE_SIZE")
#if ((0x500 % FLASH_SIZE) == 0) //IF 0x500 is even flash boundary
#define LOADER_END 0x4FF
#else //ELSE, goto next even boundary
#define LOADER_END ((0x500+FLASH_SIZE-(0x500 % FLASH_SIZE))-1)
#endif
#else
#error Bootloader only works with PCM or PCH compiler
#endif
#endif
#define LOADER_SIZE LOADER_END
#ifndef BOOTLOADER_AT_START
#define BOOTLOADER_AT_START
#endif
#ifndef _bootloader
#if defined(__PCM__)
#build(reset=LOADER_END+1, interrupt=LOADER_END+5)
#elif defined(__PCH__)
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
#endif
#org 0, LOADER_END {}
#else
#ifdef __PCM__
#if getenv("PROGRAM_MEMORY") <= 0x800
#org LOADER_END+3, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org LOADER_END+3, 0x7FF {}
#if getenv("PROGRAM_MEMORY") <= 0x1000
#org 0x800, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org 0x800, 0xFFF{}
#if getenv("PROGRAM_MEMORY") <= 0x1800
#org 0x1000, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org 0x1000, 0x17FF {}
#if getenv("PROGRAM_MEMORY") <= 0x2000
#org 0x1800, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org 0x1800, 0x1FFF {}
#if getenv("PROGRAM_MEMORY") <= 0x2800
#org 0x2000, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org 0x2000, 0x27FF {}
#if getenv("PROGRAM_MEMORY") <= 0x3000
#org 0x2800, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org 0x2800, 0x2FFF {}
#if getenv("PROGRAM_MEMORY") <= 0x3800
#org 0x3000, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org 0x3000, 0x37FF {}
#org 0x3800, 0x3FFF {}
#endif
#endif
#endif
#endif
#endif
#endif
#endif
#else
#if getenv("PROGRAM_MEMORY") <= 0x10000
#org LOADER_END+5, (getenv("PROGRAM_MEMORY") - 1) {}
#else
#org LOADER_END+5, 0xFFFE {}
#org 0x10000, (getenv("PROGRAM_MEMORY") - 1) {}
#endif
#endif
#endif
#endif
|
ex_bootload.c
Code: |
#if defined(__PCM__)
#include <16F887.h>
#fuses NOWDT
#use delay(crystal=20MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#elif defined(__PCH__)
#include <18F45K22.h>
#fuses NOWDT
#use delay(crystal=16MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif
#include <bootloader.h>
void main(void)
{
int8 i;
delay_ms(100);
printf("\r\nApplication Version 1.0\r\n");
while(TRUE)
printf("%3u ",++i);
}
|
loader.c
Code: |
#ifndef LOADER_END
#define LOADER_END getenv("PROGRAM_MEMORY")-1
#if defined(__PCM__)
#define LOADER_SIZE 0x27F
#elif defined(__PCH__)
#if (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")) == 0
#define LOADER_SIZE 0x3FF
#else
#define LOADER_SIZE (getenv("PROGRAM_MEMORY") % (getenv("FLASH_ERASE_SIZE")) - 1)
#endif
#endif
#endif
#define LOADER_ADDR LOADER_END-LOADER_SIZE
#ifndef BOOTLOADER_AT_START
#ORG LOADER_ADDR+4, LOADER_END auto=0 default
#endif
#ifndef BUFFER_LEN_LOD
#define BUFFER_LEN_LOD 64
#endif
#ifdef BOOTLOADER_MODE2X
#define BUFFER_COUNT 2
#else
#define BUFFER_COUNT 1
#endif
#if defined(__PCM__) && !getenv("ENH16") && (BUFFER_COUNT == 2)
struct
{
int8 idx;
char *buffer;
} rBuffer[BUFFER_COUNT];
char Buffer1[BUFFER_LEN_LOD];
char Buffer2[BUFFER_LEN_LOD];
#else
struct
{
int8 idx;
char buffer[BUFFER_LEN_LOD];
} rBuffer[BUFFER_COUNT];
#endif
#define ACKLOD 0x06
#define XON 0x11
#define XOFF 0x13
unsigned int atoi_b16(char *s);
#ifdef BOOTLOADER_STREAM
#define BootLoaderGetc() fgetc(BOOTLOADER_STREAM)
#define BootLoaderPutc(c) fputc(c, BOOTLOADER_STREAM)
#else
#define BootLoaderGetc() getc()
#define BootLoaderPutc(c) putc(c)
#endif
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") != getenv("FLASH_WRITE_SIZE")
int32 next_addr;
#endif
int8 dataidx, i, count;
int8 data[BUFFER_LEN_LOD / 2];
#ifdef BOOTLOADER_MODE2X
int8 buffidx;
#endif
#if defined(__PCM__) && !getenv("ENH16") && (BUFFER_COUNT == 2)
rBuffer[0].buffer = &Buffer1[0];
rBuffer[1].buffer = &Buffer2[0];
#endif
#ifdef BOOTLOADER_MODE2X
buffidx = 0;
while (!done) // Loop until the entire program is downloaded
{
rBuffer[buffidx].idx = 0; // Read into the buffer until 0x0D ('\r') is received or the buffer is full
do {
rBuffer[buffidx].buffer[rBuffer[buffidx].idx] = BootLoaderGetc();
} while ((rBuffer[buffidx].buffer[rBuffer[buffidx].idx++] != 0x0D) && (rBuffer[buffidx].idx <= BUFFER_LEN_LOD));
if(++buffidx >= BUFFER_COUNT)
{
#else
while (!done) // Loop until the entire program is downloaded
{
rBuffer[0].idx = 0;
do {
rBuffer[0].buffer[rBuffer[0].idx] = BootLoaderGetc();
} while ((rBuffer[0].buffer[rBuffer[0].idx++] != 0x0D) && (rBuffer[0].idx <= BUFFER_LEN_LOD));
#endif
BootLoaderPutc(XOFF); // Suspend sender
do_ACKLOD = TRUE;
#ifdef BOOTLOADER_MODE2X
if(rBuffer[0].idx != rBuffer[1].idx)
do_ACKLOD = FALSE;
else
{
for(i=0;i<(rBuffer[0].idx-1);i++)
{
if(rBuffer[0].buffer[i] != rBuffer[1].buffer[i])
{
do_ACKLOD = FALSE;
break;
}
}
if(do_ACKLOD)
{
#endif
// Only process data blocks that start with ':'
if (rBuffer[0].buffer[0] == ':')
{
count = atoi_b16 (&rBuffer[0].buffer[1]); // Get the number of bytes from the buffer
// Get the lower 16 bits of address
l_addr = make16(atoi_b16(&rBuffer[0].buffer[3]),atoi_b16(&rBuffer[0].buffer[5]));
line_type = atoi_b16 (&rBuffer[0].buffer[7]);
addr = make32(h_addr,l_addr);
#if defined(__PCM__) // PIC16 uses word addresses
addr /= 2;
#endif
checksum = 0; // Sum the bytes to find the check sum value
for (i=1; i<(rBuffer[0].idx-3); i+=2)
checksum += atoi_b16 (&rBuffer[0].buffer[i]);
checksum = 0xFF - checksum + 1;
if (checksum != atoi_b16 (&rBuffer[0].buffer[rBuffer[0].idx-3]))
do_ACKLOD = FALSE;
else
{
// If the line type is 1, then data is done being sent
if (line_type == 1)
done = TRUE;
else if (line_type == 4)
h_addr = make16(atoi_b16(&rBuffer[0].buffer[9]), atoi_b16(&rBuffer[0].buffer[11]));
else if (line_type == 0)
{
if ((addr < LOADER_ADDR || addr > LOADER_END) && addr < getenv("PROGRAM_MEMORY"))
{
// 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 < rBuffer[0].idx-3; i += 2)
data[dataidx++]=atoi_b16(&rBuffer[0].buffer[i]);
#if getenv("FLASH_ERASE_SIZE") > getenv("FLASH_WRITE_SIZE")
if ((addr!=next_addr) && (addr > (next_addr + (getenv("FLASH_ERASE_SIZE") - (next_addr % getenv("FLASH_ERASE_SIZE"))))) && ((addr & (getenv("FLASH_ERASE_SIZE")-1)) != 0))
{
#if defined(__PCH__) && defined(BOOTLOADER_AT_START)
#if ((getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")) != 0)
if (addr > (getenv("PROGRAM_MEMORY") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE"))))
{
read_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
erase_program_eeprom(addr);
write_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
}
else
#endif
#endif
erase_program_eeprom(addr);
}
#if defined(__PCM__)
next_addr = addr + count/2;
#else
next_addr = addr + count;
#endif
#endif
#if defined(__PCH__) && defined(BOOTLOADER_AT_START)
#if ((getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")) != 0)
if (addr == (getenv("PROGRAM_MEMORY") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE"))))
{
read_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
write_program_memory(addr, data, count);
write_program_memory(getenv("PROGRAM_MEMORY"), rBuffer[0].buffer, getenv("FLASH_ERASE_SIZE") - (getenv("PROGRAM_MEMORY") % getenv("FLASH_ERASE_SIZE")));
}
else
#endif
#endif
write_program_memory(addr, data, count);
}
}
}
}
#ifdef BOOTLOADER_MODE2X
}
}
buffidx = 0;
#endif
if (do_ACKLOD)
BootLoaderPutc(ACKLOD);
BootLoaderPutc(XON);
#ifdef BOOTLOADER_MODE2X
}
#endif
}
BootLoaderPutc(ACKLOD);
BootLoaderPutc(XON);
reset_cpu();
}
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);
}
#ifndef BOOTLOADER_AT_START
#ORG default
#ORG LOADER_ADDR, LOADER_ADDR+3
#endif
void load_program(void)
{
real_load_program();
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu May 25, 2017 4:53 am |
|
|
Well I can see a couple of things (#1 Proteus is BUSTED) but it's a real 'challenge' to decode your code. I'm 'old school' and don't like a lot of conditionals (if-then-elses) based on compiler or PIC type. I prefer 'clean' code, cut for ONE PIC not 2 or 3.
Since you're only using two PICs, have two separate projects and eliminate the mess of the if-then-elses.
It's very easy to have one too many or wrongly placed brace and while the code 'looks' OK, it's actually wrong.
Maybe others (younger ?) are OK with the flow but my old eyes get sore easily these days.
Jay |
|
|
saeed
Joined: 07 Mar 2017 Posts: 10
|
|
Posted: Thu May 25, 2017 5:36 am |
|
|
temtronic wrote: | Well I can see a couple of things (#1 Proteus is BUSTED) but it's a real 'challenge' to decode your code. I'm 'old school' and don't like a lot of conditionals (if-then-elses) based on compiler or PIC type. I prefer 'clean' code, cut for ONE PIC not 2 or 3.
Since you're only using two PICs, have two separate projects and eliminate the mess of the if-then-elses.
It's very easy to have one too many or wrongly placed brace and while the code 'looks' OK, it's actually wrong.
Maybe others (younger ?) are OK with the flow but my old eyes get sore easily these days.
Jay |
It's not my code!
It's CCS example for bootloader
|
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Thu May 25, 2017 6:15 am |
|
|
saeed wrote: | It's not my code!
It's CCS example for bootloader
|
You're not supposed to post the CCS examples or drivers. |
|
|
saeed
Joined: 07 Mar 2017 Posts: 10
|
|
Posted: Thu May 25, 2017 6:45 am |
|
|
newguy wrote: | saeed wrote: | It's not my code!
It's CCS example for bootloader
|
You're not supposed to post the CCS examples or drivers. |
Thats right but i send the full code to show that it works with pic16f887 and doesn't have any problem. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Thu May 25, 2017 6:45 am |
|
|
If it's 100% CCS code, then that confirms Proteus is BUSTED !! |
|
|
Oreminclutch
Joined: 31 May 2017 Posts: 2
|
|
Posted: Wed May 31, 2017 6:56 am |
|
|
If it's an example code and it's not working then you know what the problem is. Especially if it's working for something else.
Proteus sucks
top 3 best roulette chat sites |
|
|
|
|
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
|