|
1672
|
1 <!-- {{{ Banner --> |
|
|
2 |
|
|
3 <!-- =============================================================== --> |
|
|
4 <!-- --> |
|
|
5 <!-- flash.sgml --> |
|
|
6 <!-- --> |
|
|
7 <!-- eCos FLASH support --> |
|
|
8 <!-- --> |
|
|
9 <!-- =============================================================== --> |
|
|
10 <!-- ####COPYRIGHTBEGIN#### --> |
|
|
11 <!-- --> |
|
|
12 <!-- =============================================================== --> |
|
|
13 <!-- Copyright (C) 2004 Andrew Lunn --> |
|
|
14 <!-- This material may be distributed only subject to the terms --> |
|
|
15 <!-- and conditions set forth in the Open Publication License, v1.0 --> |
|
|
16 <!-- or later (the latest version is presently available at --> |
|
|
17 <!-- http://www.opencontent.org/openpub/) --> |
|
|
18 <!-- Distribution of the work or derivative of the work in any --> |
|
|
19 <!-- standard (paper) book form is prohibited unless prior --> |
|
|
20 <!-- permission obtained from the copyright holder --> |
|
|
21 <!-- =============================================================== --> |
|
|
22 <!-- --> |
|
|
23 <!-- ####COPYRIGHTEND#### --> |
|
|
24 <!-- =============================================================== --> |
|
|
25 <!-- #####DESCRIPTIONBEGIN#### --> |
|
|
26 <!-- --> |
|
|
27 <!-- ####DESCRIPTIONEND#### --> |
|
|
28 <!-- =============================================================== --> |
|
|
29 |
|
|
30 <!-- }}} --> |
|
|
31 |
|
|
32 <PART id="io-flash"> |
|
|
33 <TITLE>FLASH Library</TITLE> |
|
|
34 <CHAPTER id="ecos-flash-library"> |
|
|
35 <TITLE>The eCos FLASH Library</TITLE> |
|
|
36 <PARA>The FLASH library is an optional part of eCos, and is only |
|
|
37 applicable to some platforms.</PARA> |
|
|
38 <PARA>The eCos FLASH library provides the following functionality:</PARA> |
|
|
39 |
|
|
40 <orderedlist> |
|
|
41 <listitem><PARA>Identifying installed device of a FLASH family. |
|
|
42 </PARA> |
|
|
43 </listitem> |
|
|
44 <listitem><PARA>Read, erasing and writing to FLASH blocks.</PARA></listitem> |
|
|
45 <listitem><PARA>Validating an address is within the FLASH.</PARA></listitem> |
|
|
46 <listitem><PARA>Determining the number and size of FLASH blocks. |
|
|
47 <PARA></listitem> |
|
|
48 </orderedlist> |
|
|
49 |
|
1706
|
50 <PARA> There are two APIs with the flash library. The old API is |
|
|
51 retained for backwards compatibility reasons, but should slowly be |
|
|
52 replaced with the new API which is much more flexible and does not |
|
|
53 pollute the name space as much. |
|
|
54 </PARA> |
|
|
55 |
|
|
56 <SECT1> |
|
|
57 <TITLE>Notes on using the FLASH library</TITLE> |
|
|
58 |
|
|
59 <PARA>FLASH devices cannot be read from when an erase or write |
|
|
60 operation is active. This means it is not possible to execute code |
|
|
61 from flash while an erase or write operation is active. It is possible |
|
|
62 to use the library when the executable image is resident in FLASH. The |
|
|
63 low level drivers are written such that the linker places the |
|
|
64 functions that actually manipulate the flash into RAM. However the |
|
|
65 library may not be interrupt safe. An interrupt must not cause |
|
|
66 execution of code that is resident in FLASH. This may be the image |
|
|
67 itself, or RedBoot. In some configurations of eCos, ^C on the serial |
|
|
68 port or debugging via Ethernet may cause an interrupt handler to call |
|
|
69 RedBoot. If RedBoot is resident in FLASH this will cause a crash. |
|
|
70 Similarly, if another thread invokes a virtual vector function to |
|
|
71 access RedBoot, eg to perform a <FUNCTION>diag_printf()</FUNCTION> a |
|
|
72 crash could result. |
|
|
73 </PARA> |
|
|
74 |
|
|
75 <PARA> Thus with a ROM based image or a ROM based Redboot it is |
|
|
76 recommended to disable interrupts while erasing or programming |
|
|
77 flash. Using both a ROMRAM or RAM images and a ROMRAM or RAM RedBoot |
|
|
78 are safe and there is no need to disable interrupts. Similarly, |
|
|
79 </PARA> |
|
|
80 </SECT1> |
|
|
81 |
|
|
82 <SECT1> |
|
|
83 <TITLE>Danger, Will Robinson! Danger!</TITLE> |
|
|
84 |
|
|
85 <PARA>Unlike nearly every other aspect of embedded system programming, |
|
|
86 getting it wrong with FLASH devices can render your target system |
|
|
87 useless. Most targets have a boot loader in the FLASH. Without this |
|
|
88 boot loader the target will obviously not boot. So before starting to |
|
|
89 play with this library its worth investigating a few things. How do |
|
|
90 you recover your target if you delete the boot loader? Do you have the |
|
|
91 necessary JTAG cable? Or is specialist hardware needed? Is it even |
|
|
92 possible to recover the target boards or must it be thrown into the |
|
|
93 rubbish bin? How does killing the board affect your project schedule? |
|
|
94 </PARA> |
|
|
95 |
|
|
96 </SECT1> |
|
|
97 </CHAPTER> |
|
|
98 |
|
|
99 <CHAPTER id="ecos-flash-v2"> |
|
|
100 <TITLE>The Version 2 eCos FLASH API</TITLE> |
|
|
101 |
|
|
102 <PARA> There are two APIs described here. The first is the application |
|
|
103 API which programs should use. The second API is that between the |
|
|
104 FLASH IO library and the device drivers. </PARA> |
|
|
105 |
|
|
106 <SECT1 id="ecos-flash-v2-api"> |
|
|
107 <TITLE>FLASH user API</TITLE> |
|
|
108 <PARA> |
|
|
109 |
|
|
110 <PARA>All of the functions described below are declared in the header |
|
|
111 file <filename><cyg/io/flash.h.h></filename> which all users of |
|
|
112 the FLASH library should include.</PARA> |
|
|
113 |
|
|
114 <SECT2> |
|
|
115 <TITLE>Initializing the FLASH library</TITLE> |
|
|
116 |
|
|
117 <PARA>The FLASH library needs to be initialized before other FLASH |
|
|
118 operations can be performed. This only needs to be done once. The |
|
|
119 following function will only do the initialization once so it's safe |
|
|
120 to call multiple times: </PARA> |
|
|
121 |
|
|
122 <PROGRAMLISTING>__externC int cyg_flash_init(const cyg_flash_printf *pf); |
|
|
123 typedef int cyg_flash__printf(const char *fmt, ...); </PROGRAMLISTING> |
|
|
124 |
|
|
125 <PARA> |
|
|
126 The parameter <parameter>pf</parameter> is a pointer to a function |
|
|
127 which is to be used for diagnostic output. Typically the function |
|
|
128 <function>diag_printf()</function> will be passed. Normally this |
|
|
129 function is not used by the higher layer of the library unless |
|
|
130 <literal>CYGSEM_IO_FLASH_CHATTER</literal> is enabled. Passing a |
|
|
131 <parameter>NULL</parameter> is not recommended, even when |
|
|
132 CYGSEM_IO_FLASH_CHATTER is disabled. The lower layers of the library |
|
|
133 may unconditionally call this function, especially when errors occur, |
|
|
134 probably resulting in a more serious error/crash!.</PARA> |
|
|
135 </SECT2> |
|
|
136 |
|
|
137 <SECT2> |
|
|
138 <TITLE>Retrieving information about FLASH devices</TITLE> |
|
|
139 |
|
|
140 <PARA> |
|
|
141 The following five functions return information about the FLASH. |
|
|
142 </PARA> |
|
|
143 |
|
|
144 <PROGRAMLISTING> |
|
|
145 __externC int cyg_flash_get_info(cyg_uint32 devno, cyg_flash_info_t * info); |
|
|
146 __externC int cyg_flash_get_info_addr(cyg_flashaddr_t flash_base, cyg_flash_info_t * info); |
|
|
147 __externC int cyg_flash_verify_addr(const flashaddr_t address); |
|
|
148 __externC int cyg_flash_code_overlaps(const flashaddr_t start, const flashaddr_t end); |
|
|
149 __extern size_t cyg_flash_block_size(const cyg_flashaddr_t flash_base); |
|
|
150 |
|
|
151 typedef struct cyg_block_info |
|
|
152 size_t block_size; |
|
|
153 cyg_unit32 blocks; |
|
|
154 } cyg_block_info_t; |
|
|
155 |
|
|
156 typedef struct { |
|
|
157 flashaddr_t start; // First address |
|
|
158 flashaddr_t end; // Last address |
|
|
159 cyg_uint32 num_block_infos // Number of entries |
|
|
160 cyg_block_info_t *blocks_info; // Info about one block size |
|
|
161 } cyg_flash_info_t; |
|
|
162 </PROGRAMLISTING> |
|
|
163 |
|
|
164 <PARA><FUNCTION>cyg_flash_get_info()</FUNCTION> is the main function |
|
|
165 to get information about installed flash devices. Parameter |
|
|
166 <PARAMETER>devno</PARAMETER> is used to iterate over the available |
|
|
167 flash devices, starting from 0. If the devno'th device exists, the |
|
|
168 structure pointed to by <PARAMETER>info</PARAMETER> is filled in and |
|
|
169 <LITERAL>CYG_FLASH_ERR_OK</LITERAL> is returned, otherwise |
|
|
170 <LITERAL>CYG_FLASH_ERR_INVALID</LITERAL>. |
|
|
171 <FUNCTION>cyg_flash_get_info()</FUNCTION> if similar, but returns the |
|
|
172 information about the flash device at the given address. |
|
|
173 <FUNCTION>cyg_flash_block_size()</FUNCTION> returns the size of the |
|
|
174 block at the given address. <FUNCTION>cyg_flash_verify_addr() |
|
|
175 </FUNCTION> tests if the target addresses is within one of the FLASH |
|
|
176 devices, returning <LITERAL>CYG_FLASH_ERR_OK </LITERAL> if so. |
|
|
177 <FUNCTION> cyg_flash_code_overlaps() </FUNCTION> checks if the |
|
|
178 executing code is resident in the section of flash indicated by |
|
|
179 <PARAMETER>start</PARAMETER> and <PARAMETER> end </PARAMETER>. If |
|
|
180 this function returns <LITERAL>CYG_FLASH_ERR_OK</LITERAL> the code is |
|
|
181 inside the address refion given. Erase and program operations within |
|
|
182 this range are very likely to cause the target to crash and burn |
|
|
183 horribly. Note the FLASH library does allow you to shoot yourself in |
|
|
184 the foot in this way.</PARA> |
|
|
185 </SECT2> |
|
|
186 <SECT2> |
|
|
187 |
|
|
188 <TITLE>Reading from FLASH</TITLE> |
|
|
189 |
|
|
190 <PARA> |
|
|
191 There are two methods for reading from FLASH. The first is to use the |
|
|
192 following function. </PARA> |
|
|
193 |
|
|
194 <PROGRAMLISTING> |
|
|
195 __externC int cyg_flash_read(flashaddr_t *flash_base, const void *ram_base, const size_t len, flashaddr_t **err_address); |
|
|
196 </PROGRAMLISTING> |
|
|
197 |
|
|
198 <PARA> |
|
|
199 <PARAMETER>flash_base</PARAMETER> is where in the flash to read |
|
|
200 from. <PARAMETER>ram_base</PARAMETER> indicates where the data read |
|
|
201 from flash should be placed into RAM. <PARAMETER>len</PARAMETER> is |
|
|
202 the number of bytes to be read from the FLASH and |
|
|
203 <PARAMETER>err_address</PARAMETER> is used to return the location in |
|
|
204 FLASH that any error occurred while reading. |
|
|
205 </PARA> |
|
|
206 |
|
|
207 <PARA> |
|
|
208 The second method is to simply <FUNCTION>memcpy()</FUNCTION> directly |
|
|
209 from the FLASH. This is not recommended since some types of device |
|
|
210 cannot be read in this way, eg NAND FLASH. Using the FLASH library |
|
|
211 function to read the FLASH will always work so making it easy to port |
|
|
212 code from one FLASH device to another. |
|
|
213 </PARA> |
|
|
214 |
|
|
215 </SECT2> |
|
|
216 <SECT2> |
|
|
217 |
|
|
218 <TITLE>Erasing areas of FLASH</TITLE> |
|
|
219 |
|
|
220 <PARA> |
|
|
221 Blocks of FLASH can be erased using the following function: |
|
|
222 </PARA> |
|
|
223 |
|
|
224 <PROGRAMLISTING>__externC int cyg_flash_erase(flashaddr_t *flash_base, const size_t len, flashaddr_t **err_address); |
|
|
225 </PROGRAMLISTING> |
|
|
226 |
|
|
227 <PARA> |
|
|
228 <PARAMETER>flash_base</PARAMETER> is where in the flash to erase |
|
|
229 from. <PARAMETER>len</PARAMETER> is the minimum number of bytes to |
|
|
230 erase in the FLASH and <PARAMETER>err_address</PARAMETER> is used to |
|
|
231 return the location in FLASH that any error occurred while erasing. It |
|
|
232 should be noted that FLASH devices are block oriented when erasing. It |
|
|
233 is not possible to erase a few bytes within a block, the whole block |
|
|
234 will be erased. <PARAMETER>flash_base</PARAMETER> may be anywhere |
|
|
235 within the first block to be erased and <PARAMETER>flash_base+len |
|
|
236 </PARAMETER> maybe anywhere in the last block to be erased. </PARA> |
|
|
237 |
|
|
238 </SECT2> |
|
|
239 <SECT2> |
|
|
240 |
|
|
241 <TITLE>Programming the FLASH</TITLE> |
|
|
242 |
|
|
243 <PARA> Programming of the flash is achieved using the following |
|
|
244 function.</PARA> |
|
|
245 |
|
|
246 <PROGRAMLISTING>__externC int cyg_flash_program(const flashaddr_t *flash_base, void *ram_base, const size_t len, flashaddr_t **err_address); |
|
|
247 </PROGRAMLISTING> |
|
|
248 |
|
|
249 <PARA> |
|
|
250 <PARAMETER>flash_base</PARAMETER> is where in the flash to program |
|
|
251 from. <PARAMETER>ram_base</PARAMETER> indicates where the data to be |
|
|
252 programmed into FLASH should be read from in RAM. <PARAMETER>len |
|
|
253 </PARAMETER> is the number of bytes to be program into the FLASH and |
|
|
254 <PARAMETER>err_address</PARAMETER> is used to return the location in |
|
|
255 FLASH that any error occurred while programming. </PARA> |
|
|
256 |
|
|
257 </SECT2> |
|
|
258 <SECT2> |
|
|
259 |
|
|
260 <TITLE>Locking and unlocking blocks</TITLE> |
|
|
261 |
|
|
262 <PARA> |
|
|
263 Some flash devices have the ability to lock and unlock blocks. A |
|
|
264 locked block cannot be erased or programmed without it first being |
|
|
265 unlocked. For devices which support this feature and when <LITERAL> |
|
|
266 CYGHWR_IO_FLASH_BLOCK_LOCKING</LITERAL> is enabled then the following |
|
|
267 two functions are available:</PARA> |
|
|
268 |
|
|
269 <PROGRAMLISTING> |
|
|
270 __externC int cyg_flash_lock(const flashaddr_t *flash_base, const size_t len, flashaddr_t **err_address); |
|
|
271 __externC int cyg_flash_unlock(const flashaddr_t *flash_base, const size_t len, flashaddr_t **err_address); |
|
|
272 </PROGRAMLISTING> |
|
|
273 |
|
|
274 </SECT2> |
|
|
275 |
|
|
276 <SECT2> |
|
|
277 <TITLE>Locking FLASH Mutex's</TITLE> |
|
|
278 |
|
|
279 <PARA>When the eCos kernel package is included in the eCos |
|
|
280 configuration, the FLASH IO library will perform mutex locking on |
|
|
281 FLASH operations. This makes the API defined here thread safe. However |
|
|
282 applications may wish to directly access the contents of the FLASH. In |
|
|
283 order for this to be thread safe it is necessary for the application |
|
|
284 to use the following two functions to inform the FLASH IO library that |
|
|
285 the FLASH devices are being used and other API calls should be |
|
|
286 blocked.</PARA> |
|
|
287 |
|
|
288 <PROGRAMLISTING> |
|
|
289 __externC int cyg_flash_mutex_lock(const flashaddr_t *from, const size_t len); |
|
|
290 __externC int cyg_flash_mutex_unlock(const flashaddr_t *from, const size_t len); |
|
|
291 </PROGRAMLISTING> |
|
|
292 |
|
|
293 <SECT2> |
|
|
294 |
|
|
295 <TITLE>Return values and errors</TITLE> |
|
|
296 |
|
|
297 <PARA>All the functions above, except <FUNCTION>cyg_flash_code_overlaps() |
|
|
298 </FUNCTION> return one of the following return values.</PARA> |
|
|
299 |
|
|
300 <PROGRAMLISTING> |
|
|
301 CYG_FLASH_ERR_OK No error - operation complete |
|
|
302 CYG_FLASH_ERR_INVALID Invalid FLASH address |
|
|
303 CYG_FLASH_ERR_ERASE Error trying to erase |
|
|
304 CYG_FLASH_ERR_LOCK Error trying to lock/unlock |
|
|
305 CYG_FLASH_ERR_PROGRAM Error trying to program |
|
|
306 CYG_FLASH_ERR_PROTOCOL Generic error |
|
|
307 CYG_FLASH_ERR_PROTECT Device/region is write-protected |
|
|
308 CYG_FLASH_ERR_NOT_INIT FLASH info not yet initialized |
|
|
309 CYG_FLASH_ERR_HWR Hardware (configuration?) problem |
|
|
310 CYG_FLASH_ERR_ERASE_SUSPEND Device is in erase suspend mode |
|
|
311 CYG_FLASH_ERR_PROGRAM_SUSPEND Device is in program suspend mode |
|
|
312 CYG_FLASH_ERR_DRV_VERIFY Driver failed to verify data |
|
|
313 CYG_FLASH_ERR_DRV_TIMEOUT Driver timed out waiting for device |
|
|
314 CYG_FLASH_ERR_DRV_WRONG_PART Driver does not support device |
|
|
315 CYG_FLASH_ERR_LOW_VOLTAGE Not enough juice to complete job |
|
|
316 </PROGRAMLISTING> |
|
|
317 |
|
|
318 <PARA>To turn an error code into a human readable string the following |
|
|
319 function can be used:</PARA> |
|
|
320 |
|
|
321 <PROGRAMLISTING>__externC const char *cyg_flash_errmsg(const int err); |
|
|
322 </PROGRAMLISTING> |
|
|
323 </SECT2> |
|
|
324 |
|
|
325 <SECT1 id="ecos-flash-v2-dev"> |
|
|
326 <TITLE>FLASH device API</TITLE> <PARA>This section describes the API |
|
|
327 between the FLASH IO library the FLASH device drivers.</PARA> |
|
|
328 |
|
|
329 <SECT2> |
|
|
330 <TITLE>The FLASH device Structure</TITLE> |
|
|
331 |
|
|
332 <PARA>This structure keeps all the information about a single driver.</PARA> |
|
|
333 |
|
|
334 <PROGRAMLISTING>struct cyg_flash_dev { |
|
|
335 struct cyg_flash_dev_funs *funs; // Function pointers |
|
|
336 flashaddr_t *start; // First address |
|
|
337 flashaddr_t *end; // Last address |
|
|
338 void *priv; // Devices private data |
|
|
339 cyg_uint32 num_block_infos; // Number of entries |
|
|
340 cyg_block_info_t *blocks_info; // Info about one block size |
|
|
341 |
|
|
342 |
|
|
343 // The following are only written to by the FLASH IO layer. |
|
|
344 cyg_flash_printf *pf; // Pointer to diagnostic printf |
|
|
345 cyg_bool init; // Device has been initialized |
|
|
346 #ifdef CYG_KERNEL |
|
|
347 cyg_mutex_t mutex; // Mutex for thread safeness |
|
|
348 #endif |
|
|
349 struct cyg_flash_dev *next; // Pointer to next device |
|
|
350 } |
|
|
351 |
|
|
352 struct cyg_flash_dev_funs { |
|
|
353 int (*flash_init) (struct cyg_flash_dev *dev); |
|
|
354 size_t (*flash_query) (struct cyg_flash_dev *dev, void * data, const size_t len); |
|
|
355 int (*flash_erase_block) (struct cyg_flash_dev *dev, const flashaddr_t *block_base); |
|
|
356 int (*flash_program) (struct cyg_flash_dev *dev, flashaddr_t *base, const void* data, const size_t len); |
|
|
357 int (*flash_read) (struct cyg_flash_dev *dev, const flashaddr_t *base, void* data, const size_t len); |
|
|
358 int (*flash_hwr_map_error) (struct cyg_flash_dev *dev, int err); |
|
|
359 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING |
|
|
360 int (*flash_block_lock) (struct cyg_flash_dev *dev, const flashaddr_t *block_base); |
|
|
361 int (*flash_block_unlock) (struct cyg_flash_dev *dev, const flashaddr_t *block_base); |
|
|
362 #endif |
|
|
363 } |
|
|
364 </PROGRAMLISTING> |
|
|
365 |
|
|
366 <PARA>The FLASH IO layer will only pass requests for operations on a single block. |
|
|
367 </SECT1> |
|
|
368 </CHAPTER> |
|
|
369 |
|
|
370 <CHAPTER id="ecos-flash-v1"> |
|
|
371 <TITLE>The legacy Version 1 eCos FLASH API</TITLE> |
|
1672
|
372 <PARA> |
|
|
373 The library has a number of limitations:</PARA> |
|
|
374 |
|
|
375 <orderedlist> |
|
|
376 <listitem><PARA>Only one family of FLASH device may be supported at once. |
|
|
377 </PARA> |
|
|
378 </listitem> |
|
|
379 <listitem><PARA>Multiple devices of one family are supported, but they must |
|
|
380 be contiguous in memory. |
|
|
381 </PARA> |
|
|
382 </listitem> |
|
|
383 <listitem><PARA>The library is not thread or interrupt safe under |
|
|
384 some conditions. |
|
|
385 </PARA> |
|
|
386 </listitem> |
|
|
387 <listitem><PARA>The library currently does not use the eCos naming |
|
|
388 convention for its functions. This may change in the |
|
|
389 future but backward compatibility is likely to be kept. |
|
|
390 </PARA> |
|
|
391 </listitem> |
|
|
392 </orderedlist> |
|
|
393 |
|
1706
|
394 <PARA> There are two APIs described here. The first is the application |
|
|
395 API which programs should use. The second API is that between the |
|
|
396 FLASH io library and the device drivers. </PARA> |
|
|
397 |
|
|
398 <SECT1 id="ecos-flash-v1-api"> |
|
|
399 <TITLE>FLASH user API</TITLE> |
|
|
400 |
|
1672
|
401 <PARA>All of the functions described below are declared in the header |
|
|
402 file <filename><cyg/io/flash.h.h></filename> which all users of |
|
|
403 the FLASH library should include.</PARA> |
|
|
404 |
|
1706
|
405 |
|
1672
|
406 <SECT2> |
|
|
407 <TITLE>Initializing the FLASH library</TITLE> |
|
|
408 |
|
|
409 <PARA>The FLASH library needs to be initialized before other FLASH |
|
|
410 operations can be performed. This only needs to be done once. The |
|
|
411 following function will only do the initialization once so it's safe |
|
|
412 to call multiple times: </PARA> |
|
|
413 |
|
1706
|
414 <PROGRAMLISTING>externC int flash_init( _printf *pf ); |
|
|
415 typedef int _printf(const char *fmt, ...); </PROGRAMLISTING> |
|
1672
|
416 |
|
|
417 <PARA> |
|
|
418 The parameter <parameter>pf</parameter> is a pointer to a function |
|
|
419 which is to be used for diagnostic output. Typically the function |
|
|
420 <function>diag_printf()</function> will be passed. Normally this |
|
|
421 function is not used by the higher layer of the library unless |
|
|
422 <literal>CYGSEM_IO_FLASH_CHATTER</literal> is enabled. Passing a |
|
|
423 <parameter>NULL</parameter> is not recommended, even when |
|
|
424 CYGSEM_IO_FLASH_CHATTER is disabled. The lower layers of the library |
|
|
425 may unconditionally call this function, especially when errors occur, |
|
|
426 probably resulting in a more serious error/crash!.</PARA> |
|
|
427 </SECT2> |
|
|
428 |
|
|
429 <SECT2> |
|
|
430 <TITLE>Retrieving information about the FLASH</TITLE> |
|
|
431 |
|
|
432 <PARA> |
|
|
433 The following four functions return information about the FLASH. |
|
|
434 </PARA> |
|
|
435 |
|
|
436 <PROGRAMLISTING>externC int flash_get_block_info(int *block_size, int *blocks); |
|
|
437 externC int flash_get_limits(void *target, void **start, void **end); |
|
|
438 externC int flash_verify_addr(void *target); |
|
|
439 externC bool flash_code_overlaps(void *start, void *end); |
|
|
440 </PROGRAMLISTING> |
|
|
441 |
|
|
442 <PARA> |
|
|
443 The function <FUNCTION>flash_get_block_info()</FUNCTION> returns the |
|
|
444 size and number of blocks. When the device has a mixture of block |
|
|
445 sizes, the size of the "normal" block will be returned. Please read |
|
|
446 the source code to determine exactly what this means. |
|
|
447 <FUNCTION>flash_get_limits()</FUNCTION> returns the lower and upper |
|
|
448 memory address the FLASH occupies. The <PARAMETER>target</PARAMETER> |
|
|
449 parameter is current unused. <FUNCTION> flash_verify_addr() |
|
|
450 </FUNCTION> tests if the target addresses is within the flash, |
|
|
451 returning <LITERAL>FLASH_ERR_OK</LITERAL> if so. Lastly, <FUNCTION> |
|
|
452 flash_code_overlaps() </FUNCTION> checks if the executing code is |
|
|
453 resident in the section of flash indicated by |
|
|
454 <PARAMETER>start</PARAMETER> and <PARAMETER> end</PARAMETER>. If this |
|
|
455 function returns true, erase and program operations within this range |
|
|
456 are very likely to cause the target to crash and burn horribly. Note |
|
|
457 the FLASH library does allow you to shoot yourself in the foot in this |
|
|
458 way.</PARA> |
|
|
459 |
|
|
460 </SECT2> |
|
|
461 <SECT2> |
|
|
462 |
|
|
463 <TITLE>Reading from FLASH</TITLE> |
|
|
464 |
|
|
465 <PARA> |
|
|
466 There are two methods for reading from FLASH. The first is to use the |
|
|
467 following function. </PARA> |
|
|
468 |
|
|
469 <PROGRAMLISTING> |
|
|
470 externC int flash_read(void *flash_base, void *ram_base, int len, void **err_address); |
|
|
471 </PROGRAMLISTING> |
|
|
472 |
|
|
473 <PARA> |
|
|
474 <PARAMETER>flash_base</PARAMETER> is where in the flash to read |
|
|
475 from. <PARAMETER>ram_base</PARAMETER> indicates where the data read |
|
|
476 from flash should be placed into RAM. <PARAMETER>len</PARAMETER> is |
|
|
477 the number of bytes to be read from the FLASH and |
|
|
478 <PARAMETER>err_address</PARAMETER> is used to return the location in |
|
|
479 FLASH that any error occurred while reading. |
|
|
480 </PARA> |
|
|
481 |
|
|
482 <PARA> |
|
|
483 The second method is to simply <FUNCTION>memcpy()</FUNCTION> directly |
|
|
484 from the FLASH. This is not recommended since some types of device |
|
|
485 cannot be read in this way, eg NAND FLASH. Using the FLASH library |
|
|
486 function to read the FLASH will always work so making it easy to port |
|
|
487 code from one FLASH device to another. |
|
|
488 </PARA> |
|
|
489 |
|
|
490 </SECT2> |
|
|
491 <SECT2> |
|
|
492 |
|
|
493 <TITLE>Erasing areas of FLASH</TITLE> |
|
|
494 |
|
|
495 <PARA> |
|
|
496 Blocks of FLASH can be erased using the following function: |
|
|
497 </PARA> |
|
|
498 |
|
|
499 <PROGRAMLISTING>externC int flash_erase(void *flash_base, int len, void **err_address); |
|
|
500 </PROGRAMLISTING> |
|
|
501 |
|
|
502 <PARA> |
|
|
503 <PARAMETER>flash_base</PARAMETER> is where in the flash to erase |
|
|
504 from. <PARAMETER>len</PARAMETER> is the minimum number of bytes to |
|
|
505 erase in the FLASH and <PARAMETER>err_address</PARAMETER> is used to |
|
|
506 return the location in FLASH that any error occurred while erasing. It |
|
|
507 should be noted that FLASH devices are block oriented when erasing. It |
|
|
508 is not possible to erase a few bytes within a block, the whole block |
|
|
509 will be erased. <PARAMETER>flash_base</PARAMETER> may be anywhere |
|
|
510 within the first block to be erased and <PARAMETER>flash_base+len |
|
|
511 </PARAMETER> maybe anywhere in the last block to be erased. </PARA> |
|
|
512 |
|
|
513 </SECT2> |
|
|
514 <SECT2> |
|
|
515 |
|
|
516 <TITLE>Programming the FLASH</TITLE> |
|
|
517 |
|
|
518 <PARA> Programming of the flash is achieved using the following |
|
|
519 function.</PARA> |
|
|
520 |
|
|
521 <PROGRAMLISTING>externC int flash_program(void *flash_base, void *ram_base, int len, void **err_address); |
|
|
522 </PROGRAMLISTING> |
|
|
523 |
|
|
524 <PARA> |
|
|
525 <PARAMETER>flash_base</PARAMETER> is where in the flash to program |
|
|
526 from. <PARAMETER>ram_base</PARAMETER> indicates where the data to be |
|
|
527 programmed into FLASH should be read from in RAM. <PARAMETER>len |
|
|
528 </PARAMETER> is the number of bytes to be program into the FLASH and |
|
|
529 <PARAMETER>err_address</PARAMETER> is used to return the location in |
|
|
530 FLASH that any error occurred while programming. </PARA> |
|
|
531 |
|
|
532 </SECT2> |
|
|
533 <SECT2> |
|
|
534 |
|
|
535 <TITLE>Locking and unlocking blocks</TITLE> |
|
|
536 |
|
|
537 <PARA> |
|
|
538 Some flash devices have the ability to lock and unlock blocks. A |
|
|
539 locked block cannot be erased or programmed without it first being |
|
|
540 unlocked. For devices which support this feature and when <LITERAL> |
|
|
541 CYGHWR_IO_FLASH_BLOCK_LOCKING</LITERAL> is enabled then the following |
|
|
542 two functions are available:</PARA> |
|
|
543 |
|
|
544 <PROGRAMLISTING> |
|
|
545 externC int flash_lock(void *flash_base, int len, void **err_address); |
|
|
546 externC int flash_unlock(void *flash_base, int len, void **err_address); |
|
|
547 </PROGRAMLISTING> |
|
|
548 |
|
|
549 </SECT2> |
|
|
550 <SECT2> |
|
|
551 |
|
|
552 <TITLE>Return values and errors</TITLE> |
|
|
553 |
|
|
554 <PARA>All the functions above, except <FUNCTION>flash_code_overlaps() |
|
|
555 </FUNCTION> return one of the following return values.</PARA> |
|
|
556 |
|
|
557 <PROGRAMLISTING> |
|
|
558 FLASH_ERR_OK No error - operation complete |
|
|
559 FLASH_ERR_INVALID Invalid FLASH address |
|
|
560 FLASH_ERR_ERASE Error trying to erase |
|
|
561 FLASH_ERR_LOCK Error trying to lock/unlock |
|
|
562 FLASH_ERR_PROGRAM Error trying to program |
|
|
563 FLASH_ERR_PROTOCOL Generic error |
|
|
564 FLASH_ERR_PROTECT Device/region is write-protected |
|
|
565 FLASH_ERR_NOT_INIT FLASH info not yet initialized |
|
|
566 FLASH_ERR_HWR Hardware (configuration?) problem |
|
|
567 FLASH_ERR_ERASE_SUSPEND Device is in erase suspend mode |
|
|
568 FLASH_ERR_PROGRAM_SUSPEND Device is in program suspend mode |
|
|
569 FLASH_ERR_DRV_VERIFY Driver failed to verify data |
|
|
570 FLASH_ERR_DRV_TIMEOUT Driver timed out waiting for device |
|
|
571 FLASH_ERR_DRV_WRONG_PART Driver does not support device |
|
|
572 FLASH_ERR_LOW_VOLTAGE Not enough juice to complete job |
|
|
573 </PROGRAMLISTING> |
|
|
574 |
|
|
575 <PARA>To turn an error code into a human readable string the following |
|
|
576 function can be used:</PARA> |
|
|
577 |
|
|
578 <PROGRAMLISTING>externC char *flash_errmsg(int err); |
|
|
579 </PROGRAMLISTING> |
|
|
580 </SECT2> |
|
|
581 |
|
|
582 <SECT2> |
|
|
583 |
|
|
584 <TITLE> Notes on using the FLASH library</TITLE> |
|
|
585 |
|
|
586 <PARA> |
|
|
587 The FLASH library evolved from the needs and environment of RedBoot |
|
|
588 rather than being a general purpose eCos component. This history |
|
|
589 explains some of the problems with the library. </PARA> |
|
|
590 |
|
|
591 <PARA>The library is not thread safe. Multiple simultaneous calls to |
|
|
592 its library functions will likely fail and may cause a crash. It is |
|
|
593 the callers responsibility to use the necessary mutex's if needed. |
|
|
594 <PARA> |
|
|
595 |
|
1706
|
596 </SECT2> |
|
|
597 </SECT1> |
|
|
598 |
|
|
599 <SECT1 id="ecos-flash-v1-dev"> |
|
|
600 <TITLE>FLASH device API</TITLE> <PARA>This section describes the API |
|
|
601 between the FLASH IO library the FLASH device drivers.</PARA> |
|
|
602 |
|
|
603 <SECT2> |
|
|
604 <TITLE>The flash_info structure</TITLE> |
|
|
605 |
|
|
606 <PARA> The <parameter>flash_info</parameter>structure is used by both |
|
|
607 the FLASH IO library and the device driver.</PARA> |
|
|
608 <PROGRAMLISTING>struct flash_info { |
|
|
609 int block_size; // Assuming fixed size "blocks" |
|
|
610 int blocks; // Number of blocks |
|
|
611 int buffer_size; // Size of write buffer (only defined for some devices) |
|
|
612 unsigned long block_mask; |
|
|
613 void *start, *end; // Address range |
|
|
614 int init; // FLASH API initialised |
|
|
615 _printf *pf; // printf like function for diagnostics |
|
|
616 }; |
|
|
617 </PROGRAMLISTING> |
|
|
618 |
|
|
619 <PARA>block_mask is used internally in the FLASH IO library. It |
|
|
620 contains a mask which can be used to turn an arbitrary address in |
|
|
621 flash to the base address of the block which contains the |
|
|
622 address.</PARA> |
|
|
623 |
|
|
624 <PARA>There exists one global instance of this structure with the name |
|
|
625 <parameter>flash_info</parameter>. All calls into the device driver |
|
|
626 makes use of this global structure to maintain state.</PARA> |
|
|
627 |
|
|
628 </SECT2> |
|
|
629 |
|
|
630 <SECT2> |
|
|
631 <TITLE>Initializing the device driver</TITLE> |
|
|
632 |
|
|
633 <PARA>The FLASH IO library will call the following function to |
|
|
634 initialize the device driver:</PARA> |
|
|
635 |
|
|
636 <PROGRAMLISTING>externC int flash_hwr_init(void); |
|
|
637 </PROGRAMLISTING> |
|
|
638 |
|
|
639 <PARA>The device driver should probe the hardware to see if the FLASH |
|
|
640 devices exist. If it does it should fill in <parameter>start, end, |
|
|
641 blocks and block_size.</parameter>If the FLASH contains a write buffer |
|
|
642 the size of this should be placed in <parameter>buffer_size |
|
|
643 </parameter>. On successful probing the function should return |
|
|
644 <literal>FLASH_ERR_OK</literal>. When things go wrong it can be |
|
|
645 assumed that <parameter>pf</parameter> points to a printf like |
|
|
646 function for outputting error messages. |
|
1672
|
647 </PARA> |
|
1706
|
648 </SECT2> |
|
1672
|
649 |
|
1706
|
650 <SECT2> |
|
|
651 <TITLE>Querying the FLASH</TITLE> |
|
|
652 |
|
|
653 <PARA>FLASH devices can be queried to return there manufacture ID, |
|
|
654 size etc. This function allows this information to be returned.</PARA> |
|
|
655 |
|
|
656 <PROGRAMLISTING>int flash_query(unsigned char *data);</PROGRAMLISTING> |
|
|
657 |
|
|
658 <PARA>The caller must know the size of data to be returned and provide |
|
|
659 an appropriately sized buffer pointed to be parameter |
|
|
660 <parameter>data</parameter>. This function is generally used by |
|
|
661 <function>flash_hwr_init()</function>.</PARA> |
|
|
662 |
|
|
663 </SECT2> |
|
|
664 <SECT2> |
|
|
665 <TITLE>Erasing a block of FLASH</TITLE> |
|
|
666 |
|
|
667 <PARA>So that the FLASH IO layer can erase a block of FLASH the |
|
|
668 following function should be provided.</PARA> |
|
|
669 |
|
|
670 <PROGRAMLISTING>int flash_erase_block(volatile flash_t *block, unsigned int block_size); |
|
|
671 </PROGRAMLISTING> |
|
1672
|
672 |
|
|
673 </SECT2> |
|
|
674 <SECT2> |
|
1706
|
675 <TITLE>Programming a region of FLASH</TITLE> |
|
1672
|
676 |
|
1706
|
677 <PARA>The following function must be provided so that data can be |
|
|
678 written into the FLASH.</PARA> |
|
|
679 |
|
|
680 <PROGRAMLISTING>int flash_program_buf(volatile flash_t *addr, flash_t *data, int len, |
|
|
681 unsigned long block_mask, int buffer_size);</PROGRAMLISTING> |
|
|
682 |
|
|
683 <PARA>The device will only be asked to program data in one block of |
|
|
684 the flash. The FLASH IO layer will break longer user requests into a |
|
|
685 smaller writes.</PARA> |
|
|
686 |
|
|
687 <SECT2> |
|
|
688 <TITLE>Reading a region from FLASH</TITLE> |
|
|
689 |
|
|
690 <PARA>Some FLASH devices are not memory mapped so it is not possible |
|
|
691 to read there contents directly. The following function read a region |
|
|
692 of FLASH.</PARA> |
|
|
693 |
|
|
694 <PROGRAMLISTING>int flash_read_buf(volatile flash_t* addr, flash_t* data, int len); |
|
|
695 </PROGRAMLISTING> |
|
1672
|
696 |
|
1706
|
697 <PARA>As with writing to the flash, the FLASH IO layer will break |
|
|
698 longer user requests for data into a number of reads which are at |
|
|
699 maximum one block in size.</PARA> |
|
|
700 |
|
|
701 <PARA>A device which cannot be read directy should set |
|
|
702 <LITERAL>CYGSEM_IO_FLASH_READ_INDIRECT</LITERAL> so that the IO layer |
|
|
703 makes use of the <function>flash_read_buf()</function>function. |
|
|
704 |
|
|
705 </SECT2> |
|
|
706 |
|
|
707 <SECT2> |
|
|
708 <TITLE>Locking and unlocking FLASH blocks</TITLE> |
|
|
709 |
|
|
710 <PARA>Some flash devices allow blocks to be locked so that they cannot |
|
|
711 be written to. The device driver should provide the following |
|
|
712 functions to manipulate these locks.</PARA> |
|
|
713 |
|
|
714 <PROGRAMLISTING>int flash_lock_block(volatile flash_t *block); |
|
|
715 int flash_unlock_block(volatile flash_t *block, int block_size, int blocks); |
|
|
716 </PROGRAMLISTING> |
|
|
717 |
|
|
718 <PARA>These functions are only used if |
|
|
719 <LITERAL>CYGHWR_IO_FLASH_BLOCK_LOCKING</LITERAL></PARA> |
|
1672
|
720 |
|
|
721 </SECT2> |
|
1706
|
722 |
|
|
723 <SECT2> |
|
|
724 <TITLE>Mapping FLASH error codes to FLASH IO error codes</TITLE> |
|
|
725 |
|
|
726 <PARA>The functions <function>flash_erase_block(), |
|
|
727 flash_program_buf(), flash_read_buf(), flash_lock_block() and |
|
|
728 flash_unlock_block()</function> return an error code which is specific |
|
|
729 to the flash device. To map this into a FLASH IO error code, the |
|
|
730 driver should provide the following function: </PARA> |
|
|
731 |
|
|
732 <PROGRAMLISTING>int flash_hwr_map_error(int err);</PROGRAMLISTING> |
|
|
733 |
|
|
734 </SECT2> |
|
|
735 |
|
|
736 <SECT2> |
|
|
737 <TITLE>Determining if code is in FLASH</TITLE> |
|
|
738 |
|
|
739 <PARA>Although a general function, the device driver is expected to |
|
|
740 provide the implementation of the function |
|
|
741 <function>flash_code_overlaps()</function>.</PARA> |
|
|
742 |
|
|
743 </SECT2> |
|
|
744 |
|
|
745 <SECT2> |
|
|
746 <TITLE>Implementation Notes</TITLE> |
|
|
747 |
|
|
748 <PARA>The FLASH IO layer will manipulate the caches as required. The |
|
|
749 device drivers do not need to enable/disable caches when performing |
|
|
750 operations of the FLASH.<PARA> |
|
|
751 |
|
|
752 <PARA>Device drivers should keep all chatter to a minimum when |
|
|
753 <literal>CYGSEM_IO_FLASH_CHATTER</literal> is not defined. All output |
|
|
754 should use the print function in the <parameter>pf</parameter> in |
|
|
755 <parameter>flash_info</parameter> and not |
|
|
756 <function>diag_printf()</function></PARA> |
|
|
757 |
|
|
758 <PARA>Device driver functions which manipulate the state of the flash |
|
|
759 so that it cannot be read from for program execute need to ensure |
|
|
760 there code is placed into RAM. The linker will do this if the |
|
|
761 appropriate attribute is added to the function. e.g:</PARA> |
|
|
762 |
|
|
763 <PROGRAMLISTING>int flash_program_buf(volatile flash_t *addr, flash_t *data, int len, |
|
|
764 unsigned long block_mask, int buffer_size) |
|
|
765 __attribute__ ((section (".2ram.flash_program_buf")));</PROGRAMLISTING> |
|
|
766 |
|
|
767 </SECT2> |
|
|
768 </SECT1> |
|
1672
|
769 </CHAPTER> |
|
|
770 </PART> |