![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
orazio
Joined: 03 Sep 2010 Posts: 27
|
CCS BOOTLOADER in PIC18f97j60 |
Posted: Wed May 16, 2012 6:14 am |
|
|
I have installed CCS example bootloader in my PIC18f97j60. It include bootloader.h and loader.h situated in PICC\Drivers directory
This is the ex_bootloader.c
Code: |
#include <18f97j60.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=25000000)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7)
#define __PCH__
#define _bootloader
#include <bootloader.h>
#include <loader.c>
#if defined(__PCM__)
#org LOADER_END+1,LOADER_END+10
#elif defined(__PCH__)
#org LOADER_END+2,LOADER_END+20
#endif
void application(void) {
while(TRUE);
}
#if defined(__PCH__)
#org 0x40,0x7F
#else
#org 0x20,0x3F
#endif
void main(void) {
output_bit(PIN_J0,!input(PIN_B3));
if(!input(PIN_B3))
{
load_program();
}
application();
}
#ORG default
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
This is the bootloader.h
Code: |
#if defined(__PCM__)
#define LOADER_END 0x1FF
#define LOADER_SIZE 0x1BF
#elif defined(__PCH__)
#define LOADER_END 0x4FF
#define LOADER_SIZE 0x3FF
#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 {}
#endif
|
And this is the application
Code: |
#include <18f97j60.h>
#fuses HS,NOWDT,PROTECT
#use delay(clock=25000000)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7,stream=HOSTPC,parity=N,ERRORS)
#define __PCH__
#include <stdlib.h>
#include <string.h>
#include "test_seriale_rtx.h"
#include <bootloader.h>
#include <lcd_olimex.c>
void InitRs232(unsigned char p, unsigned char t){
switch (t) {
case 0:set_uart_speed(1200,HOSTPC);break;
case 1:set_uart_speed(2400,HOSTPC);break;
case 2:set_uart_speed(4800,HOSTPC);break;
case 3:set_uart_speed(9600,HOSTPC);break;
case 4:set_uart_speed(19200,HOSTPC);break;
case 5:set_uart_speed(38400,HOSTPC);break;
}
}
void Init() {
rsStateRx=0;
rsCountRx=0;
_msg =0x00;
memset(rsRxBuf,0,sizeof(rsRxBuf));
}
#int_rda
void UsartRx(){
int x;
if (kbhit(HOSTPC) ) {
rsChRx=getc(HOSTPC);
switch (rsStateRx) {
case 0:
if ((char)rsChRx=='{'||rsCountRx>20) {rsCountRx=0; }
rsRxBuf[rsCountRx++]=(char) rsChRx;
if ((char)rsChRx=='}') {rsStateRx=1;}
break;
case 1:
rsStateRx=0;
rsRxBuf[rsCountRx++]=(char)rsChRx;
rsRxBuf[rsCountRx]=0;
if (rsRxBuf[1]==64) {
rsChk=0;
for (x=0;x<rsCountRx-1;x++) rsChk+=(rsRxBuf[x]-32);
rsChk=(rsChk%95)+32;
if (rsChk==rsRxBuf[rsCountRx-1]) _msg =0x01;
} //if (RxBuf[1]==Config.Address)
rsCountRx=0;
//memset(rsRxBuf,0,sizeof(rsRxBuf));
break;
} //switch (StateRx)
}// if (kbhit(HOSTPC))
}
void MonitorAndControlManager(){
int x;
_msg =0x00;
//if (RxBuf[2]=='?'||Config.ControlMode==REMOTE) {
if ( (rsRxBuf[2]=='?') ) {
switch (rsRxBuf[2]) {
case '?':
sprintf(rsTxBuf,"ciao");
rsChk=0;for (x=0;x<strlen(rsTxBuf);x++) rsChk+=(rsTxBuf[x]-32);
rsChk=(rsChk%95)+32;
x=strlen(rsTxBuf);
rsTxBuf[x]=(unsigned char)rsChk;
rsTxBuf[x+1]=0;
for (x=0;x<strlen(rsTxBuf);x++) putc(rsTxBuf[x],HOSTPC);
while ((*TXSTA&0x02)==0);
break;
} //switch (RxBuf[2])
} //if (Chk==RxBuf[CountRx-1]&&(RxBuf[2]=='?'||Config.ControlMode==REMOTE))
//else SendAckNack('n');
memset(rsRxBuf,0,sizeof(rsRxBuf));
}
void SendAckNack(char Code)
{
int x;
unsigned int Chk;
char TxBuf[10];
TxBuf[ 0]='{';
TxBuf[ 1]=64;
TxBuf[ 2]=Code;
TxBuf[ 3]='}';
Chk=0;for (x=0;x<4;x++) Chk+=(TxBuf[x]-32);
Chk=(Chk%95)+32;
TxBuf[ 4]=(unsigned char)Chk;
TxBuf[ 5]=0;
for (x=0;x<strlen(TxBuf);x++) putc(TxBuf[x],HOSTPC);
while ((*TXSTA&0x02)==0);
}
void main() {
delay_ms(500);
lcd_init();
delay_ms(100);
lcd_init();
LCD_CLEAR();
enable_interrupts(global);
enable_interrupts(int_rda);
Init();
InitRs232(0,3); //RS-322 9600 baud
LCD_GOTOXY(1,1);
sprintf(string,"RS-232/422 Test");
LCD_PUTS(string);
LCD_GOTOXY(1,2);
sprintf(string,"Rx: ");
LCD_PUTS(string);
delay_ms(2000);
SendAckNack('t');
delay_ms(500);
while(1){
delay_ms(100);
if (_msg == 0x01) MonitorAndControlManager();
}//while
}
|
I have installed successfully the ex_bootloader.c in my PIC.
If i press button PIN_B3, after power on, i enter in bootloader and i can transfer myapp.hex using ccsbootloader.
The command line that i run is:
ccsbootloader PORT=COM1 BAUD=38400 DEBUGT=debug.txt myapp.hex
After transferring with success, I see that pic doesn't reset himself. So i reset it manually. But after that it restarts, I see that myapp.hex doesn't start. While i see that the bootloader remain installed.
In fact if I press button PIN_B3, after power on, I enter in bootloader again.
Which the problem? Why the bootloader don't install myapp.hex after transferring it?
Please can anyone help me? |
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1328
|
|
Posted: Wed May 16, 2012 7:50 am |
|
|
I am not as familiar with PIC18, but something that strikes me as confusing. You have __PCH__ defined, which means your #build statement chosen is:
Code: |
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
|
But in your bootloader ISR code you have:
Code: |
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
That doesn't seem to match in my mind. |
|
![](templates/subSilver/images/spacer.gif) |
orazio
Joined: 03 Sep 2010 Posts: 27
|
|
Posted: Wed May 16, 2012 8:32 am |
|
|
jeremiah wrote: | I am not as familiar with PIC18, but something that strikes me as confusing. You have __PCH__ defined, which means your #build statement chosen is:
Code: |
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
|
But in your bootloader ISR code you have:
Code: |
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
That doesn't seem to match in my mind. |
What do you mean?
Which should be the correct instruction about you? |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed May 16, 2012 3:15 pm |
|
|
_You_ should not be defining __PCH__. __PCH__ (and the same for PCB, PCM, and PCD), are _internal_ values automatically set according to what compiler you are using. So code can be written to have different configurations according to the compiler used. Currently your code overrides this setting, which would mean it'd select options only applicable to the PCH compiler, even if you changed compiler - not right....
The bootloader is _designed_ to 'remain installed'. Provided the code you load is written to run with a bootloader, and the trigger button is not pressed, it runs with the bootloader present. Otherwise there would be no point in having the bootloader, since you would then have to reprogram the pic with an external programmer if you wanted to change anything else. It can't delete itself, since you have to erase program memory in pages, and you'd be deleting the program that is running, if you tried to do this to the area containing the bootloader, and would crash the program. You need to include 'bootload.c' into the front of your main code before you compile it, which will then relocate it to run with the bootloader present. The bootloader is written to _not_ allow writes to where it lives.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
orazio
Joined: 03 Sep 2010 Posts: 27
|
|
Posted: Thu May 17, 2012 1:00 am |
|
|
Excuse me Ttelmah, i understood the first part of your reply.
But i don't understood the second part of your reply.
"You need to include 'bootload.c' into the front of your main code before you compile it"
Please can you explane better?
It is ok for me that "The bootloader is _designed_ to 'remain installed'." But i want to use bootloader to install my application via RS-232 amd without pic-kit2.
In my appllication, i have deleted #define __PCH__ as you said.
What is bootload.c ? In my application i already include bootloader.h
#include <bootloader.h>
Any suggestion? |
|
![](templates/subSilver/images/spacer.gif) |
orazio
Joined: 03 Sep 2010 Posts: 27
|
|
Posted: Thu May 17, 2012 1:08 am |
|
|
To be perfectly compliant with CCS Bootloader example code, situated in PICC/Example, I have used and compiled following code.
bootloader.h :
Code: |
#if defined(__PCM__)
#define LOADER_END 0x1FF
#define LOADER_SIZE 0x1BF
#elif defined(__PCH__)
#define LOADER_END 0x4FF
#define LOADER_SIZE 0x3FF
#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 {}
#endif |
ex_bootloader.c :
Code: |
#include <18f97j60.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=25000000)
#use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7)
#define _bootloader
#include <bootloader.h>
#include <loader.c>
#if defined(__PCM__)
#org LOADER_END+1,LOADER_END+10
#elif defined(__PCH__)
#org LOADER_END+2,LOADER_END+20
#endif
void application(void) {
while(TRUE);
}
#if defined(__PCH__)
#org 0x40,0x7F
#else
#org 0x20,0x3F
#endif
void main(void) {
//output_bit(PIN_J0,!input(PIN_B3));
if(!input(PIN_B3))
{
load_program();
}
application();
}
#ORG default
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
ex_bootload.c :
Code: |
#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#elif defined(__PCH__)
//#include <18F452.h>
//#fuses HS,NOWDT,NOPROTECT,NOLVP
//#use delay(clock=20000000)
#include <18f97j60.h>
#fuses HS,NOWDT,PROTECT
#use delay(clock=25000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif
#include <bootloader.h>
void main(void) {
int i=0;
printf("\r\nApplication program version 1.00 \r\n");
while(TRUE)
printf("%u ",++i);
}
|
First of all I install ex_bootloader.hex in my PIC.
After that I reset pic, press PIN_B3 button and I use ccsbootloader to transfer ex_bootload.hex (that will send a string via RS-232).
Then I reset pic, but the application ex_bootload.hex doesn't start. In fact if I open hyperterminal at 9600 baud I don't receive anything.
Please can anyone help me? |
|
![](templates/subSilver/images/spacer.gif) |
orazio
Joined: 03 Sep 2010 Posts: 27
|
|
Posted: Thu May 17, 2012 2:35 pm |
|
|
comù finiu?
I translate for you.
Anyone expert programmer in the Forum has a solution for my problem? |
|
![](templates/subSilver/images/spacer.gif) |
orazio
Joined: 03 Sep 2010 Posts: 27
|
|
Posted: Mon May 21, 2012 4:50 am |
|
|
Excuse me Ttelmah,
i have used CCS Bootloader example code (ex_bootloader.c and ex_bootload.c), situated in PICC/Example.
First of all I install ex_bootloader.hex in my PIC.
After that I reset pic, press PIN_B3 button and I use ccsbootloader to transfer ex_bootload.hex (that will send a string via RS-232).
Then I reset pic, but the application ex_bootload.hex doesn't start. In fact if I open hyperterminal at 9600 baud I don't receive anything.
Please can you help me? |
|
![](templates/subSilver/images/spacer.gif) |
WillysJeeps
Joined: 24 May 2012 Posts: 5
|
|
Posted: Thu May 24, 2012 3:44 pm |
|
|
Hi -
This seems similar to an issue I'm having.
I too am using the provided sample bootloader code that came with the PCH compiler. I too am using a slightly different PIC18 (F46K22) than the sample to try to make a go of it.
I've been able to work through the difference in the two micros (memory organization) to get it to work and compile. I don't have access to the b-port button used in the original example so I changed the way the bootloader behaves before it jumps to the application location. And that all seems to work fine for me. I can put it on the target device and see it run. I can pull the program memory back into a window and see where it falls.
So my trouble seems to be with the loader routine. And I haven't figured it out. When I send a file via the serial port, the loader grabs the first line of the passed hex file and stops. Hmm I said to myself. After some poking around and pull of my hair, I've found that the new/passed in hex file is getting written to the address starting at 0x000000. I can see that the entire first line is there.
I think I did something to the memory locations when I was adapting the code for the new PIC. If anyone had some pointers, I'd love to hear them. I have read the post PCM programmer did back in April 2011. Very nicely done. I wish I had some formal programming training to real make sense of everything he has to say.
My ROM allocation:
0008 isr
0026 @const112
0040 MAIN
0040 @cinit1
0092 @cinit2
001E @const110
0100 load_program
010A @@PUTCHARI_BIU_2
0112 atoi_b16
0174 @@FLASHWR
0194 @@WRITE_PROGRAM_MEMORY
01D6 real_load_program
0500 @const113
0512 @const114
0528 @const115
0540 @PSTRINGC_9600_31766_31767
0564 application |
|
![](templates/subSilver/images/spacer.gif) |
WillysJeeps
Joined: 24 May 2012 Posts: 5
|
|
Posted: Thu May 24, 2012 5:22 pm |
|
|
OK I don't quite understand what's happening in here. My serially transmitted app wants to be written starting at position 0x0000. I setup my hardware for debug break points and am trying to smartly step through the code in real_load_program(). When I get to
Code: | addr = make32(h_addr,l_addr); |
both h_addr and l_addr are at zero. The buffer[] is full of the first line of the file. I don't understand how these x_addr vars would be initially positioned at the offset of where I want to write my (new) application.
Anyone have some insight? |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|