Mercurial > flash_v2
diff packages/io/flash/current/doc/flash.sgml @ 1672:304f194b1c78
First draft version of documentation.
| author | asl |
|---|---|
| date | Sat, 19 Jun 2004 19:22:30 +0000 |
| parents | |
| children | 3845779eca10 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/io/flash/current/doc/flash.sgml @@ -0,0 +1,310 @@ +<!-- {{{ Banner --> + +<!-- =============================================================== --> +<!-- --> +<!-- flash.sgml --> +<!-- --> +<!-- eCos FLASH support --> +<!-- --> +<!-- =============================================================== --> +<!-- ####COPYRIGHTBEGIN#### --> +<!-- --> +<!-- =============================================================== --> +<!-- Copyright (C) 2004 Andrew Lunn --> +<!-- This material may be distributed only subject to the terms --> +<!-- and conditions set forth in the Open Publication License, v1.0 --> +<!-- or later (the latest version is presently available at --> +<!-- http://www.opencontent.org/openpub/) --> +<!-- Distribution of the work or derivative of the work in any --> +<!-- standard (paper) book form is prohibited unless prior --> +<!-- permission obtained from the copyright holder --> +<!-- =============================================================== --> +<!-- --> +<!-- ####COPYRIGHTEND#### --> +<!-- =============================================================== --> +<!-- #####DESCRIPTIONBEGIN#### --> +<!-- --> +<!-- ####DESCRIPTIONEND#### --> +<!-- =============================================================== --> + +<!-- }}} --> + +<PART id="io-flash"> +<TITLE>FLASH Library</TITLE> +<CHAPTER id="ecos-flash-library"> +<TITLE>The eCos FLASH Library</TITLE> +<PARA>The FLASH library is an optional part of eCos, and is only + applicable to some platforms.</PARA> +<SECT1 id="flash-library"> +<TITLE>FLASH Library</TITLE> + +<PARA>The eCos FLASH library provides the following functionality:</PARA> + +<orderedlist> +<listitem><PARA>Identifying installed device of a FLASH family. + </PARA> +</listitem> +<listitem><PARA>Read, erasing and writing to FLASH blocks.</PARA></listitem> +<listitem><PARA>Validating an address is within the FLASH.</PARA></listitem> +<listitem><PARA>Determining the number and size of FLASH blocks. + <PARA></listitem> +</orderedlist> + +<PARA> +The library has a number of limitations:</PARA> + +<orderedlist> +<listitem><PARA>Only one family of FLASH device may be supported at once. + </PARA> +</listitem> +<listitem><PARA>Multiple devices of one family are supported, but they must + be contiguous in memory. + </PARA> +</listitem> +<listitem><PARA>The library is not thread or interrupt safe under + some conditions. + </PARA> +</listitem> +<listitem><PARA>The library currently does not use the eCos naming + convention for its functions. This may change in the + future but backward compatibility is likely to be kept. + </PARA> +</listitem> +</orderedlist> + +<PARA>All of the functions described below are declared in the header +file <filename><cyg/io/flash.h.h></filename> which all users of +the FLASH library should include.</PARA> + +<SECT2> +<TITLE>Initializing the FLASH library</TITLE> + +<PARA>The FLASH library needs to be initialized before other FLASH +operations can be performed. This only needs to be done once. The +following function will only do the initialization once so it's safe +to call multiple times: </PARA> + +<PROGRAMLISTING>externC int flash_init( _printf *pf ); typedef int +_printf(const char *fmt, ...); </PROGRAMLISTING> + +<PARA> +The parameter <parameter>pf</parameter> is a pointer to a function +which is to be used for diagnostic output. Typically the function +<function>diag_printf()</function> will be passed. Normally this +function is not used by the higher layer of the library unless +<literal>CYGSEM_IO_FLASH_CHATTER</literal> is enabled. Passing a +<parameter>NULL</parameter> is not recommended, even when +CYGSEM_IO_FLASH_CHATTER is disabled. The lower layers of the library +may unconditionally call this function, especially when errors occur, +probably resulting in a more serious error/crash!.</PARA> +</SECT2> + +<SECT2> +<TITLE>Retrieving information about the FLASH</TITLE> + +<PARA> +The following four functions return information about the FLASH. +</PARA> + +<PROGRAMLISTING>externC int flash_get_block_info(int *block_size, int *blocks); +externC int flash_get_limits(void *target, void **start, void **end); +externC int flash_verify_addr(void *target); +externC bool flash_code_overlaps(void *start, void *end); +</PROGRAMLISTING> + +<PARA> +The function <FUNCTION>flash_get_block_info()</FUNCTION> returns the +size and number of blocks. When the device has a mixture of block +sizes, the size of the "normal" block will be returned. Please read +the source code to determine exactly what this means. +<FUNCTION>flash_get_limits()</FUNCTION> returns the lower and upper +memory address the FLASH occupies. The <PARAMETER>target</PARAMETER> +parameter is current unused. <FUNCTION> flash_verify_addr() +</FUNCTION> tests if the target addresses is within the flash, +returning <LITERAL>FLASH_ERR_OK</LITERAL> if so. Lastly, <FUNCTION> +flash_code_overlaps() </FUNCTION> checks if the executing code is +resident in the section of flash indicated by +<PARAMETER>start</PARAMETER> and <PARAMETER> end</PARAMETER>. If this +function returns true, erase and program operations within this range +are very likely to cause the target to crash and burn horribly. Note +the FLASH library does allow you to shoot yourself in the foot in this +way.</PARA> + +</SECT2> +<SECT2> + +<TITLE>Reading from FLASH</TITLE> + +<PARA> +There are two methods for reading from FLASH. The first is to use the +following function. </PARA> + +<PROGRAMLISTING> +externC int flash_read(void *flash_base, void *ram_base, int len, void **err_address); +</PROGRAMLISTING> + +<PARA> +<PARAMETER>flash_base</PARAMETER> is where in the flash to read +from. <PARAMETER>ram_base</PARAMETER> indicates where the data read +from flash should be placed into RAM. <PARAMETER>len</PARAMETER> is +the number of bytes to be read from the FLASH and +<PARAMETER>err_address</PARAMETER> is used to return the location in +FLASH that any error occurred while reading. +</PARA> + +<PARA> +The second method is to simply <FUNCTION>memcpy()</FUNCTION> directly +from the FLASH. This is not recommended since some types of device +cannot be read in this way, eg NAND FLASH. Using the FLASH library +function to read the FLASH will always work so making it easy to port +code from one FLASH device to another. +</PARA> + +</SECT2> +<SECT2> + +<TITLE>Erasing areas of FLASH</TITLE> + +<PARA> +Blocks of FLASH can be erased using the following function: +</PARA> + +<PROGRAMLISTING>externC int flash_erase(void *flash_base, int len, void **err_address); +</PROGRAMLISTING> + +<PARA> +<PARAMETER>flash_base</PARAMETER> is where in the flash to erase +from. <PARAMETER>len</PARAMETER> is the minimum number of bytes to +erase in the FLASH and <PARAMETER>err_address</PARAMETER> is used to +return the location in FLASH that any error occurred while erasing. It +should be noted that FLASH devices are block oriented when erasing. It +is not possible to erase a few bytes within a block, the whole block +will be erased. <PARAMETER>flash_base</PARAMETER> may be anywhere +within the first block to be erased and <PARAMETER>flash_base+len +</PARAMETER> maybe anywhere in the last block to be erased. </PARA> + +</SECT2> +<SECT2> + +<TITLE>Programming the FLASH</TITLE> + +<PARA> Programming of the flash is achieved using the following +function.</PARA> + +<PROGRAMLISTING>externC int flash_program(void *flash_base, void *ram_base, int len, void **err_address); +</PROGRAMLISTING> + +<PARA> +<PARAMETER>flash_base</PARAMETER> is where in the flash to program +from. <PARAMETER>ram_base</PARAMETER> indicates where the data to be +programmed into FLASH should be read from in RAM. <PARAMETER>len +</PARAMETER> is the number of bytes to be program into the FLASH and +<PARAMETER>err_address</PARAMETER> is used to return the location in +FLASH that any error occurred while programming. </PARA> + +</SECT2> +<SECT2> + +<TITLE>Locking and unlocking blocks</TITLE> + +<PARA> +Some flash devices have the ability to lock and unlock blocks. A +locked block cannot be erased or programmed without it first being +unlocked. For devices which support this feature and when <LITERAL> +CYGHWR_IO_FLASH_BLOCK_LOCKING</LITERAL> is enabled then the following +two functions are available:</PARA> + +<PROGRAMLISTING> +externC int flash_lock(void *flash_base, int len, void **err_address); +externC int flash_unlock(void *flash_base, int len, void **err_address); +</PROGRAMLISTING> + +</SECT2> +<SECT2> + +<TITLE>Return values and errors</TITLE> + +<PARA>All the functions above, except <FUNCTION>flash_code_overlaps() +</FUNCTION> return one of the following return values.</PARA> + +<PROGRAMLISTING> +FLASH_ERR_OK No error - operation complete +FLASH_ERR_INVALID Invalid FLASH address +FLASH_ERR_ERASE Error trying to erase +FLASH_ERR_LOCK Error trying to lock/unlock +FLASH_ERR_PROGRAM Error trying to program +FLASH_ERR_PROTOCOL Generic error +FLASH_ERR_PROTECT Device/region is write-protected +FLASH_ERR_NOT_INIT FLASH info not yet initialized +FLASH_ERR_HWR Hardware (configuration?) problem +FLASH_ERR_ERASE_SUSPEND Device is in erase suspend mode +FLASH_ERR_PROGRAM_SUSPEND Device is in program suspend mode +FLASH_ERR_DRV_VERIFY Driver failed to verify data +FLASH_ERR_DRV_TIMEOUT Driver timed out waiting for device +FLASH_ERR_DRV_WRONG_PART Driver does not support device +FLASH_ERR_LOW_VOLTAGE Not enough juice to complete job +</PROGRAMLISTING> + +<PARA>To turn an error code into a human readable string the following +function can be used:</PARA> + +<PROGRAMLISTING>externC char *flash_errmsg(int err); +</PROGRAMLISTING> +</SECT2> + +<SECT2> + +<TITLE> Notes on using the FLASH library</TITLE> + +<PARA> +The FLASH library evolved from the needs and environment of RedBoot +rather than being a general purpose eCos component. This history +explains some of the problems with the library. </PARA> + +<PARA>The library is not thread safe. Multiple simultaneous calls to +its library functions will likely fail and may cause a crash. It is +the callers responsibility to use the necessary mutex's if needed. +<PARA> + +<PARA>FLASH devices cannot be read from when an erase or write +operation is active. This means it is not possible to execute code +from flash while an erase or write operation is active. It is possible +to use the library when the executable image is resident in FLASH. The +low level drivers are written such that the linker places the +functions that actually manipulate the flash into RAM. However the +library may not be interrupt safe. An interrupt must not cause +execution of code that is resident in FLASH. This may be the image +itself, or RedBoot. In some configurations of eCos, ^C on the serial +port or debugging via Ethernet may cause an interrupt handler to call +RedBoot. If RedBoot is resident in FLASH this will cause a crash. +Similarly, if another thread invokes a virtual vector function to +access RedBoot, eg to perform a <FUNCTION>diag_printf()</FUNCTION> a +crash could result. +</PARA> + +<PARA> Thus with a ROM based image or a ROM based Redboot it is +recommended to disable interrupts while erasing or programming +flash. Using both a ROMRAM or RAM images and a ROMRAM or RAM RedBoot +are safe and there is no need to disable interrupts. Similarly, +</PARA> + +</SECT2> +<SECT2> + +<TITLE>Danger, Will Robinson! Danger!</TITLE> + +<PARA>Unlike nearly every other aspect of embedded system programming, +getting it wrong with FLASH devices can render your target system +useless. Most targets have a boot loader in the FLASH. Without this +boot loader the target will obviously not boot. So before starting to +play with this library its worth investigating a few things. How do +you recover your target if you delete the boot loader? Do you have the +necessary JTAG cable? Or is specialist hardware needed? Is it even +possible to recover the target boards or must it be thrown into the +rubbish bin? How does killing the board affect your project schedule? +</PARA> + +</SECT2> +</SECT1> +</CHAPTER> +</PART>
