|
|
View previous topic :: View next topic |
Author |
Message |
fuffkin
Joined: 17 Aug 2005 Posts: 2
|
Tiny Bootloader problem |
Posted: Wed Aug 17, 2005 6:09 pm |
|
|
I am testing the Tiny Bootloader with an 18F452 and it works once only - loads the code, boots into the user code and is fine. However, you cannot then reload code - you must burn it again with ICD and off you go again. Looking at the .LST file that is generated a "goto main" is duly created at ORG 0x0000 as required by Tiny. So everything seems fine. I also reserve some ROM with a #org 0x7F00, 0x7FFF void boot_loader(void) {} (I've generously given it more than the required 100 bytes - could this be relevant?)
I have seen prior posts that describe the same effect, but in all cases no conclusion was drawn or the problem went away by itself. Has anyone discovered anything more concrete about this? Any ideas? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Aug 17, 2005 7:05 pm |
|
|
From the source code
Quote: | #define first_address max_flash-200 ;100 words |
It is actually 200 bytes.
Quote: | ORG first_address ;space to deposit first 4 instr. of user prog.
nop
nop
nop
nop
|
The goto main is at the top of the bootloader not at org 0
The first instructions at org 0 should be to jump to the bootloader
Quote: | ORG 0x0000
GOTO IntrareBootloader
|
From their website
"A bootloader is a program that stays in the microcontroller and communicates with the PC (usually through the serial interface). The bootloader receives a user program from the PC and writes it in the flash memory, then launches this program in execution. Bootloaders can only be used with those microcontrollers that can write their flash memory through software. The bootloader itself must be written into the flash memory with an external programmer. In order for the bootloader to be launched after each reset, a "goto bootloader" instruction must exist somewhere in the first 4 instructions; There are two types of bootloaders, some that require that the user reallocate his code and others that by themselves reallocate the first 4 instructions of the user program to another location and execute them when the bootloader exits.
" |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Wed Aug 17, 2005 8:01 pm |
|
|
I use it without any modification in my code, never had problems with 16f876, 16f877 and 18f452. |
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Thu Aug 18, 2005 9:17 am |
|
|
Hi,
The same problem occurred when I used Loader.c, after a successful download the bootloader got erased. So the next time I needed to re-load the program, I had to use Pictstart .
Well what's the point in using a bootloader when it is better to program an mcu the usual way , then solder the MCU to the board ????
thanks
arunb |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Thu Aug 18, 2005 3:36 pm |
|
|
Because the bootloader takes less than 5 seconds to load a 10k firmware and needs just one click.
I don't even need to touch the board/cables/switches.
Bootloaders are the cheapest and fastest way to develop, I think.
An ICD have a good use WHEN you are testing code, when you don't know if what you are doing is correct. |
|
|
hansknec
Joined: 30 Sep 2004 Posts: 25 Location: Virginia, USA
|
another bootloader issue |
Posted: Sun Aug 28, 2005 3:00 pm |
|
|
The following code works when the PIC is programmed using the ICD-U40. The serial port spits out the proper address (9)
Code: |
#include <16F876A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ENABLE=PIN_A4,ERRORS)
#include <input.c>
#define mem1 (0x2100)
// EEPROM reading and writing info ********************************************
#rom mem1 = {'9'} // set initial address to 9 when loading first hex file
char address;
void main() { //********************************** MAIN ************************
address = read_eeprom(mem1);
do{
printf("\nmem1 is %c",address);
delay_ms (200);
} while (TRUE);
}
|
Next I programmed the PIC with PICbootPlus loader software and they tell me to add a line of code to reserve memory for the loader. The
#org 0x1F00, 0x1FFF will now be reserved for the loader. The remaining code was left alone.
Code: |
#include <16F876A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#org 0x1F00, 0x1FFF void loader16F876(void) {}
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ENABLE=PIN_A4,ERRORS)
#include <input.c>
#define mem1 (0x2100)
// EEPROM reading and writing info ********************************************
#rom mem1 = {'9'} //set the initial address to 9 when loading hex file
char address;
void main() { //********************************** MAIN ************************
address = read_eeprom(mem1);
do{
printf("\nmem1 is %c",address);
delay_ms (200);
} while (TRUE);
}
|
Now the serial prints out "mem1 is " (blank)
The memory address 0x2100 isn't part of this reserved memory area.
Could someone tell me what I'm doing wrong and how to fix it? I only need to initialize about 6 bytes in my final program and I will need to read and write to these 6 bytes at will.
I have tried using the read_program_eeprom() instead with no luck.
Beyond this problem I absolutely LOVE the bootloader! It programs the PIC in a SCRE.... (was going to say scream, but it programmed too fast.) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 28, 2005 3:09 pm |
|
|
Quote: | #define mem1 (0x2100)
address = read_eeprom(mem1); |
The read_eeprom() function does not use absolute addresses.
From the CCS manual:
Quote: | Function: Reads a byte from the specified data EEPROM address.
The address begins at 0 and the range depends on the part. |
|
|
|
hansknec
Joined: 30 Sep 2004 Posts: 25 Location: Virginia, USA
|
Yes, but.... |
Posted: Sun Aug 28, 2005 4:31 pm |
|
|
As I mentioned before I also tried this:
Code: |
#include <16F876A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#org 0x1F00, 0x1FFF void loader16F876(void) {}
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ENABLE=PIN_A4,ERRORS)
#include <input.c>
#define mem1 (0x2100)
// EEPROM reading and writing info ********************************************
#rom mem1 = {'9'} //set the initial address to 9 when loading hex file
char address;
void main() { //********************************** MAIN ************************
address = read_program_eeprom(mem1);
do{
printf("\nmem1 is %c",address);
delay_ms (200);
} while (TRUE);
}
|
Still no luck. The PIC16F87X data sheet claims I can read an write to EEPROM memory.... does this also mean program memory? I have also played around with the AUTO=0 command, but I honestly don't know what it's doing, and the manual might as well be written in Greek for my ability to understand this memory organization. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 28, 2005 4:40 pm |
|
|
To read the data eeprom at address 0x2100 with the CCS function,
you must do this:
|
|
|
hansknec
Joined: 30 Sep 2004 Posts: 25 Location: Virginia, USA
|
I beg to differ |
Posted: Sun Aug 28, 2005 5:48 pm |
|
|
If you look at the code in the first half of my post above you will see that I was reading the memory location as an absolute position and it worked perfectly. This is contrary to everything you have said.
Could the real reason for my problem be that the bootloader I have (PICbootPlus) just doesn't have the ability to write to the EEPROM area? I need to look into this further. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Aug 28, 2005 6:12 pm |
|
|
Quote: |
If you look at the code in the first half of my post above you will see that
I was reading the memory location as an absolute position and it worked
perfectly. This is contrary to everything you have said. |
It works by accident.
Here is a test program:
Code: | #include <16F877A.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#define mem1 (0x2100)
//======================
main(void)
{
int8 value;
value = read_eeprom(mem1);
while(1);
} |
Here is the code from the program above, that reads the data eeprom.
Code: |
0000 .... value = read_eeprom(mem1);
0011 1703 BSF 03.6 // Bank 2
0012 018D CLRF 0D // Set EEADR register = 0
0013 1683 BSF 03.5 // Bank 3
0014 138C BCF 0C.7 // Set EEPGD bit = 0 (to read data)
0015 140C BSF 0C.0 // Set RD bit = 1 (to read eeprom)
0016 1283 BCF 03.5 // Bank 2
0017 080C MOVF 0C,W // Read EEDATA register
0018 1303 BCF 03.6 // Bank 0
0019 00A1 MOVWF 21 // Save data in "Value"
|
Notice that EEADR is an 8-bit register. It's set = 0.
Even though you have used 0x2100 as the address parameter,
the compiler has truncated it to 0x00, because the read_eeprom()
function only accepts an 8-bit value for this PIC.
So it's just an accident that you get the correct result by using an
address of 0x2100.
I am bailing on this thread. I'm done. |
|
|
hansknec
Joined: 30 Sep 2004 Posts: 25 Location: Virginia, USA
|
|
Posted: Sun Aug 28, 2005 7:21 pm |
|
|
Well thank you Mr. (or Ms.) PCM programmer. Sorry to see that you are bailing on the thread because you seem to know what you are talking about.
Unfortunately the advice I have recieved thus far did little to actually HELP me with my problem. I was told that I need to use read_program_eeprom() instead of read_eeprom(), but I stated in my original post that it didn't work either. According to what I have been told, the following code would work:
Code: |
#include <16F876A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#org 0x1F00, 0x1FFF void loader16F876(void) {}
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ENABLE=PIN_A4,ERRORS)
#include <input.c>
// EEPROM reading and writing info *********************
#rom 0x2100 = {'9'} //set the initial address to 9 when loading hex file
void main() { //******** MAIN ************************
char address;
address = read_eeprom(0);
do{
printf("\naddress is %c",address);
delay_ms (200);
} while (TRUE);
}
|
It doesn't, and I have a sneaky suspicion that it is because of that #org statement above. Unfortunately for me I'm not savvy enough to read the assembly that the compiler can provide me.
Perhaps someone else could point me in the right direction? I chose 0x2100 as the address because that's what I have used for over a year when I first learned to access the EEPROM. I found it in one of the CCS examples written for an 877. If someone has a better tutorial written somewhere I would love to get pointed in that direction. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Aug 28, 2005 8:19 pm |
|
|
Works for me
Quote: | address is 9
address is 9
address is 9
address is 9
address is 9
address is 9
address is 9
address is 9
address is 9 |
Make sure your programmer is set to program the eeprom. |
|
|
hansknec
Joined: 30 Sep 2004 Posts: 25 Location: Virginia, USA
|
|
Posted: Mon Aug 29, 2005 6:52 am |
|
|
I just got a reply from the designer of the bootloader but I haven't had my coffee yet, so I'm not quite getting it. His comments follow:
_________________________________________________
Hi,
The bootloader, in its current incarnation, doesn't allow
writing/reading of EEPROM. This is partially deliberate - it keeps the
size of the bootloader down to 256 bytes.
However, I havn't ever run into any problems because of this limitation.
Heres the solution:
1. Get reading/writing to eeprom writing without using the bootloader.
2. When the program first starts up, it checks to see if there is a
32-bit or 8-bit identification code present in the EEPROM. If its not
present, write the default configuration into the EEPROM. If it isn't,
assume that its already been written and proceed as per normal.
3. You can extend this idea to have a checksum or CRC that verifies the
validity of the contents of EEPROM on each bootup.
4. EEPROM is very reliable, 100,000 writes/reads would be a conservative
value - see datasheet.
By the way, I noticed that you had NOLVP in the code. Try to avoid this
if you possibly can - see the notes in the latest release of the
bootloader (v9.4).
Regards,
Shane Tolmie (BEng. Elec. Hons.)
www.microchipC.com (webmaster)
_________________________________________________________
I've never had to deal with checksums and CRC, so it's a little greek to me. I think he's telling me to program the EEPROM with my ICD-U40 while I load the bootloader. I'll try to get clarity on this. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Aug 29, 2005 7:11 am |
|
|
No! What he is telling you to do is to have your program write this data into the eeprom. You can have some test checksum, CRC or other that looks at the eeprom on startup and if it detects that the data is not valid, it will program the eeprom through your application code. I always do this just in case the eeprom somehow were to become garbaged. I give the user a way to "reinit" the system which would write configuration data back to the eeprom. Had I used the #rom statement, I wouldn't be able to do this. |
|
|
|
|
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
|