IAP (In-Application Programming), internal flash erase/write

Information

このページは日本語でも書かれています.日本語版はこのページ後半をご覧ください.
Japanese version is available at later part of this page.

What is this?

This is a sample/demo code for IAP (In-Application Programming) routines which does LPC1768's internal flash memory access.

First of all, I need to mention one thing: The LPC1768 has internal flash memory, it may be not best place to put data.

Because, the mbed has LocalFileSystem and SD-card memory interface already. Those will be the best way to use the big big capacity storages. And it provides easy way to access via file system calls.

Also you may need to care about how the mbed uses the internal flash.

How the mbed uses internal flash?

...because when you load new executable to the mbed (resetting mbed after new code stored in the mbed), the all (chip-internal) flash contents will be cleared and it may need to be protected certain flash memory area from other usage of the program execution (It may need reserve it by defining custom code section or something).

[User can reserve the flash area which you want to access. It can be done by two declarations of USER_FLASH_AREA_START and USER_FLASH_AREA_SIZE in "IAP.h". Improved:20100312]

However, still, the flash may be good when the mbed application which runs on single LPC1768 bare metal without SD-card or other storage devices.

Please find next Notebook page that discuss about how to run the mbed application on other board.

http://mbed.org/users/nxpfan/notebook/mbed-led-blink-code-on-lpcxpresso- lpc1768/

http://mbed.org/users/chris/notebook/prototype-to-hardware/

Code:

This program uses IAP (In-Application Programming) routine on LPC1768 internal ROM.

All details of the IAP can be found on the LPC1768 user manual.

This program demonstrates how to execute blank_check, erase and write the flash memory located in sector 29 (last 32K sector).

In the LPC1768, the 512K bytes flash memory is divided in to 30 sectors (4KB * 16 sectors + 32KB * 14 sectors). The blank_check and erase can be done in those sector by sectors.

Data writing can be done with block size of 256, 512, 1024 or 4096 bytes. No writing allowed across the segment border in a call.

Import programIAP_internal_flash_write

Sample code for how to erase/write LPC1768, LPC11U24, LPC1114, LPC812 and LPC824 internal flash memory. This program uses IAP call of MCU's ROM routines. The IAP library also supports read/write of EEPROM in LPC11U24.

Note:

Please be careful not to overwrite/erase program code which is written on same flash memory.

Normally, the executable image is written from lower side sectors.

This program doesn't use file system interface. Because it may not be good idea to use file system in such small storage space, which takes certain amount of memory blocks(sector/cluster) for its management.

This library provides simple interface to IAP call. The blank_check and erase by sector numbers, and write data by its address and data (block) length.

disable interrupt while IAP is working

Since this library does not enable/disable interrupt, user may need to control it.
Interrupt while IAP, it will be a cause of problem.

The interrupt disable/enable can done by disable_irq() and enable_irq().

reference: https://developer.mbed.org/questions/54146/LPC824-RTOS-and-IAP/

Reference:

mbed (LED blink) code on LPCXpresso-LPC1768 (-LPC1769)
http://mbed.org/users/nxpfan/notebook/mbed-led-blink-code-on-lpcxpresso-lpc1768/

The binary runs on the LPC1768 bare metal
http://mbed.org/users/chris/notebook/prototype-to-hardware/

SystemCoreClock
http://mbed.org/users/simon/programs/SystemCoreClock/16mhsh/

LPC1768 user manual
http://ics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc17xx.pdf

Flash memory address and sectors

Flash memory is placed address range of 0x00000000 - 0x0007FFFF

sector#  start_address   last_address   sector_size
      0     0x00000000  -  0x00000FFF            4K
      1     0x00001000  -  0x00001FFF            4K
      2     0x00002000  -  0x00002FFF            4K
      3     0x00003000  -  0x00003FFF            4K
      4     0x00004000  -  0x00004FFF            4K
      5     0x00005000  -  0x00005FFF            4K
      6     0x00006000  -  0x00006FFF            4K
      7     0x00007000  -  0x00007FFF            4K
      8     0x00008000  -  0x00008FFF            4K
      9     0x00009000  -  0x00009FFF            4K
     10     0x0000A000  -  0x0000AFFF            4K
     11     0x0000B000  -  0x0000BFFF            4K
     12     0x0000C000  -  0x0000CFFF            4K
     13     0x0000D000  -  0x0000DFFF            4K
     14     0x0000E000  -  0x0000EFFF            4K
     15     0x0000F000  -  0x0000FFFF            4K
     16     0x00010000  -  0x00017FFF           32K
     17     0x00018000  -  0x0001FFFF           32K
     18     0x00020000  -  0x00027FFF           32K
     19     0x00028000  -  0x0002FFFF           32K
     20     0x00030000  -  0x00037FFF           32K
     21     0x00038000  -  0x0003FFFF           32K
     22     0x00040000  -  0x00047FFF           32K
     23     0x00048000  -  0x0004FFFF           32K
     24     0x00050000  -  0x00057FFF           32K
     25     0x00058000  -  0x0005FFFF           32K
     26     0x00060000  -  0x00067FFF           32K
     27     0x00068000  -  0x0006FFFF           32K
     28     0x00070000  -  0x00077FFF           32K
     29     0x00078000  -  0x0007FFFF           32K

Table 568. Sectors in a LPC17xx device, User manual (Rev. 01 - 4 January 2010)
2010/03/10initial version
2010/03/12updated for revised code which can have user reserved area
2011/06/24a. some word corrections and rephrase
b. a link has been added for how to run the code on LPCXpresso
2012/02/16page converted new (wiki) format
2012/10/13program link restored, some minor change of words
2015/07/03added a warning of "disable interrupt while IAP is working"



Information

Japanese version follows

これは?

IAP (In-Application Programming) ルーチンを使ってLPC1768の内部フラッシュにアクセスするサンプル/デモです.

まず最初に言っておかなければならないこと..

LPC1768は内部にフラッシュメモリを持っていますが,そこはデータを保存するのに最適な場所とは言えません.

それはmbedにはすでにLocalFileSystemやSDカードといったインターフェースが用意されており,大きな容量とファイルシステム・コールを通した簡単 なアクセス方法が提供されているためです.

また下記のような制限もあり「mbedをmbedとして使う場合」は,LocalFileSystemやSDカードを使うことを推奨します.

「mbedをmbedとして使う場合」内部フラッシュメモリがどのように扱われるか

...mbedでは新しく実行ファイルをダウンロードした時,フラッシュの内容はすべてクリアされてしまいます.また使用するフラッシュの領域は(任意のコードセクシ ョンをを宣言するなどして,そのエリアを確保して)プログラムの実行から保護しなければなりません.

[IAPでアクセスするフラッシュの決まった部分を予約して(取って)おくことが可能です."IAP.h"内のUSER_FLASH_AREA_STARTとUSER _FLASH_AREA_SIZEの二つの宣言を用いてこれを行うことができます.20100312改良]

しかしそれでもフラッシュが良いデータの置き場所になることがあります.mbedアプリケーションがSDカードやその他ストレージデバイス無しの単体のLPC1768 上で実行する場合です.

別のボードでmbedアプリケーションを走らせる方法については次のNotebookページが参考になります.

http://mbed.org/users/nxpfan/notebook/mbed-led-blink-code-on-lpcxpresso-lpc1768/

http://mbed.org/users/chris/notebook/prototype-to-hardware/

コード:

このプログラムはLPC1768の内部ROMに用意されたIAP(In-Application Programming)ルーチンを使います.

IAPの詳細についてはLPC1768のユーザマニュアルを参照してください.

このプログラム例は,フラッシュメモリのセクタ29に対するブランクチェック,消去,書き込みを実行します.

LPC1768のフラッシュメモリは30個のセクタに分かれておりブランクチェック,消去はこのセクタ毎に行えます.

書き込みは1回に256,512,1024または4096バイトのブロック単位で行うことができます.セクタ境界をまたぐ書き込みを1度に行うことはできません.

Import programIAP_internal_flash_write

Sample code for how to erase/write LPC1768, LPC11U24, LPC1114, LPC812 and LPC824 internal flash memory. This program uses IAP call of MCU's ROM routines. The IAP library also supports read/write of EEPROM in LPC11U24.

注意:

同じフラッシュメモリ上にはプログラムが置かれるので,それを消さない/上書きしないように注意が必要です.

通常,実行イメージは下位側のセクタから書かれます.

このプログラムはファイルシステム・インターフェースを使用していません.なぜならファイルシステムを使おうとすると,それを管理するメモリブロック(セクタ/クラス タ)を置く場所が,このような狭いストレージエリア内に必要になるためです.

このためこのライブラリはIAPコールを単純化のみになっています.ブランクチェックと消去はセクタ番号で行い,書き込みはアドレスとデータ(ブロック)長の指定で行 います.

IAP実行中は割り込みを無効化してください

このライブラリ内では割り込みを無効化/有効化することはないので,ユーザがこれを制御しなければなりません.
IAP実行中の割り込みは問題の原因となります.

割り込みの無効化/有効化は disable_irq()enable_irq() によって行うことができます.

参考: https://developer.mbed.org/questions/54146/LPC824-RTOS-and-IAP/

参考資料:

mbed (LED blink) code on LPCXpresso-LPC1768 (-LPC1769)
http://mbed.org/users/nxpfan/notebook/mbed-led-blink-code-on-lpcxpresso-lpc1768/

mbedアプリケーションの単体のLPC1768上での実行
http://mbed.org/users/chris/notebook/prototype-to-hardware/

SystemCoreClock (CPUクロック)
http://mbed.org/users/simon/programs/SystemCoreClock/16mhsh/

LPC1768ユーザマニュアル
http://ics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc17xx.pdf

フラッシュメモリのアドレスとセクタ

Flash memory is placed address range of 0x00000000 - 0x0007FFFF

sector#  start_address   last_address   sector_size
      0     0x00000000  -  0x00000FFF            4K
      1     0x00001000  -  0x00001FFF            4K
      2     0x00002000  -  0x00002FFF            4K
      3     0x00003000  -  0x00003FFF            4K
      4     0x00004000  -  0x00004FFF            4K
      5     0x00005000  -  0x00005FFF            4K
      6     0x00006000  -  0x00006FFF            4K
      7     0x00007000  -  0x00007FFF            4K
      8     0x00008000  -  0x00008FFF            4K
      9     0x00009000  -  0x00009FFF            4K
     10     0x0000A000  -  0x0000AFFF            4K
     11     0x0000B000  -  0x0000BFFF            4K
     12     0x0000C000  -  0x0000CFFF            4K
     13     0x0000D000  -  0x0000DFFF            4K
     14     0x0000E000  -  0x0000EFFF            4K
     15     0x0000F000  -  0x0000FFFF            4K
     16     0x00010000  -  0x00017FFF           32K
     17     0x00018000  -  0x0001FFFF           32K
     18     0x00020000  -  0x00027FFF           32K
     19     0x00028000  -  0x0002FFFF           32K
     20     0x00030000  -  0x00037FFF           32K
     21     0x00038000  -  0x0003FFFF           32K
     22     0x00040000  -  0x00047FFF           32K
     23     0x00048000  -  0x0004FFFF           32K
     24     0x00050000  -  0x00057FFF           32K
     25     0x00058000  -  0x0005FFFF           32K
     26     0x00060000  -  0x00067FFF           32K
     27     0x00068000  -  0x0006FFFF           32K
     28     0x00070000  -  0x00077FFF           32K
     29     0x00078000  -  0x0007FFFF           32K

Table 568. Sectors in a LPC17xx device, User manual (Rev. 01 - 4 January 2010)
2010/03/10initial version
2010/03/12updated for revised code which can have user reserved area
2011/06/24a. some word corrections and rephrase
b. a link has been added for how to run the code on LPCXpresso
2012/02/16page converted new (wiki) format
2012/10/13program link restored, some minor change of words
2015/07/03「IAP実行中は割り込みを無効化してください」の警告を追加


Report
10 Mar 2010

Tedd, that's a very useful addition to MBED!

Question: isn't there any way you could declare variables to reside in flash?

Anders

10 Mar 2010 . Edited: 10 Mar 2010

It's a good question. 
I need someone's help who is an expert for the mbed tool-chain.

Does it allow to reserve arbitrary memory space (by making code section or some other recommended ways)?

...   ...   ...

For this quick sample program, I was assuming nobody will update the flash memory and read the blank space. If this assumption is true, the program may manipulate the sector contents if it was blank. Of course it may be a bad manner but may work for hacking :)

/tedd

10 Mar 2010

You can do it with __attribute__((at(address))) or __attribute__((section(”name”))) with a special name (".ARM.__at_0x8000"). I used it in my UsbHost sample (probably not the best usage but still).

For some reason, at(address) makes the compile fail. The following works and even seems to produce correct code:

unsigned char my_flash_sector[0x80000] __attribute__((section(".ARM.__at_0x78000"), zero_init));

int main( void )
{
  printf("Flash sector byte 0: %02X\n", my_flash_sector[0]);
}

If I try to place it in the middle of the code (e.g. 0x2000), the linker fails. I guess it might be not possible to do without changing the linker control file. But at least you should get a warning in case the compiled code runs into your reserved flash sector.

10 Mar 2010

I'd hoped that I would be able to declare variables as beloning to flash but without having to use absolute addresses.

like

#pragma flash

int i;
char h[100];

#pragma ram

It would (I guess) also require some alignment method since the flash is page-oriented, right?

Anders

10 Mar 2010

If you want your variables placed in the read-only part of the flash, just declare them as const (and set some init value). If you want them to be read-write and flash automatically updated, that's not possible with the current compiler, since it would mean every write to the variable would have to be made into a flash read/update/write call.

10 Mar 2010

Igor, Thank you for great help!

I found the exact sample in your code.
I will try it on my code and update the notebook.

But I have a problem...I'm away for these days. Once I come back, I'll do it. I can try to build the code but no hardware available at this moment :(

I noticed very important thing: I may need to bring the mbed everywhere I go :)

Hello Anders,

Thank you for pointing out the problem. As Igor said, it should be declared as "const" and is not possible to access the flash memory as normal variable located (S)RAM space. That's why we need this IAP interface to erase/write data.

You may find the data can be written if reading-out after writing to flash space, but it may be reading buffered data on cache. The data is not put on flash.

/tedd

10 Mar 2010

But you still need alignment since flash is written as pages, don't you?

I'm sure the compiler has such support.  Tasking's compiler has it at least.

10 Mar 2010

Maybe Tasking has something like that, but not the ARM's compiler.

12 Mar 2010

The program and the notebook has been updated. Thank you for all your support.

12 Mar 2010

Very nice work!

07 Jul 2010 . Edited: 12 Oct 2010


04 Nov 2010

There is something I don't quite understand.

In section 32.3.2.8 of the User Manual it says "Flash programming commands use the top 32 bytes of on-chip RAM." So I would expect that if you

use IAP you have to keep that area free, but I did not see that taken care of in this program.

I added the following line to the program to see where the mem[] array is located: printf("last byte of mem array: 0x%08X\r\n", (uint32_t) &(mem[255]));

which gave the output: "last byte of mem array: 0x10007FEF". So indeed the last 16 bytes of the mem[] array overlap this area.

However, the memory dump indicates that  none of these bytes were changed! Can anybody explain this?

 

 

04 Nov 2010

The use rmanual 32.3.2.8 describes the requirement of stack memory size. That means when an IAP command invoked (called as a function), it will take next 32 bytes on top of the stack memory. So what we need is the stack space for this function call.

It DOESN'T mean the IAP uses last 32 byte space from the RAM space of data source ;-)

05 Nov 2010

Hi Tedd,

It would make a lot of sense if the IAP is implemented this way, but where did you get this information? It means that the user manual should be corrected because it is really saying something different.

By the way, thanks, I'm probably going to use IAP in my application and your example code is very helpful :)

29 Dec 2011 . Edited: 29 Dec 2011
役立つコードの公開ありがとうございます。 (mbedとは別のコンパイル環境で)リンカースクリプトを手直ししてコンパイルしたLPC1768のバイナリーを、 ファイルから読み込み、IAPルーチンを使って Flash ROM を自己書き換えし実行することができました。 独自のブートローダーに応用できそうです。 http://mbed.org/users/okini3939/programs/DynamicLoad/latest
29 Dec 2011 . Edited: 29 Dec 2011

JUMENTUM BASIC HAS DEVISED A CODE WHICH PUTS BASIC PROGRAMMES IN LPC 1768 IN DIFFERENT BLOCKS ,DIFFERENT PROGRAMES  RESIDE IN BLOCKS  0 TO 5 AND CAN BE ACCESSED BY SELECTING A PARTICULAR BLOCK AND RUN

hargovind19@gmail.com

AHMEDABAD

09 Jan 2012

Hi Tedd,

thanks for publishing this. But some questions though: Which format the file "test.dat" must have? How can I find out the entry point of the binary?

09 Jan 2012 . Edited: 09 Jan 2012
Hi Rene,

The IAP is a flash memory writing routine you can write any data in any place of flash memory.
But if you want to program an executable binary and run it, you may need to have some extra work.

Mr. Suga koubou published his code to show the idea for dynamic loading ( 3 comments above http://mbed.org/users/okini3939/programs/DynamicLoad/latest ).
He said the code which was build on off-line environment with modified linker script can be flashed and executed.
I hope that helps what can be done.

18 Jan 2012

Hi Tedd,

Thank you so much to publishing this.. I run IAP_internal_flash_write on mbed, it works well if using sector 29 as target_sector, but get failed when using sector 28, mem_dump shows nothing is writen to sector 28, always 0xFF. It is strange to me.. Do you have any idea about this?

------------------------------------------------------------------------

IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0808160C, CPU running 96000kHz
user reserved flash area: start_address=0x00078000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)
compare result     = "FAILED"
showing the flash contents...
memdump from 0x00070000 for 256 bytes

0x00070000 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070010 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070020 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070030 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070040 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070050 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070060 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070070 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070080 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070090 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700A0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700B0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700C0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700D0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700E0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700F0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF

18 Jan 2012 . Edited: 18 Jan 2012
Hi Jin,

Thank you for using the code.

Can you retry after editing line 22 of "IAP.h"?
It seems the memory area is not reserved.
Please edit the line as "#define USER_FLASH_AREA_START FLASH_SECTOR_28".


I wish I could try to reproduce your problem by myself first, but I left my mbed in my office tonight.


>> user reserved flash area: start_address=0x00078000, size=32768 bytes
>> blank check result = 0x00000000
>> copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)

19 Jan 2012

Hi Tedd,

Test result for "#define USER_FLASH_AREA_START FLASH_SECTOR_28" is same as before, see bellow output.

Additionally, I tested sector 26/27, they work well. So it seems that only sector 28 is a exception.

------------------------Sector 28 --------------------------------------

IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0808160C, CPU running 96000kHz
user reserved flash area: start_address=0x00070000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)
compare result     = "FAILED"
showing the flash contents...
memdump from 0x00070000 for 256 bytes

0x00070000 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070010 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070020 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070030 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070040 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070050 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070060 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070070 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070080 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070090 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700A0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700B0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700C0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700D0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700E0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700F0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF

-------------- Sector 27 --------------------------

IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0808160C, CPU running 96000kHz
user reserved flash area: start_address=0x00068000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00068000) for 256 bytes. (result=0x00000000)
compare result     = "OK"
showing the flash contents...
memdump from 0x00068000 for 256 bytes

0x00068000 : 0x03020100 0x07060504 0x0B0A0908 0x0F0E0D0C
0x00068010 : 0x13121110 0x17161514 0x1B1A1918 0x1F1E1D1C
0x00068020 : 0x23222120 0x27262524 0x2B2A2928 0x2F2E2D2C
0x00068030 : 0x33323130 0x37363534 0x3B3A3938 0x3F3E3D3C
0x00068040 : 0x43424140 0x47464544 0x4B4A4948 0x4F4E4D4C
0x00068050 : 0x53525150 0x57565554 0x5B5A5958 0x5F5E5D5C
0x00068060 : 0x63626160 0x67666564 0x6B6A6968 0x6F6E6D6C
0x00068070 : 0x73727170 0x77767574 0x7B7A7978 0x7F7E7D7C
0x00068080 : 0x83828180 0x87868584 0x8B8A8988 0x8F8E8D8C
0x00068090 : 0x93929190 0x97969594 0x9B9A9998 0x9F9E9D9C
0x000680A0 : 0xA3A2A1A0 0xA7A6A5A4 0xABAAA9A8 0xAFAEADAC
0x000680B0 : 0xB3B2B1B0 0xB7B6B5B4 0xBBBAB9B8 0xBFBEBDBC
0x000680C0 : 0xC3C2C1C0 0xC7C6C5C4 0xCBCAC9C8 0xCFCECDCC
0x000680D0 : 0xD3D2D1D0 0xD7D6D5D4 0xDBDAD9D8 0xDFDEDDDC
0x000680E0 : 0xE3E2E1E0 0xE7E6E5E4 0xEBEAE9E8 0xEFEEEDEC
0x000680F0 : 0xF3F2F1F0 0xF7F6F5F4 0xFBFAF9F8 0xFFFEFDFC

----------------- Sector 26 --------------------------

IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0808160C, CPU running 96000kHz
user reserved flash area: start_address=0x00060000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00060000) for 256 bytes. (result=0x00000000)
compare result     = "OK"
showing the flash contents...
memdump from 0x00060000 for 256 bytes

0x00060000 : 0x03020100 0x07060504 0x0B0A0908 0x0F0E0D0C
0x00060010 : 0x13121110 0x17161514 0x1B1A1918 0x1F1E1D1C
0x00060020 : 0x23222120 0x27262524 0x2B2A2928 0x2F2E2D2C
0x00060030 : 0x33323130 0x37363534 0x3B3A3938 0x3F3E3D3C
0x00060040 : 0x43424140 0x47464544 0x4B4A4948 0x4F4E4D4C
0x00060050 : 0x53525150 0x57565554 0x5B5A5958 0x5F5E5D5C
0x00060060 : 0x63626160 0x67666564 0x6B6A6968 0x6F6E6D6C
0x00060070 : 0x73727170 0x77767574 0x7B7A7978 0x7F7E7D7C
0x00060080 : 0x83828180 0x87868584 0x8B8A8988 0x8F8E8D8C
0x00060090 : 0x93929190 0x97969594 0x9B9A9998 0x9F9E9D9C
0x000600A0 : 0xA3A2A1A0 0xA7A6A5A4 0xABAAA9A8 0xAFAEADAC
0x000600B0 : 0xB3B2B1B0 0xB7B6B5B4 0xBBBAB9B8 0xBFBEBDBC
0x000600C0 : 0xC3C2C1C0 0xC7C6C5C4 0xCBCAC9C8 0xCFCECDCC
0x000600D0 : 0xD3D2D1D0 0xD7D6D5D4 0xDBDAD9D8 0xDFDEDDDC
0x000600E0 : 0xE3E2E1E0 0xE7E6E5E4 0xEBEAE9E8 0xEFEEEDEC
0x000600F0 : 0xF3F2F1F0 0xF7F6F5F4 0xFBFAF9F8 0xFFFEFDFC


19 Jan 2012 . Edited: 19 Jan 2012
Hi Jin,

(1)
I tried. And I found my sector 28 is fine.
I tried it on two mbeds and both of them have no problem.

I believe the LPC1768 does not having sector write/read protect features to IAP routines.
It seems something strange is happening in that chip.

If you (or your friend) have another mbed, Please try again on that.

(2)
By the way, I suggested to modify the line 22 of "IAP.h" yesterday but I was wrong.
The lines 22 and 23 does not affect to the flash writing. I mean you don't need to edit those lines for proper operation.

However, "USER_FLASH_AREA_START" and "USER_FLASH_AREA_SIZE" may need to be defined to prevent corruption.
Without those definitions, the compiler may try to use those sectors for the code or data.
So I recommend to use those but it is not related to this case.

I'm sorry I couldn't remember last night.

The "area reserving" was discussed in this page before.
I put the link to the post
http://mbed.org/users/okano/notebook/iap-in-application-programming-internal-flash-eras/?page=1#comment-271

(3)
Next dump are results of execution on my mbeds. Both of those works fine (without area reserving).

----------------- mbed (1) --------------------------

IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x10100A1F, CPU running 96000kHz
user reserved flash area: start_address=0x00078000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)
compare result = "OK"
showing the flash contents...
memdump from 0x00070000 for 256 bytes
0x00070000 : 0x03020100 0x07060504 0x0B0A0908 0x0F0E0D0C
0x00070010 : 0x13121110 0x17161514 0x1B1A1918 0x1F1E1D1C
0x00070020 : 0x23222120 0x27262524 0x2B2A2928 0x2F2E2D2C
0x00070030 : 0x33323130 0x37363534 0x3B3A3938 0x3F3E3D3C
0x00070040 : 0x43424140 0x47464544 0x4B4A4948 0x4F4E4D4C
0x00070050 : 0x53525150 0x57565554 0x5B5A5958 0x5F5E5D5C
0x00070060 : 0x63626160 0x67666564 0x6B6A6968 0x6F6E6D6C
0x00070070 : 0x73727170 0x77767574 0x7B7A7978 0x7F7E7D7C
0x00070080 : 0x83828180 0x87868584 0x8B8A8988 0x8F8E8D8C
0x00070090 : 0x93929190 0x97969594 0x9B9A9998 0x9F9E9D9C
0x000700A0 : 0xA3A2A1A0 0xA7A6A5A4 0xABAAA9A8 0xAFAEADAC
0x000700B0 : 0xB3B2B1B0 0xB7B6B5B4 0xBBBAB9B8 0xBFBEBDBC
0x000700C0 : 0xC3C2C1C0 0xC7C6C5C4 0xCBCAC9C8 0xCFCECDCC
0x000700D0 : 0xD3D2D1D0 0xD7D6D5D4 0xDBDAD9D8 0xDFDEDDDC
0x000700E0 : 0xE3E2E1E0 0xE7E6E5E4 0xEBEAE9E8 0xEFEEEDEC
0x000700F0 : 0xF3F2F1F0 0xF7F6F5F4 0xFBFAF9F8 0xFFFEFDFC

----------------- mbed (2) --------------------------

IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0C0C081E, CPU running 96000kHz
user reserved flash area: start_address=0x00078000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)
compare result = "OK"
showing the flash contents...
memdump from 0x00070000 for 256 bytes
0x00070000 : 0x03020100 0x07060504 0x0B0A0908 0x0F0E0D0C
0x00070010 : 0x13121110 0x17161514 0x1B1A1918 0x1F1E1D1C
0x00070020 : 0x23222120 0x27262524 0x2B2A2928 0x2F2E2D2C
0x00070030 : 0x33323130 0x37363534 0x3B3A3938 0x3F3E3D3C
0x00070040 : 0x43424140 0x47464544 0x4B4A4948 0x4F4E4D4C
0x00070050 : 0x53525150 0x57565554 0x5B5A5958 0x5F5E5D5C
0x00070060 : 0x63626160 0x67666564 0x6B6A6968 0x6F6E6D6C
0x00070070 : 0x73727170 0x77767574 0x7B7A7978 0x7F7E7D7C
0x00070080 : 0x83828180 0x87868584 0x8B8A8988 0x8F8E8D8C
0x00070090 : 0x93929190 0x97969594 0x9B9A9998 0x9F9E9D9C
0x000700A0 : 0xA3A2A1A0 0xA7A6A5A4 0xABAAA9A8 0xAFAEADAC
0x000700B0 : 0xB3B2B1B0 0xB7B6B5B4 0xBBBAB9B8 0xBFBEBDBC
0x000700C0 : 0xC3C2C1C0 0xC7C6C5C4 0xCBCAC9C8 0xCFCECDCC
0x000700D0 : 0xD3D2D1D0 0xD7D6D5D4 0xDBDAD9D8 0xDFDEDDDC
0x000700E0 : 0xE3E2E1E0 0xE7E6E5E4 0xEBEAE9E8 0xEFEEEDEC
0x000700F0 : 0xF3F2F1F0 0xF7F6F5F4 0xFBFAF9F8 0xFFFEFDFC

20 Jan 2012

Hi Tedd,

Thank you for the detailed comments. I tried on another 2 mbeds(1 of them is totally new), but still got the same problem. The version of my mbeds are "mbed-005.1", not sure if we use different version? Do you have any other idea?

20 Jan 2012
Hi Jin,

My mbeds are same version, those are "mbed-005.1". So it should not have any difference, I believe.

I published my sector28 writing code, just in case.
Please find it in next link.
http://mbed.org/users/okano/programs/__IAP_sector28write/m424vi
20 Jan 2012

Hi Tedd,

I still got the same result on all my 3 mbeds using your new published code for Sector 28, it is really strange..

20 Jan 2012
Hi Jin,

Umm, I have no further idea at this moment...
09 Feb 2012 . Edited: 16 Feb 2012

Hi Tedd,

My colleague got different result on his 2 mbeds using __IAP_sector28write

1st mbed(serial# 0x0606FB0B): FAILED. nothing is written to sector 28

2nd mbed(serial# 0x0B0B160E): OK.

We also check boot code version using IAP command(see bellow read_BootVer()), find that the "good" mbed (sucessfully writing sector28)'s boot code version is 4.1, other failed mbeds are 4.2.

Is there some differences between devices with 4.1 vs. 4.2? Such as

- The boot code itself could have a bug.
- There could be a small change in the chip?
- There could be some subtle change to the board.

Is there a way to upgrade the NXP boot code, or is it in real ROM?

------------------------------------------
int read_BootVer (void) {
IAP_command[0] = IAPCommand_Read_Boot_Code_version;
IAP_result[1] = 0; // not sure if in high or low bits.
iap_entry(IAP_command, IAP_result);
return ((int)IAP_result[1]);
}
------------------------------------------

-------- MBED #1 ----------
IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0606FB0B, CPU running 96000kHz
user reserved flash area: start_address=0x00078000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)
compare result     = "FAILED"
showing the flash contents...
memdump from 0x00070000 for 256 bytes
0x00070000 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070010 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070020 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070030 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070040 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070050 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070060 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070070 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070080 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x00070090 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700A0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700B0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700C0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700D0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700E0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF
0x000700F0 : 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF

-------- MBED #2 ----------
IAP: Flash memory writing test
device-ID = 0x26013F37, serial# = 0x0B0B160E, CPU running 96000kHz
user reserved flash area: start_address=0x00078000, size=32768 bytes
blank check result = 0x00000000
copied: SRAM(0x10007EF0)->Flash(0x00070000) for 256 bytes. (result=0x00000000)
compare result     = "OK"
showing the flash contents...
memdump from 0x00070000 for 256 bytes
0x00070000 : 0x03020100 0x07060504 0x0B0A0908 0x0F0E0D0C
0x00070010 : 0x13121110 0x17161514 0x1B1A1918 0x1F1E1D1C
0x00070020 : 0x23222120 0x27262524 0x2B2A2928 0x2F2E2D2C
0x00070030 : 0x33323130 0x37363534 0x3B3A3938 0x3F3E3D3C
0x00070040 : 0x43424140 0x47464544 0x4B4A4948 0x4F4E4D4C
0x00070050 : 0x53525150 0x57565554 0x5B5A5958 0x5F5E5D5C
0x00070060 : 0x63626160 0x67666564 0x6B6A6968 0x6F6E6D6C
0x00070070 : 0x73727170 0x77767574 0x7B7A7978 0x7F7E7D7C
0x00070080 : 0x83828180 0x87868584 0x8B8A8988 0x8F8E8D8C
0x00070090 : 0x93929190 0x97969594 0x9B9A9998 0x9F9E9D9C
0x000700A0 : 0xA3A2A1A0 0xA7A6A5A4 0xABAAA9A8 0xAFAEADAC
0x000700B0 : 0xB3B2B1B0 0xB7B6B5B4 0xBBBAB9B8 0xBFBEBDBC
0x000700C0 : 0xC3C2C1C0 0xC7C6C5C4 0xCBCAC9C8 0xCFCECDCC
0x000700D0 : 0xD3D2D1D0 0xD7D6D5D4 0xDBDAD9D8 0xDFDEDDDC
0x000700E0 : 0xE3E2E1E0 0xE7E6E5E4 0xEBEAE9E8 0xEFEEEDEC
0x000700F0 : 0xF3F2F1F0 0xF7F6F5F4 0xFBFAF9F8 0xFFFEFDFC

15 comments on IAP (In-Application Programming), internal flash erase/write:

16 Feb 2012

Hi Jin,

First of all, I'm sorry for my very slow response.

Now I could get an mbed which has IAP-boot-code-version 4.2. I tried some codes and confirmed the IAP-write for sector28 has a problem. It seems the ver4.2 code has strong relation to this.

I'll try to get more information and let me come back when I get news.

17 Feb 2012

Hi Jin,

I've got an advice from a friend of mine, we can ask the question to http://www.classic.nxp.com/techsupport/index.php .

17 Feb 2012

Hi Tedd,

Thank you for quick response and suggestion! I have submitted a question to NXP techsupport, I will keep you updated on any feedback from it.

Regards, -Jin

27 Feb 2012

Hi

Whats so special about sector 28 used in this example (besides it's at the top of the memory)? And is it possible to define an array at a fixed memory location in c++ so it's safe to flash and one can access the flashed data easily?

wvd_vegt

28 Feb 2012

Hi Wim,

I'm not sure about what's so special on sector 28 (It's a sector before the last one). That's good idea to define the array for the sectors to manage. My program is just an interface to MCU's internal ROM routine. I'll come back to this idea if I could have time and good idea to make higher level interface.

/tedd

23 Jul 2012

Hello Tedd,

May i know how do you get the mbed to reset and then boot from the program that was just written using your IAP code?

Thank you very much!

24 Jul 2012

Hi AquaMW,

IntelliSense .io wrote:

May i know how do you get the mbed to reset and then boot from the program that was just written using your IAP code?

No you cannot run the program which is written by IAP after resetting the mbed. Because the mbed erases the entire flash memory after reset. That erase 512K space of LPC1768 and your latest .bin file in the mbed-storage is programmed into the flash.

So this IAP can be used only on non-mbed environment. I mean the flash programming may be useful in standalone LPC1768 environment. For the standalone LC1768, please refer to http://mbed.org/users/chris/notebook/prototype-to-hardware/

Even in the standalone environment, you cannot just overwrite the code on the flash. Overwriting will corrupt your program execution.
If you need to execute the binary which you programmed by IAP, you may need to use a mechanism to handle it. Next link may be a good sample to perform the demo http://mbed.org/users/okini3939/notebook/dynamicload/

17 Mar 2013

Hi Tedd, is it possible to use the IAP for KL25Z?

best regards, Reinhold

19 Mar 2013

Hi Reinhold, The flash writing interface on Freescale chip is very different from NXP's. So it cannot be used.

I'm familiar to the IAP on LPC-microcontrollers but not for KL25Z. You may need to implement interface which is described on section 27 of KL25 Sub-Family Reference Manual.

/tedd

13 Jul 2014

hi, I am going to use your code (api.h & api.c) in my project . my project made by IAR compiler and I use an lpc1768 in a very simple pcb board . when I add this files , errors occur in build an the firs one is in

t

class IAP {
public:

also

t

unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init));

in api.c

in api.h . can any one help me ?

22 Mar 2015

How can I store data in flash so that after resetting the mbed micro, the data woun't lost?!

15 Oct 2015

Hi Tedd,

firstly, thanks for this valuable addition to the mbed community, your IAP library has helped greatly with some of my prototyping.

I just have one question regarding the RAM usage of the demo program. Could you explain why, according to the Build program details, that the 'Zero-Initialise' space allocation appears to be maxed out? I apologise if I have missed something fundamental about the operation of your program. Or Perhaps it is a compiler issue?

/media/uploads/ThomasWilson/screen_shot_2015-10-16_at_00.27.44.png

Are others viewing the same RAM report? The program is running flawlessly, I'm just curious about this area (and most probably require some further education).

Cheers, Tom.

10 Feb 2016

Problem with 32k of RAM reported used is the zero-init in IAP.c

The following code is the culprit:

#define     USER_FLASH_AREA_START_STR( x )      STR( x )
#define     STR( x )                            #x
unsigned char user_area[ USER_FLASH_AREA_SIZE ] __attribute__((section( ".ARM.__at_" USER_FLASH_AREA_START_STR( USER_FLASH_AREA_START ) ), zero_init));

This is using a gcc-trick converting a #define to a string within quotes "" as is described here: http://stackoverflow.com/questions/6852920/how-do-i-turn-a-macro-into-a-string-using-cpp

Apparently this results in RAM being zero-init instead of the user-flash. Maybe the string trick from SO only works in gcc?

Fix: Just comment out the whole line or fill in the actual address "0x-something" within the ".ARM.at_" string.

for reference: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0474h/CHDBBAEE.html

17 Nov 2016

Hi, All. I too battled with the issues of declaring an array and compilation problems, memory usage stats etc. Thanks Igor the suggestion it took me quite some way but finally I decided to grab the problem and try something else.

Please see below. I'm using this now with standard const arrays defined in the mbed compiler, a little crunching and a few .....coffees ;)

https://developer.mbed.org/users/aidan1971/notebook/flash-array-programming-using-iap/

17 Nov 2016

I

Please log in to post comments.