CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Relocate code of 18f4620 without bootloader

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
gudurix



Joined: 16 Jul 2014
Posts: 4

View user's profile Send private message

Relocate code of 18f4620 without bootloader
PostPosted: Tue Jul 22, 2014 2:08 am     Reply with quote

Hi there:

I have a CCS code with a PIC 18F4620. It is working fine, with no problems. It's a medium size code to control a PCB : IO, RS232 communication, and different devices connected to the PCB. It handle two interrupts in the following way
Code:

[i]#include "18F4620.h"
#include <stdlib.h>
#include <Variables&Constantes.h>

#fuses HS,NOWDT, WDT256,PROTECT,NOLVP,                                                                 
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads                                                                                               
#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#priority int_ext

#int_ext
void intext() {
..................................................
}

#int_TIMER0
void TIMER0_isr(void) {
.................................   
}
void function1(void){
......
}
....
...
void functionN(void){
.....
}

void main{
.....

}
[/i]


And lot of code for several functions, and also the main code.
Now I want to relocate my code in order to load a bootloader, as many other people do, as i can see searching for the forum.

My first try was to relocate just my code, without bootloader, so I can see if my relocated code will work.

First, i relocate only the code, keeping my reset vector and my interrupts in the original position, so the code looks like:
Code:

[i]
#include "18F4620.h"
#include <stdlib.h>
#include <Variables&Constantes.h>

#fuses HS,NOWDT, WDT256,PROTECT,NOLVP,                                                                 
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads                                                                                               
[b]#org 0xaaaa, 0xffff default[/b]

#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#priority int_ext

#int_ext
void intext() {
..................................................
}

#int_TIMER0
void TIMER0_isr(void) {
.................................   
}
void function1(void){
......
}
....
...
void functionN(void){
.....
}

void main{
.....

}
[b]#org default[/b]

[/i]


As a first try, it worked fine. I can see my code has been relocated, and looking at the program memory I can see the behaviour of the program location has been the one I expected.

Now I just want to move reset and interrupt vectors to 0x800 and 0x808:0x818
Code:

[i]
#include "18F4620.h"
#include <stdlib.h>
#include <Variables&Constantes.h>

#fuses HS,NOWDT, WDT256,PROTECT,NOLVP,                                                                 
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads                                                                                               
[b]#build (reset =0x800, interrupt=0x808:0x818)[/b]
[b]#org 0xaaaa, 0xffff default[/b]

#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#priority int_ext

#int_ext
void intext() {
[b]jump_to_isr(0x0808);[/b]

..................................................
}

#int_TIMER0
void TIMER0_isr(void) {
[b]jump_to_isr(0x0818);[/b]
.................................   
}
void function1(void){
......
}
....
...
void functionN(void){
.....
}

void main{
.....

}
[b]#org default[/b]
[/i]
Doing this, the program never works. I can see looking at program memory that the interrupt code start at 0x808, BUT there is a lot of code also in positions 0x000 to 0x1E4(where is not expected to be any code). Also, I guess there should be a goto 0x800 in 0x0000 position, but there is not.

I have tried to protect this part of the memory with an org 0x0000, 0x7ff. Program memory looks better (despite I have not a goto 0x800 also) but the program is not working yet.

My guess is that there has not supposed to be any code in the first positions of the program memory, and also there should be some goto at 0 position, but I can not figure out what I'm doing wrong

I have been Reading all kind of post about "bootloader" "#build" "remmaping interrupt" but I'm unable to find the problem. I have really looked a lot of post, and tried some things but I can not detect what is happening here, so I´d like to ask if anyone has any suggestion to solve my problema. Probably is more a concept problem than any other thing, but I can clear myself

Best regards and thank in advance


Last edited by gudurix on Tue Jul 22, 2014 4:21 am; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19470

View user's profile Send private message

PostPosted: Tue Jul 22, 2014 3:35 am     Reply with quote

#BUILD relocates everything.
Your interrupt code is already at address 0x808 after the build, so the INT_EXT is never going to work, since it will jump back to 0x808, after being called by the code at 0x808. The same applies to int_timer0. Permanent loops....

Look at the examples. It is the bootloader code that needs to do the jumps to the ISR, not the code in your normal routines. These want to be exactly the same as they were before the code relocated.

You don't want the second address with the interrupt setting in #build. _both_ interrupt vectors are automatically moved when the instruction is used. You are telling it to put all the interrupt code in the segment between 0x808, and 0x818. It won't fit....

The loops are why the code won't work.

So:
Code:

#include "18F4620.h"
#include <stdlib.h>
#include <Variables&Constantes.h>

#fuses HS,NOWDT, WDT256,PROTECT,NOLVP,
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=8000000)
#build(RESET=0x800, INTERRUPT=0x808)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#priority int_ext

#int_ext
void intext() {
..................................................
}

#int_TIMER0
void TIMER0_isr(void) {
.................................
}
void function1(void){
......
}
....
...
void functionN(void){
.....
}

void main{
.....

}


Is all that is needed for the main code.
You don't need the #ORG, the compiler will place everything above the 0x800 address. If you want to force the main code to 0xAAAA you can, but it isn't needed....

Then the bootloader needs to contain:
Code:

#int_global
void isr(void) {
   jump_to_isr(0x808);
}


Added to it's code. This automatically generates the jumps at 0x8 to 0x808, and 0x18 to 0x818.

Look at the listing, if you compile with this in the bootloader:
Code:

....................    jump_to_isr(0x808);
*
0008:  GOTO   0808
000C:  NOP   
000E:  NOP   
0010:  NOP   
0012:  NOP   
0014:  NOP   
0016:  NOP   
0018:  GOTO   0818
001C:  RETFIE 0

See how it has generated a jump at address 8, to 808, and at 18 to 818.

It is the bootloader's responsibility to generate this.
gudurix



Joined: 16 Jul 2014
Posts: 4

View user's profile Send private message

PostPosted: Tue Jul 22, 2014 3:56 am     Reply with quote

Thanks Ttelmah:

I have just tried EXACTLY what you suggest but without the bootloader part, just to see how it works

In this case, should the code work just with the build stament?

I just have try what you sugest( just using the build stament and without bootloader) to see if my main program Works, and it's still not working.

I have seen also that there is also a lot of code betwen position 0x0000 and 0x07FC

Code:
     1014           07EA           F001                          NOP           
               1015           07EC           A270                          BTFSS 0x70, 1, ACCESS
               1016           07EE           D002                          BRA 0x7F4     
               1017           07F0           98AB                          BCF RCSTA, 4, ACCESS
               1018           07F2           88AB                          BSF RCSTA, 4, ACCESS
               1019           07F4           0012                          RETURN 0       
               1020           07F6           A89E                          BTFSS PIR1, 4, ACCESS
               1021           07F8           D7FE                          BRA 0x7F6     
               1022           07FA           6EAD                          MOVWF TXREG, ACCESS
               1023           07FC           0012                          RETURN 0       
               1024           07FE           FFFF                          NOP           
               1025           0800           EF88                          GOTO 0x1F10   
               1026           0802           F00F                          NOP           
               1027           0804           FFFF                          NOP           
               1028           0806           FFFF                          NOP           
               1029           0808           6E04                          MOVWF 0x4, ACCESS
               1030           080A           CFD8                          MOVFF STATUS, 0x5
               1031           080C           F005                          NOP           
               1032           080E           CFE0                          MOVFF BSR, 0x6
               1033           0810           F006                          NOP           
               1034           0812           0100                          MOVLB 0x0     
               1035           0814           CFE9                          MOVFF FSR0, 0xC
               1036           0816           F00C                          NOP           
               1037           0818           CFEA                          MOVFF FSR0H, 0x7
               1038           081A           F007                          NOP           
               1039           081C           CFE1                          MOVFF FSR1, 0x8
               1040           081E           F008                          NOP           
               1041           0820           CFE2                          MOVFF FSR1H, 0x9
               1042           0822           F009                          NOP           
               1043           0824           CFD9                          MOVFF FSR2, 0xA
               1044           0826           F00A                          NOP           
               1045           0828           CFDA                          MOVFF FSR2H, 0xB
               1046           082A           F00B                          NOP           
               1047           082C           CFF3                          MOVFF PROD, 0x12
               1048           082E           F012                          NOP           
               1049           0830           CFF4                          MOVFF PRODH, 0x13
               1050           0832           F013                          NOP           
               1051           0834           CFFA                          MOVFF PCLATH, 0x14
               1052           0836           F014                          NOP           
               1053           0838           CFF5                          MOVFF TABLAT, 0x15
               1054           083A           F015                          NOP           
               1055           083C           CFF6                          MOVFF TBLPTR, 0x16
               1056           083E           F016                          NOP           
               1057           0840           CFF7                          MOVFF TBLPTRH, 0x17
               1058           0842           F017                          NOP           
               1059           0844           C000                          MOVFF 0x0, 0xE
               1060           0846           F00E                          NOP           
               1061           0848           C001                          MOVFF 0x1, 0xF
               1062           084A           F00F                          NOP           
               1063           084C           C002                          MOVFF 0x2, 0x10
               1064           084E           F010                          NOP           


I'm pretty confused about this behaviour, wondering if this is normal or not, about how really build stament works, and if I can just relocate the code without care about boootloader

I dont think that this could be related wiith the development nviroment used, but I'm using MPLABX and CCS 4.14, just in case
Ttelmah



Joined: 11 Mar 2010
Posts: 19470

View user's profile Send private message

PostPosted: Tue Jul 22, 2014 6:34 am     Reply with quote

No.

It _needs_ the code present in the bootloader, to redirect the interrupt jump, and to jump to the entry point, once the bootloader has completed.

Think about it. The processor jumps to address 0, when it starts. The code requires a jump to address 800. The interrupts call addresses 0008, and 0018. The code requires these calls to be re-vectored to addresses 808, and 818.
gudurix



Joined: 16 Jul 2014
Posts: 4

View user's profile Send private message

PostPosted: Tue Jul 22, 2014 8:05 am     Reply with quote

Thanks again:

Well I have tried the complete suggested solution:

First the bootloader part that I have burned with ICD3

ex_bootloader.c


Code:

#if defined(__PCM__)
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=8000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to 11, 7 to 12

#elif defined(__PCH__)
#include <18F4620.h>
#fuses HS,NOWDT,WDT256,PROTECT,NOLVP
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads                                                                                              // Fosc=8Mhz

#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)

#endif


#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 0x140,0x1FF
#else
#org 0x20,0x3F
#endif

void main(void) {
   printf("\r\n INICIANDO CARGA REMOTA FW...");
   int8 estado_carga=read_eeprom(0x3FF);
   if(estado_carga==255)
   {
      printf("\r\n ESPERANDO CARGA... ");
      load_program();
      printf("\r\n FIN CARGA REMOTA FW");
      delay_ms(100);
   }

   application();

 
}
#ORG default

#int_global
 void isr(void) {
    jump_to_isr(0x808);
 }


bootload.h : it has some modifications, removing diferents parts that I never use, and also in a pedagogical (for me, of course) purpose


Code:
//#if defined(__PCM__)

#define LOADER_END   0x7FF
#define LOADER_SIZE  0x5FF
#ifndef _bootloader
#build(reset=LOADER_END+1, interrupt=LOADER_END+9)
#org 0, LOADER_END {}

#endif

loader.c is the same as examples.

Theoritical and also real memory locations for these is are (i have checked that):

Ex_bootloader main application -->0x140,0x1FF
loader.c-->0x200,0x7ff

and finaly, here is my application code.

Code:

#include "18F4620.h"
#include <stdlib.h>
#include <Variables&Constantes.h>

#fuses HS,NOWDT, WDT256,PROTECT,NOLVP,
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=8000000)
#build(RESET=0x800, INTERRUPT=0x808)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,ERRORS)
#priority int_ext

#int_ext
void intext() {
..................................................
}

#int_TIMER0
void TIMER0_isr(void) {
.................................
}
void function1(void){
......
}
....
...
void functionN(void){
.....
}

void main{
.....

}


Well, I burn the PCB with ICD3, then configure tera term as is recomended in these forums and then send the main program, but it never return from charge . Teratern ends to send the file (the percentage bar ends) but nothing else happen.


I don't know what I'm missing. I think that I could be writing un positions below 0x800, as I can see that it happens when I compile the principal application. But I dont know how to avoid this. When I have only the principal program I am not able to avoid this
Ttelmah



Joined: 11 Mar 2010
Posts: 19470

View user's profile Send private message

PostPosted: Wed Jul 23, 2014 1:20 am     Reply with quote

Start by putting back the standard bootloader.h.....

You do not need to modify this. Just set the define 'LOADER_END', with the value you want, before loading it. it then automatically adjusts everything to suit the new end address....
So in your 'main' code, just have:
Code:

#define LOADER_END 0x7FF
#include <bootloader.h>

and in your bootloader, have:
Code:

#define LOADER_END 0x7FF
#define _bootloader
#include <bootloader.h>


Don't fiddle with things. Getting the bootloader addressing 'right', requires a large sequence of stuff to all be correct. The CCS files do this for you, so let them do their job.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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