View previous topic :: View next topic |
Author |
Message |
camriz
Joined: 08 Nov 2020 Posts: 6
|
Trying to get the bootloader to work |
Posted: Sun Nov 08, 2020 10:20 am |
|
|
Hello,
I am trying to get the bootloader to work for my program. I created a simple program first which was auto-generated by CCS C Compiler project wizard. Here it is below:
Code: |
#include <main.h>
#define _bootloader
// NOTE - User must include bootloader.h in application program
#include <bootloader.h>
#include <loader.c>
#define PUSH_BUTTON PIN_A5
#INT_GLOBAL
void isr(void){
jump_to_isr(LOADER_END+9);
}
#org LOADER_END+2, LOADER_END+4
void application(void) {
while(TRUE) {
delay_ms(1000);
fprintf(rs485, ".");
}
}
void main()
{
fprintf(rs485, "Hello\r\n");
// Enter Bootloader if Pin A5 is low after a RESET
if(!input(PIN_A5))
{
load_program();
}
application();
}
|
This code compile successfully with
Code: | void application(void) {
while(true);
}
|
I assume my code is going to reside inside the "application()" function. As soon as I add a couple of lines, I get the following error:
Compiling C:\Users\Camille\Desktop\debug\main on 08-Nov-20 at 07:58
*** Error 71 "C:\Users\Camille\Desktop\debug\main.c" Line 35(1,2): Out of ROM, A segment or the program is too large application
Seg 00500-00502, 0004 left, need 00018 Orged
1 Errors, 0 Warnings.
Build Failed.
If I attempt to add few bytes, by doing
Code: | #org LOADER_END+2, LOADER_END+0x0030 |
I get the following error:
Compiling C:\Users\Camille\Desktop\debug\main on 08-Nov-20 at 08:18
--- Info 300 "C:\Users\Camille\Desktop\debug\main.c" Line 16(31,37): More info: Segment at 00000-00502 (0000 used)
--- Info 300 "C:\Users\Camille\Desktop\debug\main.c" Line 16(31,37): More info: Segment at 00504-07FFE (0000 used) Priv
--- Info 300 "C:\Users\Camille\Desktop\debug\main.c" Line 16(31,37): More info: Attempted to create: 00500-0052E for #org
*** Error 126 "C:\Users\Camille\Desktop\debug\main.c" Line 16(31,37): Invalid ORG range
1 Errors, 0 Warnings.
Build Failed.
I assume my application code is supposed to reside between 0x0500 and 0x7fff since I am using a PIC1825K83, but I have not been successful in using #org to make that happen.
Any help would be greatly appreciated. _________________ Thank you. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Nov 08, 2020 11:00 am |
|
|
this...
Out of ROM, A segment or the program is too large application
...means that the program is too big to fit into available space..
adding a 'couple'(2) of lines wouldn't generate the error UNLESS your
'main()' is already BIG.
You should compile just 'main()' and see how big it is, check the listing ( programname.LST) file. |
|
|
camriz
Joined: 08 Nov 2020 Posts: 6
|
|
Posted: Sun Nov 08, 2020 11:23 am |
|
|
Hello Temtronic,
The program is what you see in my post, only 2 lines of code, it takes up less than 3% of the space which is primarily the bootloader code. _________________ Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Nov 08, 2020 11:48 am |
|
|
To 'add a few bytes' you change the value of loader pages. Remember
the loader has to grow in _pages_, so you cannot add 30 bytes.
Set this before you load the bootloader.h, and also to the same value in your
application program when you generate this.
However post your setup for the serial output. If for instance this is using
software serial, this could add hundreds of bytes to the program size. |
|
|
camriz
Joined: 08 Nov 2020 Posts: 6
|
|
Posted: Sun Nov 08, 2020 12:07 pm |
|
|
Hello,
not sure if this is the proper fix, but if I comment
Code: |
//#org LOADER_END+5, (getenv("PROGRAM_MEMORY") - 1) {}
|
then I compile successfully.
I am not at all familiar with the #org syntax and the documentation is not that clear. _________________ Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sun Nov 08, 2020 1:36 pm |
|
|
No, it is not a fix. It means the application prototype is being put into the
bootloader space. Won't work. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: Trying to get the bootloader to work |
Posted: Sun Nov 08, 2020 10:07 pm |
|
|
camriz wrote: |
I am trying to get the bootloader to work for my program.
I am using a PIC1825K83
|
What is your version of the CCS compiler ?
For example, I noticed that Ex_bootloader.c in vs. 5.093 has this:
Quote: |
#org LOADER_END+1,LOADER_END+2
void application(void) {
while(TRUE);
}
|
And there are no #ifdef's for PCM or PCH.
But vs. 5.096 has this:
Quote: |
#org LOADER_END+1, LOADER_END+3
void application(void) {
while(TRUE);
} |
Also with no #ifdef's for PCM or PCH.
But in vs. 5.085, it looked like this:
Quote: |
#if defined(__PCM__)
#org LOADER_END+1,LOADER_END+2
#elif defined(__PCH__)
#org LOADER_END+2,LOADER_END+4
#endif |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Nov 09, 2020 12:35 am |
|
|
Compiler version.
Header defining the RS232, processor etc. actually being used.
-> Your 'main.h'.
The critical 'extra' data before we can really help.
Key here is that the 18F25K83 (guessing you 'lost' the 'F', is a PPS
chip. Unless he has the PPS settings correct, he will be using software
serial. This immediately costs more ROM, and is likely to make operation
unreliable if he did get it built.
The reason for the change PCM, is that these chips are ones that in their
larger versions support 'large' ROM sizes (>64K), these require 'long jump'
instructions to support the whole of memory, and these are larger than
the standard jumps needed. Shouldn't apply on his chip since it only has
32K ROM.
The fact he refers to the +4 layout, suggests he is using an older compiler.
So I took 5.085, and built a basic 'bootloader.c' for this:
Code: |
#include <18F25K83.h>
#use delay(internal=32MHz)
//setup PPS
#pin_select U1RX=PIN_C7
#pin_select U1TX=PIN_C6
#use rs232(UART1, ERRORS, STREAM=RS485) //setup Uart1 on this chip
#define PUSH_BUTTON PIN_A5
#define _BOOTLOADER
#include <bootloader.h>
#include <loader.c>
#org LOADER_END+2,LOADER_END+4
void application(void) {
while(TRUE);
}
void main(void) {
if(!input(PUSH_BUTTON))
{
fprintf(rs485, "Hello\r\n");
load_program();
}
application();
}
#int_global
void isr(void) {
jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
|
Merrily compiles.
Thing that worries me, is that he is using a stream name for his print.
which the bootloader code itself does not use, suggesting he may be
actually setting up two ports.
The big thing that is making it go wrong though is he is sticking code
into the 'application' in bootloader. You can't do this. This is not a real
application, but a 'stub' that contains basically nothing. It is there to make
the connections so when the real application is loaded, the code knows
where to go. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Nov 09, 2020 5:36 am |
|
|
One potential 'problem' I see is the serial line is called 'RS485' yet no 'ENABLE' pin is declared in the #USE RS232(..options...).
Without an 'enable' pin, the RS485 driver will be either be in xmt only or rcv only mode, though as I'm typing this , I'm wondering if it'd do both, looping back it's xmt data to it's rcv line,which opens up another 'can of worms'.
I should grab the databook for an RS485 chip but I HAVE to fix a flattube on the forklift...... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Nov 09, 2020 7:01 am |
|
|
He hasn't posted his #USE RS232 options. That is something we have been
asking for.... |
|
|
camriz
Joined: 08 Nov 2020 Posts: 6
|
|
Posted: Mon Nov 09, 2020 8:36 am |
|
|
Hello Gents,
I created this simple project from the wizard, I used both 5.094 and 5.096 with the same result. My #use is below:
Code: |
#pin_select U1TX=PIN_C4
#pin_select U1RX=PIN_C6
#use rs232(stream=rs485,baud=115200,enable=PIN_C5,UART1,errors) |
My question is how can I allocate my application() routine in the space between 0x504 and 0x7fff.
No matter how much I allocate, the compiler/linker rejects it and indicates that 0x504-0x7fff is already allocated and "Priv". _________________ Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Nov 09, 2020 8:55 am |
|
|
You don't.
The point is the bootloader is the program to load the application. It
doesn't have the application in it.
The application in the bootloader is just a stub to set everything up for
the real application that you load 'with' the bootloader.
You do not build the bootloader with the application included.
Now it is possible to 'integrate' a final application 'with' the bootloader
so it is loaded as one piece.
You build the application separately.
Then you include by one of several methods:
1) load the bootloader into the programmer code, then load the
application, with the option to erase 'turned off'. Then save the whole
assembly.
2) Do the same using MPLAB.
3) You can '#import' the application. :
<https://www.ccsinfo.com/forum/viewtopic.php?t=55241>
To work with the bootloader, the application _has_ to be built as a
'loadable' application, so has to be imported one of these ways. |
|
|
camriz
Joined: 08 Nov 2020 Posts: 6
|
|
Posted: Mon Nov 09, 2020 12:19 pm |
|
|
Thank you Ttelmah for the clarification,
As you said in your reply, I do want to integrate my application with the bootloader, so I can update the application in the field. I ca nthen supply customers with a small utility and an updated firmware so they can upgrade their devices when needed.
It does seem to me that if I comment the #org in the bootloader.h I can then place my application between 0x500 and 0x7fff, this way I can program the bootloader integrated with my application using the ICD, then I can upgrade it in the field using rs232. Wouldn't that work?. As long as we are placing the application code at the right place and "main" is calling the entry point of the application always at the same address? _________________ Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Nov 09, 2020 1:51 pm |
|
|
You are missing a fundamental point.
When you write an application to be loaded by the bootloader, except
for being relocated, it is a _stand alone_ application. It does not (and must
not) use any part of the bootloader. It has it's own serial handling and
control of all the I/O pine (except for the single pin that triggers the
load).
If you want to include a copy of the application to load with the bootloader,
it still _must_ be built this way. It cannot be compiled as part of the
bootloader.
So you have to build the application as a 'bootloadable' application
separately, and then merge it into the file that you load.
If you try to build the application as part of the bootloader, you make it
dependant on the bootloader, so any change to the bootloader will stop
the application working.
What you are trying to do is not the way you have to work when using the
bootloader. You instead must 'merge' a program built as a standalone
program, but located to allow for the bootloader, with the bootloader
code as I describe. You must not try to 'build' the application into the
bootloader.
The bootloader and the bootloadable application are two separate things
and must be built as such. There are then ways you can merge these so
that on the first program a copy of an application is loaded, as I have
described, but you do not do this by putting code into the 'application'
in the bootloader. |
|
|
camriz
Joined: 08 Nov 2020 Posts: 6
|
|
Posted: Mon Nov 09, 2020 2:00 pm |
|
|
Thank you for the clarification. _________________ Thank you. |
|
|
|