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

Figuring out what this code from Loader.c is doing

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








Figuring out what this code from Loader.c is doing
PostPosted: Tue Jan 04, 2005 2:15 pm     Reply with quote

I am using an 18f8720.

I wanted to modify my bootloader (I know, there are LOTS of them out there) and I was looking at the loader.c file that comes with PICC.
I am having a problem understanding this snippet:

Code:

                if (line_type == 0) {
                  // Loops through all of the data and stores it in data
                  // The last 2 bytes are the check sum, hence buffidx-3
                  for (i = 9,dataidx=0; i < buffidx-3; i += 2)
                     data[dataidx++]=atoi_b16(&buffer[i]);

                  #if getenv("FLASH_ERASE_SIZE")>2
                     #if defined(__PCM__)
                        if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")-1)!=0))
                     #else
                        if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))
                     #endif
                           erase_program_eeprom(addr);
                     next_addr = addr + 1;
                  #endif
                  write_program_memory(addr, data, count);
               }
               else if (line_type == 4)
                  h_addr = make16(atoi_b16(&buffer[9]), atoi_b16(&buffer 11]));
 


The problem I run into is with:
Code:
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))


First note that next_addr is never intialized, but let's assume the compiler always intitializes to 0 unless otherwise told.
The variable addr will probably never start at zero, and when we go through the code (assuming FLASH_ERASE_SIZE is always >2) next_addr is always set to addr+1 which means that addr will probably NEVER equal next_addr and so I can't see why (addr!=next_addr) is part of the if statement.

Let's assume that getenv("FLASH_ERASE_SIZE")/2-1) is 0x1F. This is bits 0 to 5. According to the PIC data sheet, flash erase will only operate on bits 6 to 21, bits 0 to 5 are ignored so if I call erase_program_eeprom with any address of ABC0 to ABDF, the block from ABC0 to ABDF will be erased. Obviously if I erase the block beginning at ABC0 the write 4 bytes of data I DON'T want to call erase again with ABC4 since it will simply erase the whole block beginning at ABC0 again (including the 4 bytes I just put in!)

So you would think that I would want to call erase_program_eeprom only when the address anded with 1f EQUALS zero ( (addr & 0x1f)==0) . The program sample does this when it does NOT equal zero.

Maybe I missed something. I imagine this code works, I never tried it myself but it seems other people have.

Can anyone expalin what I am seeing (or missing) here?

Thanks,
-Pete
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jan 05, 2005 4:47 am     Reply with quote

It looks like a bug to me.

Which compiler version do you have?
Between versions 3.187 and 3.190 the line with 'next_addr = addr +1' was added, so it seems like some last minutes changes were applied to this part of the code.

From the release notes:
Quote:
3.202 Some reported problems with the Bootloader examples are fixed
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Wed Jan 05, 2005 7:19 am     Reply with quote

I'm was using 3.214, I just upgraded to 3.215.
_________________
-Pete
ckielstra



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

View user's profile Send private message

PostPosted: Wed Jan 05, 2005 8:38 am     Reply with quote

I cracked it:
In an Intel-hex file it is allowed to have multiple data blocks. It is possible for these data blocks to have 'holes' in between.

The function write_program_memory will perform the erase automatically when the start address is a multiple of FLASH_ERASE_SIZE. The if-statement handles the special situations where there is a 'hole' in the hex-file with the new data block not starting at the FLASH_ERASE_SIZE multiple.
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

Re: Figuring out what this code from Loader.c is doing
PostPosted: Wed Jan 05, 2005 8:47 am     Reply with quote

Anonymous wrote:


The problem I run into is with:
Code:
if ((addr!=next_addr)&&(addr&(getenv("FLASH_ERASE_SIZE")/2-1)!=0))


Let's assume that getenv("FLASH_ERASE_SIZE")/2-1) is 0x1F. This is bits 0 to 5. According to the PIC data sheet, flash erase will only operate on bits 6 to 21, bits 0 to 5 are ignored so if I call erase_program_eeprom with any address of ABC0 to ABDF, the block from ABC0 to ABDF will be erased. Obviously if I erase the block beginning at ABC0 the write 4 bytes of data I DON'T want to call erase again with ABC4 since it will simply erase the whole block beginning at ABC0 again (including the 4 bytes I just put in!)

So you would think that I would want to call erase_program_eeprom only when the address anded with 1f EQUALS zero ( (addr & 0x1f)==0) . The program sample does this when it does NOT equal zero.


Here I am answering part of my own post....
First of all 0x1F is NOT bits 0 to 5. That would be 0x3F. I don't know why the FLASH_ERASE_SIZE is divided by two before anding with the addr BUT I did discover what is happening in general. ERASE_PROGRAM_EPROM is needed ONLY if the address given to WRITE_PROGRAM_MEMORY is NOT on a block. WRITE_PROGRAM_MEMORY will automatically erase a block if it starts on a block, so you don't have to do it manually.

Now, why divide FLASH_ERASE_SIZE by two (which seems wrong)? And what purpose does next_addr serve?

-Pete
_________________
-Pete
pfournier



Joined: 30 Sep 2003
Posts: 89

View user's profile Send private message

PostPosted: Wed Jan 05, 2005 8:54 am     Reply with quote

ckielstra

We must have been replying at the same time! I didn't see your post until I submitted my own.

Example code needs more comments!
_________________
-Pete
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