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 CCS Technical Support

Bootloader works, but want modifications that break it

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



Joined: 03 Jun 2021
Posts: 6

View user's profile Send private message

Bootloader works, but want modifications that break it
PostPosted: Thu Jun 03, 2021 9:20 am     Reply with quote

I've implemented the bootloader successfully with compiler version 5.094. It loads a new application with no issue.

The problem is I'm trying to make some changes to the original code. I want to add to the application() function has some initialization code relating to leds just before the infinite loop to indicate to the user that no user application code has been loaded.

So I want to change this:

Code:

#org LOADER_END+1,LOADER_END+3
void application(void) {
   while(TRUE);
}


To this:

Code:

#org LOADER_END+1,LOADER_END+3
void application(void) {
   // set up led i/o - RA2/RA3
   set_tris_a (0xc);
   output_high (PIN_A2);
   output_high (PIN_A3);
   while(TRUE);
}


I have an error message relating to the isr() indicating "Out of ROM, A segment or the program is too large application". I tried increasing the #org end address, but it fails in the same way.

Any advice on how to correct this?
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Thu Jun 03, 2021 12:12 pm     Reply with quote

Think about it.

The standard application is just a single entry. Hence fits in three
instructions. You now have perhaps 20 physical instructions. The space
allocated needs to go up to allow for this. Instead of +3, something
like +30.
lt2021_genie



Joined: 03 Jun 2021
Posts: 6

View user's profile Send private message

PostPosted: Thu Jun 03, 2021 12:54 pm     Reply with quote

I did do that. All of the errors come back as:

Code:

Compiling D:\project\TEST\system\css_sbl\css_serial_bootloader on 03-Jun-21 at 13:52
--- Info 300 "D:\project\TEST\system\css_sbl\css_serial_bootloader.c" Line 51(30,32): More info:   Segment at 00000-00502 (0000 used)
--- Info 300 "D:\project\TEST\system\css_sbl\css_serial_bootloader.c" Line 51(30,32): More info:   Segment at 00504-0FFFE (0000 used)  Priv
--- Info 300 "D:\project\TEST\system\css_sbl\css_serial_bootloader.c" Line 51(30,32): More info:   Attempted to create: 00500-0053E  for #org
*** Error 126 "D:\project\TEST\system\css_sbl\css_serial_bootloader.c" Line 51(30,32): Invalid ORG range
      1 Errors,  0 Warnings.
Build Failed.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Jun 04, 2021 1:20 am     Reply with quote

Really the bootloader is not designed to do this. The 'application' declaration
is meant to be a 'stub', telling the bootloader where the future function actually
'is', but containing nothing. It is possible to add a function here, but you have
to tweak all the memory declarations to do this.
Easier possibly to compile the application as a bootloadable problem, and
then import this at the end of the bootloader. This ought to work.

Trying to do it the way you are has huge problems. The 'main;' that is
loaded by a bootloader at the application location, won't physically be at that
location. Instead it'll have a single jump at this point to the code that will
sit higher in memory. This is done to leave the space for the interrupt
handlers. Now trying to load a whole 'program' here, if it is more than about
a couple of bytes, results in the locations reserved for the interrupt handlers
being overwritten. Result, won't work.
This is why the code that is added here has to be a correctly written complete
program with the jumps and spaces included.
The normal way to combine the bootloader and a program is to compile
both separately, and to #import the bootloader, into the main program.
This is the only 'tested' way that works that I know of.
lt2021_genie



Joined: 03 Jun 2021
Posts: 6

View user's profile Send private message

PostPosted: Fri Jun 04, 2021 7:44 am     Reply with quote

I had a feeling this was the case, so I tried something else shown below just for reference for anyone else who may want to do the same thing. Thanks for the help.

Code:

#include <18F26Q10.h>

#use delay( internal=32MHz )
#use rs232(baud=115200, xmit=PIN_C7, rcv=PIN_C6) //Text through the UART
#define PUSH_BUTTON PIN_B4

#define _BOOTLOADER
//#define BOOTLOADER_MODE2X

#include <bootloader.h>
#include <loader.c>

void app (void);

#org LOADER_END+1,LOADER_END+3
void app_init(void) {
  app();
}

//-------------------------------------------------------------------------
void main (void) {
//-------------------------------------------------------------------------
   // setup pull ups on B3/B4
   port_b_pullups (0x18);
   
   // setup i/o clear led
   set_tris_a (~0x0c);
   output_high (PIN_A2);
   output_high (PIN_A3);
   
   //delay_ms (100);
   
   if(!input(PUSH_BUTTON))
   {
      output_low (PIN_A2);
      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();
   }
   
   printf("\r\nRunning loaded app...");
   app_init();
}

//-------------------------------------------------------------------------
void app (void) {
//-------------------------------------------------------------------------
   output_low (PIN_A2);
   output_low (PIN_A3);
   while(TRUE);
}

#int_global
//-------------------------------------------------------------------------
void isr (void) {
//-------------------------------------------------------------------------
   jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Jun 04, 2021 8:20 am     Reply with quote

OK.
The problem with this is the 'app' here is actually inside the bootloader
memory space. So anything much larger will result in this running out of
space.
So long as it is kept really small this should work.
lt2021_genie



Joined: 03 Jun 2021
Posts: 6

View user's profile Send private message

PostPosted: Thu Jul 01, 2021 11:59 am     Reply with quote

I have a follow-up question.

Using the #import method, what type of file would I be importing? The object file? A hex file? What compile settings would I use to create this file for the bootloader and the application?

From your post, I have to do the following.

1. Compile bootloader.c with following options:

Code:
"CCSC.exe" +FH +EXPORT bootloader.c


2. Add to top of application.c source:

Code:
#import "bootloader.o"


3. Compile application.c

This should then create a application.hex file that I can load?

Am i missing anything? I thought the +EXPORT produced relocatable code. Wouldn't that defeat the purpose of what we're doing? Or do I not use the export feature. When I do that I can only produce the final hex output and not the object file.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Fri Jul 02, 2021 12:28 am     Reply with quote

No, you #import the hex file.

Also ideally, modify the application getting rid of all the #fuses, and instead
having #fuses NONE.
If you don't do this you will get a complaint when the new hex file includes
the bootloader fuses (even though these will be (must be...)) the same as
the ones in the application.

So you add to the application (which you are compiling to use the
bootloader), so with :
#include <bootloader.h>

You then add:
#IMPORT (FILE=bootloader.hex,HEX,RANGE=0:LOADER_SIZE)

With obviously the file name of your bootloader.

This way it loads a normal .hex file.
lt2021_genie



Joined: 03 Jun 2021
Posts: 6

View user's profile Send private message

PostPosted: Fri Jul 02, 2021 7:57 am     Reply with quote

Following your instructions, I successfully generated an application.hex file with the imported bootloader.hex. There's a warning from application.c compile. Should I be concerned? I've included the source for both below.

"Line 6(0,1): Memory not available at requested location"

bootloader.c

Code:

#include <18F26Q10.h>

#use delay( internal=32MHz )
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7) //Text through the UART

#define _BOOTLOADER
//#define BOOTLOADER_MODE2X

#define PUSH_BUTTON PIN_B4

#include <bootloader.h>
#include <loader.c>

void app (void);

#org LOADER_END+1,LOADER_END+3
void application(void) {
  while (TRUE);
}

//-------------------------------------------------------------------------
void main (void) {
//-------------------------------------------------------------------------
   if(!input(PUSH_BUTTON))
   {
      output_low (PIN_A2);
      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();
   }
   
   printf("\r\nRunning loaded app...");
   application();
}

#int_global
//-------------------------------------------------------------------------
void isr (void) {
//-------------------------------------------------------------------------
   jump_to_isr(LOADER_END+5*(getenv("BITS_PER_INSTRUCTION")/8));
}


application.c

Code:

#include <18F26Q10.h>
#include <bootloader.h>

#FUSES NONE

#IMPORT (FILE=bootloader.hex,HEX,RANGE=0:LOADER_SIZE)

#use delay(internal=32MHz)
#use rs232(baud=115200, xmit=PIN_C6, rcv=PIN_C7)

//-------------------------------------------------------------------------
void main (void) {
//-------------------------------------------------------------------------
   int8 i = 0;

   delay_ms(100);

   printf("\r\nApplication Version 1.1\r\n");
   
   // setup pull ups on B3/B4
   port_b_pullups (0x18);
   
   // setup i/o clear led
   set_tris_a (~0x0c);
   output_high (PIN_A2);
   output_high (PIN_A3);

   while(TRUE) {
      // print incrementing count
      printf("\n\r%3u ",++i);
      // toggle green led
      output_toggle (PIN_A3);
      // wait 500ms
      delay_ms(500);
   }
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Sun Jul 04, 2021 2:14 am     Reply with quote

That is perfectly OK.
All that is happening, is the main program is built to start after the
loader, and you are then 'importing' something that resides below it's
permitted memory range, so it warns you that this might be a problem.
If you load the resulting hex file, you will see that it is all correctly there
and where it should be. Smile

The only problem you may get is with the fuses.
Problem is that the 'application' when you build it does not specify any
fuses. However the bootloader when loaded is told not to include the
fuses.
The behaviour of this depends on compiler version. Most seem to load
the fuses 'anyway', however some of the recent ones do not. So get
rid of #fuses NONE, which will ensure the fuses are set. You will still get
the same error, but it ensures that there are fuses included in the result.
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