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 support@ccsinfo.com

Tiny Bootloader problem
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
fuffkin



Joined: 17 Aug 2005
Posts: 2

View user's profile Send private message

Tiny Bootloader problem
PostPosted: Wed Aug 17, 2005 6:09 pm     Reply with quote

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

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

PostPosted: Wed Aug 17, 2005 7:05 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Aug 17, 2005 8:01 pm     Reply with quote

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

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

RE:
PostPosted: Thu Aug 18, 2005 9:17 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Aug 18, 2005 3:36 pm     Reply with quote

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

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

another bootloader issue
PostPosted: Sun Aug 28, 2005 3:00 pm     Reply with quote

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.) Very Happy
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Aug 28, 2005 3:09 pm     Reply with quote

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

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

Yes, but....
PostPosted: Sun Aug 28, 2005 4:31 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Aug 28, 2005 4:40 pm     Reply with quote

To read the data eeprom at address 0x2100 with the CCS function,
you must do this:

Code:
read_eeprom(0);
hansknec



Joined: 30 Sep 2004
Posts: 25
Location: Virginia, USA

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

I beg to differ
PostPosted: Sun Aug 28, 2005 5:48 pm     Reply with 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.

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

View user's profile Send private message

PostPosted: Sun Aug 28, 2005 6:12 pm     Reply with quote

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

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

PostPosted: Sun Aug 28, 2005 7:21 pm     Reply with quote

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

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

PostPosted: Sun Aug 28, 2005 8:19 pm     Reply with quote

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

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

PostPosted: Mon Aug 29, 2005 6:52 am     Reply with quote

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

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

PostPosted: Mon Aug 29, 2005 7:11 am     Reply with quote

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.
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