1 <!-- HTML header for doxygen 1.8.20-->
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3 <html xmlns="http://www.w3.org/1999/xhtml">
5 <meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
6 <meta http-equiv="X-UA-Compatible" content="IE=9"/>
7 <meta name="generator" content="Doxygen 1.9.4"/>
8 <meta name="viewport" content="width=device-width, initial-scale=1"/>
9 <title>Raspberry Pi Pico SDK: hardware_flash</title>
10 <!-- <link href="tabs.css" rel="stylesheet" type="text/css"/> -->
11 <script type="text/javascript" src="jquery.js"></script>
12 <script type="text/javascript" src="dynsections.js"></script>
13 <link href="navtree.css" rel="stylesheet" type="text/css"/>
14 <script type="text/javascript" src="resize.js"></script>
15 <script type="text/javascript" src="navtreedata.js"></script>
16 <script type="text/javascript" src="navtree.js"></script>
17 <link href="search/search.css" rel="stylesheet" type="text/css"/>
18 <script type="text/javascript" src="search/searchdata.js"></script>
19 <script type="text/javascript" src="search/search.js"></script>
20 <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
21 <link href="doxygen.css" rel="stylesheet" type="text/css" />
22 <link href="normalise.css" rel="stylesheet" type="text/css"/>
23 <link href="main.css" rel="stylesheet" type="text/css"/>
24 <link href="styles.css" rel="stylesheet" type="text/css"/>
27 <div class="navigation-mobile">
28 <div class="logo--mobile">
29 <a href="/"><img src="logo-mobile.svg" alt="Raspberry Pi"></a>
31 <div class="navigation-toggle">
32 <span class="line-1"></span>
36 <span class="line-3"></span>
39 <div id="top"><!-- do not remove this div, it is closed by doxygen! -->
41 <a href="index.html"> <img src="logo.svg" alt="Raspberry Pi"></a>
42 <span style="display: inline-block; margin-top: 10px;">
46 <div class="navigation-footer">
47 <img src="logo-mobile.svg" alt="Raspberry Pi">
48 <a href="https://www.raspberrypi.com/" target="_blank">By Raspberry Pi Ltd</a>
50 <!-- <div class="search">
52 <input type="search" name="search" id="search" placeholder="Search">
53 <input type="submit" value="Search">
56 <!-- Generated by Doxygen 1.9.4 -->
57 <script type="text/javascript">
58 /* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
59 var searchBox = new SearchBox("searchBox", "search",'Search','.html');
62 <script type="text/javascript" src="menudata.js"></script>
63 <script type="text/javascript" src="menu.js"></script>
64 <script type="text/javascript">
65 /* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
67 initMenu('',true,false,'search.php','Search');
68 $(document).ready(function() { init_search(); });
72 <div id="main-nav"></div>
74 <div id="side-nav" class="ui-resizable side-nav-resizable">
76 <div id="nav-tree-contents">
77 <div id="nav-sync" class="sync"></div>
80 <div id="splitbar" style="-moz-user-select:none;"
81 class="ui-resizable-handle">
84 <script type="text/javascript">
85 /* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&dn=expat.txt MIT */
86 $(document).ready(function(){initNavTree('group__hardware__flash.html',''); initResizable(); });
89 <div id="doc-content">
90 <!-- window showing the filter options -->
91 <div id="MSearchSelectWindow"
92 onmouseover="return searchBox.OnSearchSelectShow()"
93 onmouseout="return searchBox.OnSearchSelectHide()"
94 onkeydown="return searchBox.OnSearchSelectKey(event)">
97 <!-- iframe showing the search results (closed by default) -->
98 <div id="MSearchResultsWindow">
99 <iframe src="javascript:void(0)" frameborder="0"
100 name="MSearchResults" id="MSearchResults">
105 <div class="summary">
106 <a href="#func-members">Functions</a> </div>
107 <div class="headertitle"><div class="title">hardware_flash<div class="ingroups"><a class="el" href="group__hardware.html">Hardware APIs</a></div></div></div>
109 <div class="contents">
111 <p>Low level flash programming and erase API.
112 <a href="#details">More...</a></p>
113 <table class="memberdecls">
114 <tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="func-members" name="func-members"></a>
115 Functions</h2></td></tr>
116 <tr class="memitem:ga5b88461b126b1c226121146c87d5abe2"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__hardware__flash.html#ga5b88461b126b1c226121146c87d5abe2">flash_range_erase</a> (uint32_t flash_offs, size_t count)</td></tr>
117 <tr class="memdesc:ga5b88461b126b1c226121146c87d5abe2"><td class="mdescLeft"> </td><td class="mdescRight">Erase areas of flash. <a href="group__hardware__flash.html#ga5b88461b126b1c226121146c87d5abe2">More...</a><br /></td></tr>
118 <tr class="separator:ga5b88461b126b1c226121146c87d5abe2"><td class="memSeparator" colspan="2"> </td></tr>
119 <tr class="memitem:ga345513fba0951661d012fa20a6441c5f"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__hardware__flash.html#ga345513fba0951661d012fa20a6441c5f">flash_range_program</a> (uint32_t flash_offs, const uint8_t *data, size_t count)</td></tr>
120 <tr class="memdesc:ga345513fba0951661d012fa20a6441c5f"><td class="mdescLeft"> </td><td class="mdescRight">Program flash. <a href="group__hardware__flash.html#ga345513fba0951661d012fa20a6441c5f">More...</a><br /></td></tr>
121 <tr class="separator:ga345513fba0951661d012fa20a6441c5f"><td class="memSeparator" colspan="2"> </td></tr>
122 <tr class="memitem:ga5c6452005ad28f1e444698b0b97194d2"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__hardware__flash.html#ga5c6452005ad28f1e444698b0b97194d2">flash_get_unique_id</a> (uint8_t *id_out)</td></tr>
123 <tr class="memdesc:ga5c6452005ad28f1e444698b0b97194d2"><td class="mdescLeft"> </td><td class="mdescRight">Get flash unique 64 bit identifier. <a href="group__hardware__flash.html#ga5c6452005ad28f1e444698b0b97194d2">More...</a><br /></td></tr>
124 <tr class="separator:ga5c6452005ad28f1e444698b0b97194d2"><td class="memSeparator" colspan="2"> </td></tr>
125 <tr class="memitem:ga9e352de7ea62ffebc579f6449b5b44d3"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__hardware__flash.html#ga9e352de7ea62ffebc579f6449b5b44d3">flash_do_cmd</a> (const uint8_t *txbuf, uint8_t *rxbuf, size_t count)</td></tr>
126 <tr class="memdesc:ga9e352de7ea62ffebc579f6449b5b44d3"><td class="mdescLeft"> </td><td class="mdescRight">Execute bidirectional flash command. <a href="group__hardware__flash.html#ga9e352de7ea62ffebc579f6449b5b44d3">More...</a><br /></td></tr>
127 <tr class="separator:ga9e352de7ea62ffebc579f6449b5b44d3"><td class="memSeparator" colspan="2"> </td></tr>
129 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
130 <p >Low level flash programming and erase API. </p>
131 <p >Note these functions are <em>unsafe</em> if you are using both cores, and the other is executing from flash concurrently with the operation. In this could be the case, you must perform your own synchronisation to make sure that no XIP accesses take place during flash programming. One option is to use the <a class="el" href="group__multicore__lockout.html">lockout</a> functions.</p>
132 <p >Likewise they are <em>unsafe</em> if you have interrupt handlers or an interrupt vector table in flash, so you must disable interrupts before calling in this case.</p>
133 <p >If PICO_NO_FLASH=1 is not defined (i.e. if the program is built to run from flash) then these functions will make a static copy of the second stage bootloader in SRAM, and use this to reenter execute-in-place mode after programming or erasing flash, so that they can safely be called from flash-resident code.</p>
134 <h2><a class="anchor" id="flash_example"></a>
136 <div class="fragment"><div class="line"> </div>
137 <div class="line"><span class="preprocessor">#include <<a class="code" href="stdio_8h.html">stdio.h</a>></span></div>
138 <div class="line"><span class="preprocessor">#include <<a class="code" href="stdlib_8h.html">stdlib.h</a>></span></div>
139 <div class="line"> </div>
140 <div class="line"><span class="preprocessor">#include "<a class="code" href="stdlib_8h.html">pico/stdlib.h</a>"</span></div>
141 <div class="line"><span class="preprocessor">#include "<a class="code" href="hardware__flash_2include_2hardware_2flash_8h.html">hardware/flash.h</a>"</span></div>
142 <div class="line"> </div>
143 <div class="line"><span class="comment">// We're going to erase and reprogram a region 256k from the start of flash.</span></div>
144 <div class="line"><span class="comment">// Once done, we can access this at XIP_BASE + 256k.</span></div>
145 <div class="line"><span class="preprocessor">#define FLASH_TARGET_OFFSET (256 * 1024)</span></div>
146 <div class="line"> </div>
147 <div class="line"><span class="keyword">const</span> uint8_t *flash_target_contents = (<span class="keyword">const</span> uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);</div>
148 <div class="line"> </div>
149 <div class="line"><span class="keywordtype">void</span> print_buf(<span class="keyword">const</span> uint8_t *buf, <span class="keywordtype">size_t</span> len) {</div>
150 <div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">size_t</span> i = 0; i < len; ++i) {</div>
151 <div class="line"> printf(<span class="stringliteral">"%02x"</span>, buf[i]);</div>
152 <div class="line"> <span class="keywordflow">if</span> (i % 16 == 15)</div>
153 <div class="line"> printf(<span class="stringliteral">"\n"</span>);</div>
154 <div class="line"> <span class="keywordflow">else</span></div>
155 <div class="line"> printf(<span class="stringliteral">" "</span>);</div>
156 <div class="line"> }</div>
157 <div class="line">}</div>
158 <div class="line"> </div>
159 <div class="line"><span class="keywordtype">int</span> main() {</div>
160 <div class="line"> <a class="code hl_function" href="group__pico__stdio.html#ga0e604311fb226dae91ff4eb17a19d67a">stdio_init_all</a>();</div>
161 <div class="line"> uint8_t random_data[FLASH_PAGE_SIZE];</div>
162 <div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < FLASH_PAGE_SIZE; ++i)</div>
163 <div class="line"> random_data[i] = rand() >> 16;</div>
164 <div class="line"> </div>
165 <div class="line"> printf(<span class="stringliteral">"Generated random data:\n"</span>);</div>
166 <div class="line"> print_buf(random_data, FLASH_PAGE_SIZE);</div>
167 <div class="line"> </div>
168 <div class="line"> <span class="comment">// Note that a whole number of sectors must be erased at a time.</span></div>
169 <div class="line"> printf(<span class="stringliteral">"\nErasing target region...\n"</span>);</div>
170 <div class="line"> <a class="code hl_function" href="group__hardware__flash.html#ga5b88461b126b1c226121146c87d5abe2">flash_range_erase</a>(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);</div>
171 <div class="line"> printf(<span class="stringliteral">"Done. Read back target region:\n"</span>);</div>
172 <div class="line"> print_buf(flash_target_contents, FLASH_PAGE_SIZE);</div>
173 <div class="line"> </div>
174 <div class="line"> printf(<span class="stringliteral">"\nProgramming target region...\n"</span>);</div>
175 <div class="line"> <a class="code hl_function" href="group__hardware__flash.html#ga345513fba0951661d012fa20a6441c5f">flash_range_program</a>(FLASH_TARGET_OFFSET, random_data, FLASH_PAGE_SIZE);</div>
176 <div class="line"> printf(<span class="stringliteral">"Done. Read back target region:\n"</span>);</div>
177 <div class="line"> print_buf(flash_target_contents, FLASH_PAGE_SIZE);</div>
178 <div class="line"> </div>
179 <div class="line"> <span class="keywordtype">bool</span> mismatch = <span class="keyword">false</span>;</div>
180 <div class="line"> <span class="keywordflow">for</span> (<span class="keywordtype">int</span> i = 0; i < FLASH_PAGE_SIZE; ++i) {</div>
181 <div class="line"> <span class="keywordflow">if</span> (random_data[i] != flash_target_contents[i])</div>
182 <div class="line"> mismatch = <span class="keyword">true</span>;</div>
183 <div class="line"> }</div>
184 <div class="line"> <span class="keywordflow">if</span> (mismatch)</div>
185 <div class="line"> printf(<span class="stringliteral">"Programming failed!\n"</span>);</div>
186 <div class="line"> <span class="keywordflow">else</span></div>
187 <div class="line"> printf(<span class="stringliteral">"Programming successful!\n"</span>);</div>
188 <div class="line">}</div>
189 <div class="ttc" id="agroup__hardware__flash_html_ga345513fba0951661d012fa20a6441c5f"><div class="ttname"><a href="group__hardware__flash.html#ga345513fba0951661d012fa20a6441c5f">flash_range_program</a></div><div class="ttdeci">void __no_inline_not_in_flash_func() flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count)</div><div class="ttdoc">Program flash.</div><div class="ttdef"><b>Definition:</b> flash.c:103</div></div>
190 <div class="ttc" id="agroup__hardware__flash_html_ga5b88461b126b1c226121146c87d5abe2"><div class="ttname"><a href="group__hardware__flash.html#ga5b88461b126b1c226121146c87d5abe2">flash_range_erase</a></div><div class="ttdeci">void __no_inline_not_in_flash_func() flash_range_erase(uint32_t flash_offs, size_t count)</div><div class="ttdoc">Erase areas of flash.</div><div class="ttdef"><b>Definition:</b> flash.c:75</div></div>
191 <div class="ttc" id="agroup__pico__stdio_html_ga0e604311fb226dae91ff4eb17a19d67a"><div class="ttname"><a href="group__pico__stdio.html#ga0e604311fb226dae91ff4eb17a19d67a">stdio_init_all</a></div><div class="ttdeci">bool stdio_init_all(void)</div><div class="ttdoc">Initialize all of the present standard stdio types that are linked into the binary.</div><div class="ttdef"><b>Definition:</b> stdio.c:200</div></div>
192 <div class="ttc" id="ahardware__flash_2include_2hardware_2flash_8h_html"><div class="ttname"><a href="hardware__flash_2include_2hardware_2flash_8h.html">flash.h</a></div></div>
193 <div class="ttc" id="astdio_8h_html"><div class="ttname"><a href="stdio_8h.html">stdio.h</a></div></div>
194 <div class="ttc" id="astdlib_8h_html"><div class="ttname"><a href="stdlib_8h.html">stdlib.h</a></div></div>
195 </div><!-- fragment --> <h2 class="groupheader">Function Documentation</h2>
196 <a id="ga9e352de7ea62ffebc579f6449b5b44d3" name="ga9e352de7ea62ffebc579f6449b5b44d3"></a>
197 <h2 class="memtitle"><span class="permalink"><a href="#ga9e352de7ea62ffebc579f6449b5b44d3">◆ </a></span>flash_do_cmd()</h2>
199 <div class="memitem">
200 <div class="memproto">
201 <table class="memname">
203 <td class="memname">void flash_do_cmd </td>
205 <td class="paramtype">const uint8_t * </td>
206 <td class="paramname"><em>txbuf</em>, </td>
209 <td class="paramkey"></td>
211 <td class="paramtype">uint8_t * </td>
212 <td class="paramname"><em>rxbuf</em>, </td>
215 <td class="paramkey"></td>
217 <td class="paramtype">size_t </td>
218 <td class="paramname"><em>count</em> </td>
226 </div><div class="memdoc">
228 <p>Execute bidirectional flash command. </p>
229 <p >Low-level function to execute a serial command on a flash device attached to the QSPI interface. Bytes are simultaneously transmitted and received from txbuf and to rxbuf. Therefore, both buffers must be the same length, count, which is the length of the overall transaction. This is useful for reading metadata from the flash chip, such as device ID or SFDP parameters.</p>
230 <p >The XIP cache is flushed following each command, in case flash state has been modified. Like other hardware_flash functions, the flash is not accessible for execute-in-place transfers whilst the command is in progress, so entering a flash-resident interrupt handler or executing flash code on the second core concurrently will be fatal. To avoid these pitfalls it is recommended that this function only be used to extract flash metadata during startup, before the main application begins to run: see the implementation of pico_get_unique_id() for an example of this.</p>
231 <dl class="params"><dt>Parameters</dt><dd>
232 <table class="params">
233 <tr><td class="paramname">txbuf</td><td>Pointer to a byte buffer which will be transmitted to the flash </td></tr>
234 <tr><td class="paramname">rxbuf</td><td>Pointer to a byte buffer where data received from the flash will be written. txbuf and rxbuf may be the same buffer. </td></tr>
235 <tr><td class="paramname">count</td><td>Length in bytes of txbuf and of rxbuf </td></tr>
242 <a id="ga5c6452005ad28f1e444698b0b97194d2" name="ga5c6452005ad28f1e444698b0b97194d2"></a>
243 <h2 class="memtitle"><span class="permalink"><a href="#ga5c6452005ad28f1e444698b0b97194d2">◆ </a></span>flash_get_unique_id()</h2>
245 <div class="memitem">
246 <div class="memproto">
247 <table class="memname">
249 <td class="memname">void flash_get_unique_id </td>
251 <td class="paramtype">uint8_t * </td>
252 <td class="paramname"><em>id_out</em></td><td>)</td>
256 </div><div class="memdoc">
258 <p>Get flash unique 64 bit identifier. </p>
259 <p >Use a standard 4Bh RUID instruction to retrieve the 64 bit unique identifier from a flash device attached to the QSPI interface. Since there is a 1:1 association between the MCU and this flash, this also serves as a unique identifier for the board.</p>
260 <dl class="params"><dt>Parameters</dt><dd>
261 <table class="params">
262 <tr><td class="paramname">id_out</td><td>Pointer to an 8-byte buffer to which the ID will be written </td></tr>
269 <a id="ga5b88461b126b1c226121146c87d5abe2" name="ga5b88461b126b1c226121146c87d5abe2"></a>
270 <h2 class="memtitle"><span class="permalink"><a href="#ga5b88461b126b1c226121146c87d5abe2">◆ </a></span>flash_range_erase()</h2>
272 <div class="memitem">
273 <div class="memproto">
274 <table class="memname">
276 <td class="memname">void flash_range_erase </td>
278 <td class="paramtype">uint32_t </td>
279 <td class="paramname"><em>flash_offs</em>, </td>
282 <td class="paramkey"></td>
284 <td class="paramtype">size_t </td>
285 <td class="paramname"><em>count</em> </td>
293 </div><div class="memdoc">
295 <p>Erase areas of flash. </p>
296 <dl class="params"><dt>Parameters</dt><dd>
297 <table class="params">
298 <tr><td class="paramname">flash_offs</td><td>Offset into flash, in bytes, to start the erase. Must be aligned to a 4096-byte flash sector. </td></tr>
299 <tr><td class="paramname">count</td><td>Number of bytes to be erased. Must be a multiple of 4096 bytes (one sector).</td></tr>
303 <dl class="section note"><dt>Note</dt><dd>Erasing a flash sector sets all the bits in all the pages in that sector to one. You can then "program" flash pages in the sector to turn some of the bits to zero. Once a bit is set to zero it can only be changed back to one by erasing the whole sector again. </dd></dl>
307 <a id="ga345513fba0951661d012fa20a6441c5f" name="ga345513fba0951661d012fa20a6441c5f"></a>
308 <h2 class="memtitle"><span class="permalink"><a href="#ga345513fba0951661d012fa20a6441c5f">◆ </a></span>flash_range_program()</h2>
310 <div class="memitem">
311 <div class="memproto">
312 <table class="memname">
314 <td class="memname">void flash_range_program </td>
316 <td class="paramtype">uint32_t </td>
317 <td class="paramname"><em>flash_offs</em>, </td>
320 <td class="paramkey"></td>
322 <td class="paramtype">const uint8_t * </td>
323 <td class="paramname"><em>data</em>, </td>
326 <td class="paramkey"></td>
328 <td class="paramtype">size_t </td>
329 <td class="paramname"><em>count</em> </td>
337 </div><div class="memdoc">
339 <p>Program flash. </p>
340 <dl class="params"><dt>Parameters</dt><dd>
341 <table class="params">
342 <tr><td class="paramname">flash_offs</td><td>Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page. </td></tr>
343 <tr><td class="paramname">data</td><td>Pointer to the data to program into flash </td></tr>
344 <tr><td class="paramname">count</td><td>Number of bytes to program. Must be a multiple of 256 bytes (one page).</td></tr>
348 <dl class="section note"><dt>Note</dt><dd>: Programming a flash page effectively changes some of the bits from one to zero. The only way to change a zero bit back to one is to "erase" the whole sector that the page resides in. So you may need to make sure you have called flash_range_erase before calling flash_range_program. </dd></dl>
352 </div><!-- contents -->
353 </div><!-- doc-content -->
355 <script src="main.js"></script>