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: sem</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__sem.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">sem<div class="ingroups"><a class="el" href="group__high__level.html">High Level APIs</a> » <a class="el" href="group__pico__sync.html">pico_sync</a></div></div></div>
109 <div class="contents">
111 <p>Semaphore API for restricting access to a resource.
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:gab4e56b5ccfacafd2fb17765e702a21ba"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#gab4e56b5ccfacafd2fb17765e702a21ba">sem_init</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem, int16_t initial_permits, int16_t max_permits)</td></tr>
117 <tr class="memdesc:gab4e56b5ccfacafd2fb17765e702a21ba"><td class="mdescLeft"> </td><td class="mdescRight">Initialise a semaphore structure. <a href="group__sem.html#gab4e56b5ccfacafd2fb17765e702a21ba">More...</a><br /></td></tr>
118 <tr class="separator:gab4e56b5ccfacafd2fb17765e702a21ba"><td class="memSeparator" colspan="2"> </td></tr>
119 <tr class="memitem:gad9e065ef0c0e59309f9bdb5fb74bb7c1"><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#gad9e065ef0c0e59309f9bdb5fb74bb7c1">sem_available</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem)</td></tr>
120 <tr class="memdesc:gad9e065ef0c0e59309f9bdb5fb74bb7c1"><td class="mdescLeft"> </td><td class="mdescRight">Return number of available permits on the semaphore. <a href="group__sem.html#gad9e065ef0c0e59309f9bdb5fb74bb7c1">More...</a><br /></td></tr>
121 <tr class="separator:gad9e065ef0c0e59309f9bdb5fb74bb7c1"><td class="memSeparator" colspan="2"> </td></tr>
122 <tr class="memitem:gaeac89066f5fdbde0c7db2718464dcbde"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#gaeac89066f5fdbde0c7db2718464dcbde">sem_release</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem)</td></tr>
123 <tr class="memdesc:gaeac89066f5fdbde0c7db2718464dcbde"><td class="mdescLeft"> </td><td class="mdescRight">Release a permit on a semaphore. <a href="group__sem.html#gaeac89066f5fdbde0c7db2718464dcbde">More...</a><br /></td></tr>
124 <tr class="separator:gaeac89066f5fdbde0c7db2718464dcbde"><td class="memSeparator" colspan="2"> </td></tr>
125 <tr class="memitem:gab6c128952e4981a95ce2e2d093a8a3ba"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#gab6c128952e4981a95ce2e2d093a8a3ba">sem_reset</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem, int16_t permits)</td></tr>
126 <tr class="memdesc:gab6c128952e4981a95ce2e2d093a8a3ba"><td class="mdescLeft"> </td><td class="mdescRight">Reset semaphore to a specific number of available permits. <a href="group__sem.html#gab6c128952e4981a95ce2e2d093a8a3ba">More...</a><br /></td></tr>
127 <tr class="separator:gab6c128952e4981a95ce2e2d093a8a3ba"><td class="memSeparator" colspan="2"> </td></tr>
128 <tr class="memitem:gaefa22667355703497ae883f68a87aacf"><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#gaefa22667355703497ae883f68a87aacf">sem_acquire_blocking</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem)</td></tr>
129 <tr class="memdesc:gaefa22667355703497ae883f68a87aacf"><td class="mdescLeft"> </td><td class="mdescRight">Acquire a permit from the semaphore. <a href="group__sem.html#gaefa22667355703497ae883f68a87aacf">More...</a><br /></td></tr>
130 <tr class="separator:gaefa22667355703497ae883f68a87aacf"><td class="memSeparator" colspan="2"> </td></tr>
131 <tr class="memitem:ga38275bfc4c00e5039028f58860709610"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#ga38275bfc4c00e5039028f58860709610">sem_acquire_timeout_ms</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem, uint32_t timeout_ms)</td></tr>
132 <tr class="memdesc:ga38275bfc4c00e5039028f58860709610"><td class="mdescLeft"> </td><td class="mdescRight">Acquire a permit from a semaphore, with timeout. <a href="group__sem.html#ga38275bfc4c00e5039028f58860709610">More...</a><br /></td></tr>
133 <tr class="separator:ga38275bfc4c00e5039028f58860709610"><td class="memSeparator" colspan="2"> </td></tr>
134 <tr class="memitem:ga0f5a509fb132e8e764795a66773500ad"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#ga0f5a509fb132e8e764795a66773500ad">sem_acquire_timeout_us</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem, uint32_t timeout_us)</td></tr>
135 <tr class="memdesc:ga0f5a509fb132e8e764795a66773500ad"><td class="mdescLeft"> </td><td class="mdescRight">Acquire a permit from a semaphore, with timeout. <a href="group__sem.html#ga0f5a509fb132e8e764795a66773500ad">More...</a><br /></td></tr>
136 <tr class="separator:ga0f5a509fb132e8e764795a66773500ad"><td class="memSeparator" colspan="2"> </td></tr>
137 <tr class="memitem:ga4410f17fc2f35b91e5bcfaf18bcf26ae"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#ga4410f17fc2f35b91e5bcfaf18bcf26ae">sem_acquire_block_until</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem, <a class="el" href="group__timestamp.html#ga8b7f3d602cc053f05bacceeacc257ed8">absolute_time_t</a> until)</td></tr>
138 <tr class="memdesc:ga4410f17fc2f35b91e5bcfaf18bcf26ae"><td class="mdescLeft"> </td><td class="mdescRight">Wait to acquire a permit from a semaphore until a specific time. <a href="group__sem.html#ga4410f17fc2f35b91e5bcfaf18bcf26ae">More...</a><br /></td></tr>
139 <tr class="separator:ga4410f17fc2f35b91e5bcfaf18bcf26ae"><td class="memSeparator" colspan="2"> </td></tr>
140 <tr class="memitem:ga25b473ab6f287e4a6a0c9d0288a0a497"><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><a class="el" href="group__sem.html#ga25b473ab6f287e4a6a0c9d0288a0a497">sem_try_acquire</a> (<a class="el" href="structsemaphore.html">semaphore_t</a> *sem)</td></tr>
141 <tr class="memdesc:ga25b473ab6f287e4a6a0c9d0288a0a497"><td class="mdescLeft"> </td><td class="mdescRight">Attempt to acquire a permit from a semaphore without blocking. <a href="group__sem.html#ga25b473ab6f287e4a6a0c9d0288a0a497">More...</a><br /></td></tr>
142 <tr class="separator:ga25b473ab6f287e4a6a0c9d0288a0a497"><td class="memSeparator" colspan="2"> </td></tr>
144 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
145 <p >Semaphore API for restricting access to a resource. </p>
146 <p >A semaphore holds a number of available permits. <code>sem_acquire</code> methods will acquire a permit if available (reducing the available count by 1) or block if the number of available permits is 0. <a class="el" href="group__sem.html#gaeac89066f5fdbde0c7db2718464dcbde">sem_release()</a> increases the number of available permits by one potentially unblocking a <code>sem_acquire</code> method.</p>
147 <p >Note that <a class="el" href="group__sem.html#gaeac89066f5fdbde0c7db2718464dcbde">sem_release()</a> may be called an arbitrary number of times, however the number of available permits is capped to the max_permit value specified during semaphore initialization.</p>
148 <p >Although these semaphore related functions can be used from IRQ handlers, it is obviously preferable to only release semaphores from within an IRQ handler (i.e. avoid blocking) </p>
149 <h2 class="groupheader">Function Documentation</h2>
150 <a id="ga4410f17fc2f35b91e5bcfaf18bcf26ae" name="ga4410f17fc2f35b91e5bcfaf18bcf26ae"></a>
151 <h2 class="memtitle"><span class="permalink"><a href="#ga4410f17fc2f35b91e5bcfaf18bcf26ae">◆ </a></span>sem_acquire_block_until()</h2>
153 <div class="memitem">
154 <div class="memproto">
155 <table class="memname">
157 <td class="memname">bool sem_acquire_block_until </td>
159 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
160 <td class="paramname"><em>sem</em>, </td>
163 <td class="paramkey"></td>
165 <td class="paramtype"><a class="el" href="group__timestamp.html#ga8b7f3d602cc053f05bacceeacc257ed8">absolute_time_t</a> </td>
166 <td class="paramname"><em>until</em> </td>
174 </div><div class="memdoc">
176 <p>Wait to acquire a permit from a semaphore until a specific time. </p>
177 <p >This function will block and wait if no permits are available, until the specified timeout time. If the timeout is reached the function will return false, otherwise it will return true.</p>
178 <dl class="params"><dt>Parameters</dt><dd>
179 <table class="params">
180 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
181 <tr><td class="paramname">until</td><td>The time after which to return if the sem is not available. </td></tr>
185 <dl class="section return"><dt>Returns</dt><dd>true if permit was acquired, false if the until time was reached before acquiring. </dd></dl>
189 <a id="gaefa22667355703497ae883f68a87aacf" name="gaefa22667355703497ae883f68a87aacf"></a>
190 <h2 class="memtitle"><span class="permalink"><a href="#gaefa22667355703497ae883f68a87aacf">◆ </a></span>sem_acquire_blocking()</h2>
192 <div class="memitem">
193 <div class="memproto">
194 <table class="memname">
196 <td class="memname">void sem_acquire_blocking </td>
198 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
199 <td class="paramname"><em>sem</em></td><td>)</td>
203 </div><div class="memdoc">
205 <p>Acquire a permit from the semaphore. </p>
206 <p >This function will block and wait if no permits are available.</p>
207 <dl class="params"><dt>Parameters</dt><dd>
208 <table class="params">
209 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
216 <a id="ga38275bfc4c00e5039028f58860709610" name="ga38275bfc4c00e5039028f58860709610"></a>
217 <h2 class="memtitle"><span class="permalink"><a href="#ga38275bfc4c00e5039028f58860709610">◆ </a></span>sem_acquire_timeout_ms()</h2>
219 <div class="memitem">
220 <div class="memproto">
221 <table class="memname">
223 <td class="memname">bool sem_acquire_timeout_ms </td>
225 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
226 <td class="paramname"><em>sem</em>, </td>
229 <td class="paramkey"></td>
231 <td class="paramtype">uint32_t </td>
232 <td class="paramname"><em>timeout_ms</em> </td>
240 </div><div class="memdoc">
242 <p>Acquire a permit from a semaphore, with timeout. </p>
243 <p >This function will block and wait if no permits are available, until the defined timeout has been reached. If the timeout is reached the function will return false, otherwise it will return true.</p>
244 <dl class="params"><dt>Parameters</dt><dd>
245 <table class="params">
246 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
247 <tr><td class="paramname">timeout_ms</td><td>Time to wait to acquire the semaphore, in milliseconds. </td></tr>
251 <dl class="section return"><dt>Returns</dt><dd>false if timeout reached, true if permit was acquired. </dd></dl>
255 <a id="ga0f5a509fb132e8e764795a66773500ad" name="ga0f5a509fb132e8e764795a66773500ad"></a>
256 <h2 class="memtitle"><span class="permalink"><a href="#ga0f5a509fb132e8e764795a66773500ad">◆ </a></span>sem_acquire_timeout_us()</h2>
258 <div class="memitem">
259 <div class="memproto">
260 <table class="memname">
262 <td class="memname">bool sem_acquire_timeout_us </td>
264 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
265 <td class="paramname"><em>sem</em>, </td>
268 <td class="paramkey"></td>
270 <td class="paramtype">uint32_t </td>
271 <td class="paramname"><em>timeout_us</em> </td>
279 </div><div class="memdoc">
281 <p>Acquire a permit from a semaphore, with timeout. </p>
282 <p >This function will block and wait if no permits are available, until the defined timeout has been reached. If the timeout is reached the function will return false, otherwise it will return true.</p>
283 <dl class="params"><dt>Parameters</dt><dd>
284 <table class="params">
285 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
286 <tr><td class="paramname">timeout_us</td><td>Time to wait to acquire the semaphore, in microseconds. </td></tr>
290 <dl class="section return"><dt>Returns</dt><dd>false if timeout reached, true if permit was acquired. </dd></dl>
294 <a id="gad9e065ef0c0e59309f9bdb5fb74bb7c1" name="gad9e065ef0c0e59309f9bdb5fb74bb7c1"></a>
295 <h2 class="memtitle"><span class="permalink"><a href="#gad9e065ef0c0e59309f9bdb5fb74bb7c1">◆ </a></span>sem_available()</h2>
297 <div class="memitem">
298 <div class="memproto">
299 <table class="memname">
301 <td class="memname">int sem_available </td>
303 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
304 <td class="paramname"><em>sem</em></td><td>)</td>
308 </div><div class="memdoc">
310 <p>Return number of available permits on the semaphore. </p>
311 <dl class="params"><dt>Parameters</dt><dd>
312 <table class="params">
313 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
317 <dl class="section return"><dt>Returns</dt><dd>The number of permits available on the semaphore. </dd></dl>
321 <a id="gab4e56b5ccfacafd2fb17765e702a21ba" name="gab4e56b5ccfacafd2fb17765e702a21ba"></a>
322 <h2 class="memtitle"><span class="permalink"><a href="#gab4e56b5ccfacafd2fb17765e702a21ba">◆ </a></span>sem_init()</h2>
324 <div class="memitem">
325 <div class="memproto">
326 <table class="memname">
328 <td class="memname">void sem_init </td>
330 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
331 <td class="paramname"><em>sem</em>, </td>
334 <td class="paramkey"></td>
336 <td class="paramtype">int16_t </td>
337 <td class="paramname"><em>initial_permits</em>, </td>
340 <td class="paramkey"></td>
342 <td class="paramtype">int16_t </td>
343 <td class="paramname"><em>max_permits</em> </td>
351 </div><div class="memdoc">
353 <p>Initialise a semaphore structure. </p>
354 <dl class="params"><dt>Parameters</dt><dd>
355 <table class="params">
356 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
357 <tr><td class="paramname">initial_permits</td><td>How many permits are initially acquired </td></tr>
358 <tr><td class="paramname">max_permits</td><td>Total number of permits allowed for this semaphore </td></tr>
365 <a id="gaeac89066f5fdbde0c7db2718464dcbde" name="gaeac89066f5fdbde0c7db2718464dcbde"></a>
366 <h2 class="memtitle"><span class="permalink"><a href="#gaeac89066f5fdbde0c7db2718464dcbde">◆ </a></span>sem_release()</h2>
368 <div class="memitem">
369 <div class="memproto">
370 <table class="memname">
372 <td class="memname">bool sem_release </td>
374 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
375 <td class="paramname"><em>sem</em></td><td>)</td>
379 </div><div class="memdoc">
381 <p>Release a permit on a semaphore. </p>
382 <p >Increases the number of permits by one (unless the number of permits is already at the maximum). A blocked <code>sem_acquire</code> will be released if the number of permits is increased.</p>
383 <dl class="params"><dt>Parameters</dt><dd>
384 <table class="params">
385 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
389 <dl class="section return"><dt>Returns</dt><dd>true if the number of permits available was increased. </dd></dl>
393 <a id="gab6c128952e4981a95ce2e2d093a8a3ba" name="gab6c128952e4981a95ce2e2d093a8a3ba"></a>
394 <h2 class="memtitle"><span class="permalink"><a href="#gab6c128952e4981a95ce2e2d093a8a3ba">◆ </a></span>sem_reset()</h2>
396 <div class="memitem">
397 <div class="memproto">
398 <table class="memname">
400 <td class="memname">void sem_reset </td>
402 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
403 <td class="paramname"><em>sem</em>, </td>
406 <td class="paramkey"></td>
408 <td class="paramtype">int16_t </td>
409 <td class="paramname"><em>permits</em> </td>
417 </div><div class="memdoc">
419 <p>Reset semaphore to a specific number of available permits. </p>
420 <p >Reset value should be from 0 to the max_permits specified in the init function</p>
421 <dl class="params"><dt>Parameters</dt><dd>
422 <table class="params">
423 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
424 <tr><td class="paramname">permits</td><td>the new number of available permits </td></tr>
431 <a id="ga25b473ab6f287e4a6a0c9d0288a0a497" name="ga25b473ab6f287e4a6a0c9d0288a0a497"></a>
432 <h2 class="memtitle"><span class="permalink"><a href="#ga25b473ab6f287e4a6a0c9d0288a0a497">◆ </a></span>sem_try_acquire()</h2>
434 <div class="memitem">
435 <div class="memproto">
436 <table class="memname">
438 <td class="memname">bool sem_try_acquire </td>
440 <td class="paramtype"><a class="el" href="structsemaphore.html">semaphore_t</a> * </td>
441 <td class="paramname"><em>sem</em></td><td>)</td>
445 </div><div class="memdoc">
447 <p>Attempt to acquire a permit from a semaphore without blocking. </p>
448 <p >This function will return false without blocking if no permits are available, otherwise it will acquire a permit and return true.</p>
449 <dl class="params"><dt>Parameters</dt><dd>
450 <table class="params">
451 <tr><td class="paramname">sem</td><td>Pointer to semaphore structure </td></tr>
455 <dl class="section return"><dt>Returns</dt><dd>true if permit was acquired. </dd></dl>
459 </div><!-- contents -->
460 </div><!-- doc-content -->
462 <script src="main.js"></script>