View previous topic :: View next topic |
Author |
Message |
Bill24
Joined: 30 Jun 2012 Posts: 45
|
Speeding up write_program_memory() |
Posted: Tue Jul 17, 2012 1:07 pm |
|
|
Using write_program_memory() on a PIC24 with a clock speed of 20mhz to write decoded lines from a hex file appears very slow. E.G a 32K file downloaded via USB takes several minutes.
Is this a feature of the way write_program_memory() works or is it that PIC24 flash writes are very slow ?
I would like to achieve download speed similar to a USB memory stick. Does anyone know if this is possible ?
TIA
Bill24 |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9219 Location: Greensville,Ontario
|
|
Posted: Tue Jul 17, 2012 1:20 pm |
|
|
You'ld have to consult the datasheet to see if there's a 'block' write mode..IE writing say 512 bytes (a 'block') at one time. I don't use the device so I don't know, but if available it'll definitely speed up things.
I use USB flashdrives through 'Vinculum' modules at 115K200 but can go as high as 3Mbytes if needed.
hth
jay |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1612 Location: Central Illinois, USA
|
|
Posted: Tue Jul 17, 2012 3:14 pm |
|
|
Just curious, when you say "32K" is that 32K lines or 32K in terms of raw bytes for the file?
When I do RS232 bootloading on a PIC18, a 36KB file (it's like 820+ lines), it takes about 10seconds. (at 57,600b/s)
Something's up with the bootloader I would think.
Which bootloader are you using?
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19484
|
|
Posted: Wed Jul 18, 2012 2:11 am |
|
|
Key is what size of block you are writing.
The built in define 'FLASH_WRITE_SIZE', tells you the block size of the chip. You _must_ write to the memory, in multiples of this size, and also starting from addresses that are multiples of this, if you want speed.
If you do, the compiler will automatically use block writes, and it takes basically the same time to write a whole block, as a single byte....
The data sheet does tell you this (indirectly...), with:
"This function is most effective when count is a multiple of FLASH_WRITE_SIZE,".
Best Wishes |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1343
|
|
Posted: Wed Jul 18, 2012 6:02 am |
|
|
One caveat to that:
You can use write_program_memory() to write less than FLASH_WRITE_SIZE, however, the write_program_memory() will fill the unused spaces with 0xFF, and go through the process of writing those 0xFF to the flash write buffer.
So, even if you tell the write_program_memory(), to write 4 bytes, it will still internally write 256 bytes. In order to speed the process of writing program memory up, it is in your best interest to write as many bytes as you can in one go, so you don't waste time writing 0xFF's in the spaces you later put data in.
The only requirement for write_program_memory() is that the data is in multiples of 4bytes and that you issue the erase_program_memory() for a block once if you aren't writing to the start of the current block. |
|
|
Bill24
Joined: 30 Jun 2012 Posts: 45
|
|
Posted: Wed Jul 18, 2012 9:53 am |
|
|
The program downloaded is around 32K bytes. I am basing the code on the CCS example. I think I am going wrong as I am writing 32 bytes at a time. I.E one line of a HEX file, Not one block which on the PIC24 I am using 0x400 words.
Thanks for your suggestion. I have not tried it yet but I believe it will solve the problem. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1612 Location: Central Illinois, USA
|
|
Posted: Wed Jul 18, 2012 10:53 am |
|
|
Bill24 wrote: | The program downloaded is around 32K bytes. I am basing the code on the CCS example. I think I am going wrong as I am writing 32 bytes at a time. I.E one line of a HEX file, Not one block which on the PIC24 I am using 0x400 words.
Thanks for your suggestion. I have not tried it yet but I believe it will solve the problem. |
Yeees... Writing one word at a time is always slower than a line (up to the write buffer size of the PIC - not necessarily the HEX line size which as you know is smaller) at a time. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Jul 18, 2012 12:06 pm |
|
|
I've implemented a PIC24 bootloader in 2008, starting with PCD V4.078. At this time, several bugs have been involved with the pcd_loader.c code and the built-in flash write functions didn't work as apparently assumed in the code.
I rewrote the code, besides other details I implemented a page buffer. Unfortunately I can't tell which of the changes has been obviated by later PCD and example code versions, but I assume, that a page buffer is still essential.
The bootloader is sufficient fast, I didn't see a reason to edit the basic operation. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1343
|
|
Posted: Wed Jul 18, 2012 12:34 pm |
|
|
FvM wrote: | but I assume, that a page buffer is still essential. |
You don't need a page buffer. Just a row buffer. The PIC 24 writes a row a time (64 instuctions = 128 words = 256 bytes). You still have to erase a page at a time though. |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Thu Jul 19, 2012 12:47 am |
|
|
Quote: | You don't need a page buffer. |
I basically agree. If I remember right, I implemented the page buffer to support non-continuous hex files that "jump" between pages. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19484
|
|
Posted: Thu Jul 19, 2012 1:04 am |
|
|
Yes. You need a page buffer if you are going to allow partial writes of pages, since you then have to store the whole page before the erase, and just change the parts you need before writing back.
Best Wishes |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1343
|
|
Posted: Thu Jul 19, 2012 6:00 pm |
|
|
FvM wrote: | I basically agree. If I remember right, I implemented the page buffer to support non-continuous hex files that "jump" between pages. |
That's definitely a good reason. CCS can generate non-continuous hex files, so I definitely have worried about that too. I've tried a couple different routes of my own with good success:
1. Write my own write_program_memory() that doesn't do the erase, then call erase_program_memory() for each page in the user section of flash memory at the beginning of the whole process once. I can then write data to my hearts content. It's a little wasteful on the write cycles if you aren't using most of the user space, but part of me likes how all the user pages have close to the same usage.
2. Write my own write_program_memory() that doesn't do the erase, then keep a list of flags for each page initialized to zero (a bit array works for this). Each time I get a start address I calculate the page it is in, see if the flag is set, and, if not, call erase_program_memory() for that page and set the flag for it so I don't erase it again. |
|
|
|