|
|
View previous topic :: View next topic |
Author |
Message |
gudurix
Joined: 16 Jul 2014 Posts: 4
|
Relocate code of 18f4620 without bootloader |
Posted: Tue Jul 22, 2014 2:08 am |
|
|
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: 19587
|
|
Posted: Tue Jul 22, 2014 3:35 am |
|
|
#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
|
|
Posted: Tue Jul 22, 2014 3:56 am |
|
|
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: 19587
|
|
Posted: Tue Jul 22, 2014 6:34 am |
|
|
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
|
|
Posted: Tue Jul 22, 2014 8:05 am |
|
|
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: 19587
|
|
Posted: Wed Jul 23, 2014 1:20 am |
|
|
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. |
|
|
|
|
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
|