View previous topic :: View next topic |
Author |
Message |
LiLou
Joined: 04 Feb 2014 Posts: 26
|
How to erase program memory with bootloader? |
Posted: Thu Feb 27, 2014 4:30 am |
|
|
Having ex_usb_bootloader.c (by ccs), is there an easy way to modify or create a function that erase the program memory? leaving the memory in blank (only with the bootloader).
Regards.
PS: The PIC is 18F4550 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Thu Feb 27, 2014 6:59 am |
|
|
Perhaps the simplest is to just write 0xff to all memory locations,except the bootloader area.If you know the size of the current program in the PIC, just send 0xFF to that amount of space. No need to reprogram 32K if only 1 K is used.
hth
jay |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Fri Feb 28, 2014 7:31 am |
|
|
Yeah, already tried that (partially) , it works. But I would do it in a proper way (educational purposes), as I'm not into the electronic world, but software developer, I would clrify some concepts.
In the CCS manual:
Code: | PROGRAM_MEMORY Size of program memory
READ_PROGRAM Returns 1 if program memory can be read
FLASH_WRITE_SIZE Smallest number of bytes written in flash
FLASH_ERASE_SIZE Smallest number of bytes erased in flash |
I don't get it.
FLASH_ERASE_SIZE is the eeprom memory? 2k?
PROGRAM_MEMORY is the program memory? 32k? |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1346
|
|
Posted: Fri Feb 28, 2014 8:26 am |
|
|
It's worth noting that some of those are sometimes in bytes and sometimes in words. Make sure you know the units for your chip.
FLASH_ERASE_SIZE tells you how big your pages are.
PROGRAM_MEMORY tells you how much program memory up to the configuration fuses.
Again, verify the units of those for your chip as they can be different sometimes. For example, on one of my chips, PROGRAM_MEMORY is in words while FLASH_ERASE_SIZE is in bytes. Don't know if that is true for all chips though.
With that in mind, once you have them in the same units (conversion may be necessary), you can divide the erase size into the program memory go get the total number of pages in your chip's memory. You can then loop through, calling erase_program_memory(addr) for each page by starting with the lowest page address you want to erase, adding the erase size (make sure it is in units that go with your addresses...for my chips this is in words) after each time the loop calls the erase function. Make sure NOT to erase the page that has the fuses. Normally if you calculated you had 10 pages, and indexed them 0 to 9, it would be page 9, but do the math for your chip and make sure. |
|
|
gpsmikey
Joined: 16 Nov 2010 Posts: 588 Location: Kirkland, WA
|
|
Posted: Fri Feb 28, 2014 10:10 am |
|
|
If you don't have it, I would suggest downloading the pdf specifications for the chip in question from Microchip. While not exactly "lite" reading, their spec sheets (all 300+ pages for most chips) are well organized and have sections on memory organization etc. that do show clearly how the chip is organized and usually it becomes much clearer once you look through the appropriate section.
mikey _________________ mikey
-- you can't have too many gadgets or too much disk space !
old engineering saying: 1+1 = 3 for sufficiently large values of 1 or small values of 3 |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Mon Mar 03, 2014 8:58 am |
|
|
Thanks for the responses. When I get some result, I will tell. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Mon Mar 03, 2014 9:37 am |
|
|
Let's go through some things:
First, you can't 'write' 0xFF.
The write operation, can only change bits from '1' to '0'.
To generate 0xFF in a location, you have to erase it. Erase is done in pages (there is a single transistor for each page).
So Jeremiah's comment is spot on. Just erase each page.
It is an erase that basically uses a 'life'.
As well as the section in the processor manual, there is also a separate 'programming' document.
For your chip, the erase is done 64 bytes at a time. So the entire memory can be cleared in 512 erase cycles. Just over 2 seconds (4mSec/cycle).
Since an erase uses a life, check before erasing, that the page does contain something other than 0xFF. Reads don't use lives.
Erases need to take place on page boundaries.
For Jeremiah's 'question/comment: "Don't know if that is true for all chips though. ", the unit, is defined in 'BYTES_PER_ADDRESS'. For your chip, '2'.
Best Wishes |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Tue Mar 04, 2014 10:05 am |
|
|
Ok then. The only function that I think it should be useful for my purpose is this one: erase_program_eeprom(addr)
The name which confuses me It erases program memory? eeprom? I don't understand why is choosen that name.
If that function is the one that I should use, this would be the solution?
Code: | for(i=0x0019; i<getenv("PROGRAM_MEMORY"); i += getenv("FLASH_ERASE_SIZE"))
erase_program_eeprom(i); |
FLASH_ERASE_SIZE is 64 bytes for my chip? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Tue Mar 04, 2014 10:21 am |
|
|
Technically, the program memory is a type of EEPROM (Electrically Erasable Programmable Read Only Memory). The word 'EEPROM', is often reserved for EEPROM's that offer single byte erase, but all memories of this type are really EEPROM's, this is just a 'convenience standard'. Hence the function name.
You need to multiply PROGRAM_MEMORY, by BYTES_PER_ADDRESS. The program memory size is in 'instructions' (words). Bytes per address gives the size of the word. Remember 'i' needs to be an int16.
Best Wishes |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1346
|
|
Posted: Tue Mar 04, 2014 10:37 am |
|
|
Also, your variable i doesn't start on a page boundary. I'm not sure how that will work. On a PIC24 it wouldn't, but I am not familiar with that chip unfortunately. |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Wed Mar 05, 2014 1:43 am |
|
|
I saw that in usb_bootloader.h it says:
Code: | //how big is the bootloader?
//the bootloader will reside from address 0x0000 to this location. the
//application will then sit at this location+1 to the end of program memory.
//#if defined(__DEBUG)
#define LOADER_SIZE (0x1FFF) |
Then I tried:
Code: | #define PROGRAM_MEMORY getenv("PROGRAM_MEMORY") //
#define EEPROM_ERASE_SIZE getenv("FLASH_ERASE_SIZE")
//...
//before writing the program. Executed only once.
for(i=0x2000; i<PROGRAM_MEMORY*2; i += EEPROM_ERASE_SIZE) //2Bytes per word
erase_program_eeprom(i); |
Doesn't work, and the bootloader has broken also, doesn't load. But I didn't touch his memory space |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Thu Mar 13, 2014 6:02 am |
|
|
Tried a dozen of time already, changing the address range, always with the same results (the PIC can't load anything after testing, neither the bootloader)
Let's clarify the purpose of all this, because I'm not sure if what I'm asking is logical or not. In the bootloader it says:
Code: | // Write to Flash ROM.
//
// location - flash program memory address
// src - pointer to data to write
// size - number of bytes to write to flash
//
// Here is the sequence of events:
// 1.) Goes to the beginning of the first erase block for this address
// 2.) Reads n records to ram, where n is the PIC's flash erase size
// 3.) Erases block in flash
// 4.) Modifies block in RAM
// 5.) Writes changed block back to FLASH. Writes in chunks defined by PIC's flash write size
// 6.) Goes back to step1 if there is still more data to be written |
Namely, what it does is erase the number of bytes to be written, yes? Then we have a problem, because if the chip already have a program and we want to load a new one, this new program must occupy not less than the current program in the chip... If we try to write a program that occupy less, it won't work as there is remaining code from the last program.
So from here comes my idea to erase the flash memory before writing. Is there some other method to solve the problem? |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Thu Mar 13, 2014 8:32 am |
|
|
Remember program memory is not erased in bytes, its done in pages of 64bytes on your processor, 1K, 2K, 4k or even 8K words on other types of processor. That's what FLASH_ERASE_SIZE tells you. PIC program memory is often not organised in bytes other than for bootloading purposes, its 12 bit, 14 bit, 16 bit etc. Some "bytes" are actually only a few bits long, especially on 10, 12 and 16 series processors.
It normally doesn't matter if the last program was longer than the new one. Yes, there may be stuff left over, but that's not usually a problem, except in some high reliability/high security applications where a more "complete" erase might be required. If so, then simply erasing all blocks NOT used by the bootloader before writing the actual new program would be the way to go. It'll take longer but that's the price you pay.
Most hex files for code don't have any information about memory the code is NOT using. You can't assume its "blank", whatever that means for your processor. You can only usefully verify, checksum and CRC over the known length of the code, not over all of program memory. Some programmers and bootloaders erase all memory, some allow it as an option, often not selected by default, others just erase memory as required to reduce programming time.
So, what is your application? Are you concerned with code security and IP protection? Or are you interested in code validation and verification?
Thoughts: How big is i in your example? It's got to be at least int16, and int32 for any PIC with more than 64Kbytes of program flash. Otherwise it will wrap round and erase the bootloader. |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Fri Mar 14, 2014 7:41 am |
|
|
How embarrassing... Actually the bootloader works well if I load a program that occupy less than the last one.
The problem was that the programs used to test the bootloader, one of them was using a different include (an older version), the usb_bootloader.h file, which is critical, as this file is responsible to reserve the necessary memory.
Thanks for all guys, and forgive me this awkwardness.
PS: Now I'm looking to erase the eeprom data after a written program. |
|
|
LiLou
Joined: 04 Feb 2014 Posts: 26
|
|
Posted: Tue Mar 18, 2014 9:48 am |
|
|
I tried this before writing the program:
Code: | for(i=getenv("EEPROM_ADDRESS"); i<getenv("EEPROM_ADDRESS")+getenv("DATA_EEPROM"); i+=FLASH_SIZE)
erase_program_eeprom(i); |
After that the program doesn't load/respond. What I'm doing wrong? |
|
|
|