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