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

tcp bootloader
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Martin H
Guest







tcp bootloader
PostPosted: Fri Nov 12, 2004 4:30 am     Reply with quote

Hi

I'm trying to modify ex_bootloader to use tcp/ip instead of rs232 but the #int_global funktion in ex_bootloader seems to dislike the #int_timer0 interrupt fnk in tick.c from the TCP/IP stack provided by CCS. What exactly does the #int_global isr funktion do and can it be avoided?

/Martin
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Nov 12, 2004 7:08 am     Reply with quote

Straight from the help file
Quote:
This directive causes the following function to replace the compiler interrupt dispatcher. The function is normally not required and should be used with great caution. When used, the compiler does not generate start-up code or clean-up code, and does not save the registers.


So what that means is that you are writing the interrupt handler so there would not be ANY other #int_xxxxx. Personally, I think that if you want to upgrade your code via TCP then I wouldn't use a bootloader. The TCP code is pretty big and what if you wanted to upgrade it. I would add some flash to my board. Download the new code to the flash. Instead of a typical bootloader, just have a small routine that copies the program from the flash into the micro.
Martin H
Guest







PostPosted: Fri Nov 12, 2004 9:58 am     Reply with quote

Thanks for the reply! I actually ment what does the #int_global function do in the ex_bootloader program. Code:

#int_global
void isr(void) {
#asm
goto LOADER_END+7
nop
nop
nop
nop
nop
nop
goto LOADER_END+0x17
#endasm
}

I suppose that it has something to do with that the program loaded is executed after the reset or something. But anyway, is there a good way around this problem if I really want to use a tcp bootloader (with the timer interrupt) and not use the flash solution? Can I somehow "set" the int_global function after that I'm done loading my program? The loading part seems to work fine it's just the execute thing left. Sorry if this sounds stupid but I don't have any experience with this kind of programming.

/Martin
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Nov 12, 2004 1:39 pm     Reply with quote

Quote:
what does the #int_global function do in the ex_bootloader program.

This is for relocating the normal and high priority interrupts. The bootloader is placed in the low part of the memory where also the hardware interrupt vectors are located. The bootloader never changes but your uploaded program has to get access to these interrupts somehow, this is achieved by jumping to some hard coded locations outside the bootloader address range.

A possible solution is to introduce a variable that keeps track of the bootloader being active or not. Depending on the status of this variable you can call the bootloader's or the application's interrupt dispatcher. This requires a bit fiddling with assembly and the #org statement. The code below is an example.

Code:
#include <18F458.h>

#use delay(clock=16000000)
#fuses HS, NOWDT, NOPROTECT, NOPUT, NOLVP

#define LOADER_ISR_ADDR 0x0024
#define LOADER_END      0x0400      // or whatever other size value

#build(interrupt=LOADER_ISR_ADDR)

int8 BootloaderActive;

//////////////////////////////////////////////////////////////
// Relocate the interrupt vectors.
// Depending on whether the bootloader is active or the
// application, other interrupt dispatchers are called.
#org 0x08, 0x23
void isr_relocate(void) {
#asm
  // Address 0x0008 is the hardware High priority interrupt
  TSTFSZ BootloaderActive       // if bootloader active
  GOTO  LOADER_ISR_ADDR         // then jump to bootloader ISR
  GOTO  LOADER_END+0x07         // jump to application ISR

  NOP                           // Just filling memory
  NOP
  NOP

  // Address 0x0018 is the hardware Low priority interrupt
  TSTFSZ BootloaderActive       // if bootloader active
  GOTO   LOADER_ISR_ADDR+0x10   // then jump to bootloader ISR
  GOTO   LOADER_END+0x17        // jump to application ISR
#endasm
}

//////////////////////////////////////////////////////////////
// Bootloader main routine.
void main()
{
  BootloaderActive = TRUE;

  // Add your bootloader stuff here
  //
  //

  BootloaderActive = FALSE;
 
  // Add here a jump to the application
}

//////////////////////////////////////////////////////////////
// Just an interrupt handler for testing.
#int_timer0
void timer0_isr()
{
  // Do something
}


I don't have ex_loader.c so I don't know how CCS jumps from the bootloader to the application, but that's something you can just copy from the CCS code. Also check my 'LOADER_END+0x07', I haven't checked the address to be correct.
sham



Joined: 18 Apr 2006
Posts: 9

View user's profile Send private message Send e-mail

Iterrupt relocation problem
PostPosted: Thu Apr 27, 2006 6:36 pm     Reply with quote

ckielstra

I was looking at your comment and example about relocating the normal and high priority interrupts. Do you think this example will work. I am also trying to do interrupt in both places (boot area + app area). Currently I don’t have any idea about this. They way I implemented was not working. You can fine my posing and code at

http://www.ccsinfo.com/forum/viewtopic.php?t=26743 this link.

you help will be greatly appreciated

Regards
Shamine
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Apr 27, 2006 9:02 pm     Reply with quote

Mark wrote:
Personally, I think that if you want to upgrade your code via TCP then I wouldn't use a bootloader. The TCP code is pretty big and what if you wanted to upgrade it. I would add some flash to my board. Download the new code to the flash. Instead of a typical bootloader, just have a small routine that copies the program from the flash into the micro.


TFTP (Trivial File Transfer Protocol) is often used in networking equipment to implement boot loaders. This is because, as Mark has already indicated, There is a lot of overhead required to support TCP. The mechanism I use is to run the bootloader directly over UDP.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Apr 30, 2006 4:12 pm     Reply with quote

Quote:
I was looking at your comment and example about relocating the normal and high priority interrupts. Do you think this example will work.
The idea of the posted code was correct but missing a few small items. Below is a more up to date version. The basic idea is that you write two seperate applications, one is the bootloader and the other is your real application. In the bootloader you include my_bootloader.h with MY_BOOTLOADER defined while in your application you include the same header file but without this define active.

my_bootloader.h
Code:
////////////////////////////////////////////////////////////////////////////////
// Some defines for my bootloader.
//
// Include this file from the bootloader with MY_BOOTLOADER defined.
// Include this file from the applicatio with MY_BOOTLOADER not defined.
////////////////////////////////////////////////////////////////////////////////

#define RESET_VECTOR            0x0000      // Defined by hardware
#define HIGH_INT_VECTOR         0x0008      // Defined by hardware
#define NORMAL_INT_VECTOR       0x0018      // Defined by hardware
#define INTERRUPT_REMAP_END     HIGH_INT_VECTOR + 0x1B // End of the remap code

#define LOADER_START            INTERRUPT_REMAP_END+1
#define LOADER_END              0x07FF        // Defined by size of the bootloader code and/or protection fuses
#define LOADER_RESET            RESET_VECTOR
#define LOADER_HIGH_INT         LOADER_START
#define LOADER_NORMAL_INT       LOADER_HIGH_INT + 0x10

#define APPLICATION_START       LOADER_END + 2
#define APPLICATION_RESET       APPLICATION_START + RESET_VECTOR
#define APPLICATION_HIGH_INT    APPLICATION_START + HIGH_INT_VECTOR
#define APPLICATION_NORMAL_INT  APPLICATION_START + NORMAL_INT_VECTOR

#ifdef MY_BOOTLOADER
  #build(reset=LOADER_RESET, interrupt=LOADER_HIGH_INT)           // Move the reset and interrupt vectors
#else
  #build(reset=APPLICATION_RESET, interrupt=APPLICATION_HIGH_INT) // Move the reset and interrupt vectors
  #org 0, LOADER_END {}   // Reserve the bootloader memory area
#endif

// A global flag indicating the bootloader is active or not.
// This flag must be present in both the bootloader and application at the same
// address, that's why we place it here in the bootloader.h with a #locate
// instruction to fixed address 0x10. Address 0x10 was choosen arbitrarily in
// the start of memory above the CCS scratch register area (0x00 to 0x??).
int8 BootloaderActive;
#locate BootloaderActive=10


bootload.c
Code:
#include <18f6722.h>
#fuses HS,NOWDT,NOLVP,NOPUT,BROWNOUT

#define XTAL_SPEED 11000000

#define MY_BOOTLOADER
#include <my_bootloader.h>


////////////////////////////////////////////////////////////////////////////////
// Relocate the interrupt vectors.
// Depending on whether the bootloader or application is active
// different interrupt dispatchers are called.
#org HIGH_INT_VECTOR, INTERRUPT_REMAP_END
void isr_relocate(void) {
#asm
  // Address 0x0008 is the hardware High priority interrupt
  TSTFSZ BootloaderActive       // if bootloader active
  GOTO  LOADER_HIGH_INT         // then jump to bootloader ISR
  GOTO  APPLICATION_HIGH_INT    // else jump to application ISR

  NOP                           // Just filling memory
  NOP
  NOP

  // Address 0x0018 is the hardware Low priority interrupt
  TSTFSZ BootloaderActive       // if bootloader active
  GOTO   LOADER_NORMAL_INT      // then jump to bootloader ISR
  GOTO   APPLICATION_NORMAL_INT // else jump to application ISR
#endasm
}


// Start of the bootloader program
//#org LOADER_START, LOADER_END default      // Fix: Segment setting removed, doesn't compile in v3.245
#use delay( clock = XTAL_SPEED ) // required for delay_ms()

// Just a simple interrupt handler example
#int_timer0
void timer0_isr()
{
  int i=0;
  i = i+1;
}

void main(void)
{
  int8 i;

  BootloaderActive = TRUE;
 
  // Do your bootloader things here
  for (i=0; i<10; i++)
  {
    output_toggle(PIN_B1);
    delay_ms(500);
  }
 
  // Exit the bootloader and go to the Real Application
  goto_address(APPLICATION_START);
}


Real Application
Code:
////////////////////////////////////////////////////////////////////////////////
// An example of how to setup an application that can be used in combination
// with the MyBootloader.
// The only thing that is different from normal programming is the including of
// the my_bootloader.h file.
////////////////////////////////////////////////////////////////////////////////
#include <18f6722.h>
#fuses HS,NOWDT,NOLVP,NOPUT,BROWNOUT

#define XTAL_SPEED 11000000
#use delay( clock = XTAL_SPEED ) // required for delay_ms()

#include <my_bootloader.h>

// Just an interrupt as example.
#int_timer0
void timer0_isr(void)
{
  // Do nothing
}

void main()
{
  BootloaderActive = FALSE;
 
  for(;;)
  {
    output_toggle(PIN_B1);
    delay_ms(500);
  }
}


Edit: Disabled the #org line in bootload.c because of compiler errors in v3.245


Last edited by ckielstra on Tue Jun 20, 2006 4:54 pm; edited 1 time in total
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

my_bootloader.h won't compile
PostPosted: Wed May 10, 2006 10:14 am     Reply with quote

ckielstra,

I too am need to make a bootloader on a system whose primary microcontroller is an 18F8722. Since your example is for an 18F6722, your code should work for me.

I put your my_bootloader.h in a common header file directory, included it, defined MY_BOOTLOADER in the bootloader code, compiled it, and it is fine. Wonderful.

I then included my_bootloader.h in my application code, did NOT define MY_BOOTLOADER, try to compile, and get errors. Here is what the build screen reports:
Quote:
Executing: "C:\Program files\Picc\CCSC.exe" "Atlanta.c" +FH +DF +LN +T +A +M +Z +Y=9 +P01 +EA I="S:\Devel\Pic-C\Lib;C:\Program Files\PICC\Devices;C:\Program Files\PICC\Drivers"
--- Info 300 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): More info: Segment at 00000-007FE (0000 used) Priv
--- Info 300 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): More info: Segment at 00800-0FFFE (0000 used)
--- Info 300 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): More info: Segment at 10000-1FDFE (0000 used)
--- Info 300 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): More info: Segment at 1FE00-1FFFE (0000 used) Priv
--- Info 300 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): More info: Attempted to create: 007FE-00800 for reset
*** Error 126 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): Invalid ORG range
1 Errors, 3 Warnings.
Halting build on first failure as requested.
BUILD FAILED: Wed May 10 11:59:08 2006

No matter what I try, it always reports an invalid ORG range. It appears it has to do with moving the reset vector. Have you compiled this code successfully?

-Kyle
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 10, 2006 2:13 pm     Reply with quote

Quote:
No matter what I try, it always reports an invalid ORG range. It appears it has to do with moving the reset vector. Have you compiled this code successfully?
The code is tested. Just to make sure I copied the code from the forum to a new project in MPLAB and compiled the application. I tested with both CCS v3.225 and v3.245, for me everything works as expected.

The error message you get shows the reset vector is mapped to the wrong location
Quote:
--- Info 300 "S:\Devel\Pic-C\Proj\Beta\Atlanta\Rev0.2\Atlanta.c" Line 115(0,1): More info: Attempted to create: 007FE-00800 for reset
This section should have started at 0x0800, not at 0x07FE.
I get this same error when in my_bootload.h I change the line
Code:
#define APPLICATION_START       LOADER_END + 2
to
Code:
#define APPLICATION_START       LOADER_END

Double check you didn't make a copy/paste error.
kda406



Joined: 17 Sep 2003
Posts: 97
Location: Atlanta, GA, USA

View user's profile Send private message

works- may have discovered a bug
PostPosted: Wed May 10, 2006 2:45 pm     Reply with quote

Many sincere thanks for the reply.

You were on the right track about the copy/paste issue, and this may have revealed a bug in the compiler. Even though our header files read the same line for line, I pasted yours from the forum again, and it started working. I traced the problem to a specific line. Yours reads:
Code:
#define LOADER_END              0x07FF        // Defined by size of the bootloader code and/or protection fuses

I like my code tidy, and all my remarks start on column 64. So I inserted a few tabs and had this in my header file:
Code:
#define LOADER_END              0x07FF                          // Defined by size of the bootloader code and/or protection fuses

So when it says
...0x07FF<space><space><space><tab><tab>// Defined by...
it turns out that the tabs cause the compiler to put the reset vector in the wrong memory location (yes, a few bytes off), which doesn't match the ORG, and causes the error I posted.

Again, many thanks for the reply AND for posting your code. I look forward to trying it now that I have taken out the tabs and it compiles. Very Happy

-Kyle
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed May 10, 2006 5:48 pm     Reply with quote

Quote:
So when it says
...0x07FF<space><space><space><tab><tab>// Defined by...
it turns out that the tabs cause the compiler to put the reset vector in the wrong memory location (yes, a few bytes off), which doesn't match the ORG, and causes the error I posted.
I already noticed the CCS preprocessor is a very poor implementation but this is just unacceptable behaviour. I posted this as a bug to CCS support.
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Thu May 18, 2006 7:26 am     Reply with quote

I was notified today by CCS that the preprocessor bug is fixed and will be in the next release (3.250?).
shahab



Joined: 03 Feb 2013
Posts: 3

View user's profile Send private message

PostPosted: Sun Feb 03, 2013 6:37 pm     Reply with quote

I am using the same code for 18F67J10 but its not working. Is there any thing different for this series.

I also tried

#define LOADER_END 0x04FFF
but it didn't work
nurquhar



Joined: 05 Aug 2006
Posts: 149
Location: Redditch, UK

View user's profile Send private message Visit poster's website

ex_usb_bootloader
PostPosted: Mon Feb 04, 2013 8:28 am     Reply with quote

I have just got the "ex_usb_bootloader" example working on the PIC18F27J53. I guess it works the same way as the serial bootloader "ex_bootloader".

With regard to the discussion above about interrupts etc I have just read the following in the comments/notes in the source.

//// To create an application that is compatible with this loader ////
//// simply #include usb_bootlaoder.h into your application. This ////
//// loader does support interrupts in your application. ////

So if I understand english this seems to suggest the you can't use the bootloader with applications that make use of any interrupts. Have I got that right ? If so, to use an american expression, that sucks.

Is there a better CCS based USB bootloader anybody has written ?

Personally I prefer the approach of the bootloader being in the top of memory so the app can be used as normal starting at 0x0000. The only wrinkle to be handled by the bootloader is to catch the writing of the apps reset vector at 0x0000 and store it elsewhere. i.e. The reset vector points directly to the start of bootloader which chains to the app using the vector it caught and stored.
dbotkin



Joined: 08 Sep 2003
Posts: 197
Location: Omaha NE USA

View user's profile Send private message Send e-mail Visit poster's website

Re: ex_usb_bootloader
PostPosted: Mon Feb 04, 2013 11:45 pm     Reply with quote

nurquhar wrote:
I have just got the "ex_usb_bootloader" example working on the PIC18F27J53. I guess it works the same way as the serial bootloader "ex_bootloader".

With regard to the discussion above about interrupts etc I have just read the following in the commets/notes in the source.

//// To create an application that is compatible with this loader ////
//// simply #include usb_bootlaoder.h into your application. This ////
//// loader does support interrupts in your application. ////

So if I understand english this seems to suggest the you can't use the bootloader with applications that make use of any interrupts. Have I got that right ? If so, to use an american expression, that sucks.

No, you don't have it right. :) You can indeed use interrupts in your application. I am using the CCS USB bootloader in the project I'm working on right now, in fact -- and I'm using several interrupts.
Quote:


Is there a better CCS based USB bootloader anybody has written ?

Personnaly I prefer the approach of the bootloader being in the top of memory so the app can be used as normal starting at 0x0000. The only wrinkle to be handled by the bootloader is to catch the writing of the apps reset vector at 0x0000 and store it elsewhere. i.e. The reset vector points directly to the start of bootloader which chains to the app using the vector it caught and stored.

I think you can use the bottom or top of memory for the CCS bootloader. Not entirely certain -- once it's in the chip I ignore it; the only thing i have to do is #include the header file. No other adjustments, really.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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