|
|
View previous topic :: View next topic |
Author |
Message |
Martin H Guest
|
tcp bootloader |
Posted: Fri Nov 12, 2004 4:30 am |
|
|
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
|
|
Posted: Fri Nov 12, 2004 7:08 am |
|
|
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
|
|
Posted: Fri Nov 12, 2004 9:58 am |
|
|
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
|
|
Posted: Fri Nov 12, 2004 1:39 pm |
|
|
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
|
Iterrupt relocation problem |
Posted: Thu Apr 27, 2006 6:36 pm |
|
|
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: 1635 Location: Perth, Australia
|
|
Posted: Thu Apr 27, 2006 9:02 pm |
|
|
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
|
|
Posted: Sun Apr 30, 2006 4:12 pm |
|
|
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
|
my_bootloader.h won't compile |
Posted: Wed May 10, 2006 10:14 am |
|
|
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
|
|
Posted: Wed May 10, 2006 2:13 pm |
|
|
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
|
works- may have discovered a bug |
Posted: Wed May 10, 2006 2:45 pm |
|
|
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.
-Kyle |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Wed May 10, 2006 5:48 pm |
|
|
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
|
|
Posted: Thu May 18, 2006 7:26 am |
|
|
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
|
|
Posted: Sun Feb 03, 2013 6:37 pm |
|
|
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
|
ex_usb_bootloader |
Posted: Mon Feb 04, 2013 8:28 am |
|
|
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
|
Re: ex_usb_bootloader |
Posted: Mon Feb 04, 2013 11:45 pm |
|
|
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. |
|
|
|
|
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
|