gnuk/ChibiOS_2.0.6/docs/html/article_create_thread.html
2010-11-22 14:53:37 +09:00

176 lines
14 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>ChibiOS/RT: How to create a thread</title>
<link href="custom.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<table style="text-align: center; width: 100%;" border="0"
cellpadding="2" cellspacing="2">
<tbody>
<tr>
<td style="width: 80px;"><img alt="ChibiOS/RT Logo" src="logo_small.png"></td>
<td><big><big>ChibiOS/RT</big></big><br><br>Architecture - Reference Manual - Guides</td>
<td style="width: 80px;"></td>
</tr>
</tbody>
</table>
<hr size="1">
<!-- Generated by Doxygen 1.7.1 -->
<div class="navigation" id="top">
<div class="tabs">
<ul class="tablist">
<li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
<li><a href="modules.html"><span>Modules</span></a></li>
<li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
<div class="navpath">
<ul>
<li><a class="el" href="main.html">ChibiOS/RT</a> </li>
<li><a class="el" href="articles.html">Articles and Code Samples</a> </li>
<li><a class="el" href="page_howtos.html">How To's</a> </li>
</ul>
</div>
</div>
<div class="header">
<div class="headertitle">
<h1>How to create a thread </h1> </div>
</div>
<div class="contents">
<p>At the system startup there are already two active threads:</p>
<ul>
<li><b>Idle thread</b>. This thread has the lowest priority in the system so it runs only when the other threads in the system are sleeping. This threads usually switches the system in a low power mode and does nothing else.</li>
<li><b>Main thread</b>. This thread executes your <code>main()</code> function at startup. The main thread is created at the <code>NORMALPRIO</code> level but it can change its own priority if required. It is from the main thread that the other threads are usually created.</li>
</ul>
<p>There are two kind of threads in ChibiOS/RT:</p>
<ul>
<li><b>Static Threads</b>. This kind of threads are statically allocated in memory. The memory used by the thread cannot reused except for restarting the threads.</li>
<li><b>Dynamic Threads</b>. Threads created by allocating memory from a memory heap or a memory pool.</li>
</ul>
<h2>Creating a static thread</h2>
<p>In order to create a static thread a working area must be declared using the macro <code>WORKING_AREA</code> as shown: </p>
<div class="fragment"><pre class="fragment"><span class="keyword">static</span> <a class="code" href="group__core.html#gac8b681d521d3b6c25e7a0304674732c9" title="Static working area allocation.">WORKING_AREA</a>(myThreadWorkingArea, 128);
</pre></div><p> This macro reserves 128 bytes of stack for the thread and space for all the required thread related structures. The total size and the alignment problems are handled inside the macro, you only need to specify the pure stack size.<br/>
A thread can be started by invoking <code><a class="el" href="group__threads.html#ga048e588238dd336c6059133b3d0c3435" title="Creates a new thread into a static memory area.">chThdCreateStatic()</a></code> as shown in this example: </p>
<div class="fragment"><pre class="fragment"> <a class="code" href="struct_thread.html" title="Structure representing a thread.">Thread</a> *tp = <a class="code" href="group__threads.html#ga048e588238dd336c6059133b3d0c3435" title="Creates a new thread into a static memory area.">chThdCreateStatic</a>(myThreadWorkingArea,
<span class="keyword">sizeof</span>(myThreadWorkingArea),
<a class="code" href="group__scheduler.html#gad6a6b28f0c1cf8e0da714ef771fb90a0" title="Normal user priority.">NORMALPRIO</a>, <span class="comment">/* Initial priority. */</span>
myThread, <span class="comment">/* Thread function. */</span>
NULL); <span class="comment">/* Thread parameter. */</span>
</pre></div><p> The variable tp receives the pointer to the thread object, it is taken by other APIs as parameter.<br/>
Now a complete example: </p>
<div class="fragment"><pre class="fragment"><span class="comment">/*</span>
<span class="comment"> * My simple application.</span>
<span class="comment"> */</span>
<span class="preprocessor">#include &lt;<a class="code" href="ch_8h.html" title="ChibiOS/RT main include file.">ch.h</a>&gt;</span>
<span class="comment">/*</span>
<span class="comment"> * Working area for the LED flashing thread.</span>
<span class="comment"> */</span>
<span class="keyword">static</span> <a class="code" href="group__core.html#gac8b681d521d3b6c25e7a0304674732c9" title="Static working area allocation.">WORKING_AREA</a>(myThreadWorkingArea, 128);
<span class="comment">/*</span>
<span class="comment"> * LED flashing thread.</span>
<span class="comment"> */</span>
<span class="keyword">static</span> <a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a> myThread(<span class="keywordtype">void</span> *arg) {
<span class="keywordflow">while</span> (TRUE) {
LED_ON();
<a class="code" href="group__threads.html#ga5aebc25e053a0094714abce4cad9f56f" title="Delays the invoking thread for the specified number of milliseconds.">chThdSleepMilliseconds</a>(500);
LED_OFF();
<a class="code" href="group__threads.html#ga5aebc25e053a0094714abce4cad9f56f" title="Delays the invoking thread for the specified number of milliseconds.">chThdSleepMilliseconds</a>(500);
}
}
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) {
<span class="comment">/* Starting the flashing LEDs thread.*/</span>
(void)<a class="code" href="group__threads.html#ga048e588238dd336c6059133b3d0c3435" title="Creates a new thread into a static memory area.">chThdCreateStatic</a>(myThreadWorkingArea, <span class="keyword">sizeof</span>(myThreadWorkingArea),
NORMALPRIO, myThread, NULL);
.
.
.
}
</pre></div><p> Note that the memory allocated to myThread() is statically defined and cannot be reused. Static threads are ideal for safety applications because there is no risk of a memory allocation failure because progressive heap fragmentation.</p>
<h2>Creating a dynamic thread using the heap allocator</h2>
<p>In order to create a thread from a memory heap is very easy: </p>
<div class="fragment"><pre class="fragment"> <a class="code" href="struct_thread.html" title="Structure representing a thread.">Thread</a> *tp = <a class="code" href="group__threads.html#ga50b84e3e82a4e09c1066e1d422e4c780" title="Creates a new thread allocating the memory from the heap.">chThdCreateFromHeap</a>(NULL, <span class="comment">/* NULL = Default heap. */</span>
<a class="code" href="group__core.html#gaf7a83c1c8bde96b77299c36dc598d33d" title="Computes the thread working area global size.">THD_WA_SIZE</a>(128),<span class="comment">/* Stack size. */</span>
<a class="code" href="group__scheduler.html#gad6a6b28f0c1cf8e0da714ef771fb90a0" title="Normal user priority.">NORMALPRIO</a>, <span class="comment">/* Initial priority. */</span>
myThread, <span class="comment">/* Thread function. */</span>
NULL); <span class="comment">/* Thread parameter. */</span>
</pre></div><p> The memory is allocated from the spawned heap and the thread is started. Note that the memory is not freed when the thread terminates but when the thread final status (its return value) is collected by the spawning thread. As example: </p>
<div class="fragment"><pre class="fragment"><span class="keyword">static</span> <a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a> myThread(<span class="keywordtype">void</span> *arg) {
<span class="keywordtype">unsigned</span> i = 10;
<span class="keywordflow">while</span> (i &gt; 0) {
LED_ON();
<a class="code" href="group__threads.html#ga5aebc25e053a0094714abce4cad9f56f" title="Delays the invoking thread for the specified number of milliseconds.">chThdSleepMilliseconds</a>(500);
LED_OFF();
<a class="code" href="group__threads.html#ga5aebc25e053a0094714abce4cad9f56f" title="Delays the invoking thread for the specified number of milliseconds.">chThdSleepMilliseconds</a>(500);
i--;
}
<span class="keywordflow">return</span> (<a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a>)i;
}
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) {
<a class="code" href="struct_thread.html" title="Structure representing a thread.">Thread</a> *tp = <a class="code" href="group__threads.html#ga50b84e3e82a4e09c1066e1d422e4c780" title="Creates a new thread allocating the memory from the heap.">chThdCreateFromHeap</a>(NULL, <a class="code" href="group__core.html#gaf7a83c1c8bde96b77299c36dc598d33d" title="Computes the thread working area global size.">THD_WA_SIZE</a>(128), <a class="code" href="group__scheduler.html#gad6a6b28f0c1cf8e0da714ef771fb90a0" title="Normal user priority.">NORMALPRIO</a>+1,
myThread, NULL);
<span class="keywordflow">if</span> (tp == NULL)
<a class="code" href="group__system.html#gad43b78f160a2c983792af3041cc4a536" title="Halts the system.">chSysHalt</a>(); <span class="comment">/* Memory exausted. */</span>
<span class="comment">/* The main thread continues its normal execution.*/</span>
.
.
<span class="comment">/*</span>
<span class="comment"> * Now waits for the spawned thread to terminate (if it has not terminated</span>
<span class="comment"> * already) then gets the thread exit message (msg) and returns the</span>
<span class="comment"> * terminated thread memory to the heap (default system heap in this</span>
<span class="comment"> * example).</span>
<span class="comment"> */</span>
<a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a> msg = <a class="code" href="group__threads.html#ga94a5727ecdbe0f738dfc8e1ede1c3409" title="Blocks the execution of the invoking thread until the specified thread terminates then the exit code ...">chThdWait</a>(tp);
.
.
}
</pre></div><h2>Creating a dynamic thread using the heap allocator</h2>
<p>A pool is a collection of equally sized memory blocks, creating a thread from a memry pool is very similar to the previous example but the memory of terminated threads is returned to the memory pool rather than to a heap: </p>
<div class="fragment"><pre class="fragment"><span class="keyword">static</span> <a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a> myThread(<span class="keywordtype">void</span> *arg) {
<span class="keywordtype">unsigned</span> i = 10;
<span class="keywordflow">while</span> (i &gt; 0) {
LED_ON();
<a class="code" href="group__threads.html#ga5aebc25e053a0094714abce4cad9f56f" title="Delays the invoking thread for the specified number of milliseconds.">chThdSleepMilliseconds</a>(500);
LED_OFF();
<a class="code" href="group__threads.html#ga5aebc25e053a0094714abce4cad9f56f" title="Delays the invoking thread for the specified number of milliseconds.">chThdSleepMilliseconds</a>(500);
i--;
}
<span class="keywordflow">return</span> (<a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a>)i;
}
<span class="keywordtype">int</span> main(<span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> *argv[]) {
<a class="code" href="struct_thread.html" title="Structure representing a thread.">Thread</a> *tp = <a class="code" href="group__threads.html#gad3ccc1a6f054c543258ed2fe97ed2f58" title="Creates a new thread allocating the memory from the specified memory pool.">chThdCreateFromMemoryPool</a>(myPool, <a class="code" href="group__scheduler.html#gad6a6b28f0c1cf8e0da714ef771fb90a0" title="Normal user priority.">NORMALPRIO</a>+1, myThread, NULL);
<span class="keywordflow">if</span> (tp == NULL)
<a class="code" href="group__system.html#gad43b78f160a2c983792af3041cc4a536" title="Halts the system.">chSysHalt</a>(); <span class="comment">/* Pool empty. */</span>
<span class="comment">/* The main thread continues its normal execution.*/</span>
.
.
<span class="comment">/*</span>
<span class="comment"> * Now waits for the spawned thread to terminate (if it has not terminated</span>
<span class="comment"> * already) then gets the thread exit message (msg) and returns the</span>
<span class="comment"> * terminated thread memory to the original memory pool.</span>
<span class="comment"> */</span>
<a class="code" href="group__types.html#ga35bcb0c321cd7bc45bf1a11fa17ebdd3" title="Message, use signed pointer equivalent.">msg_t</a> msg = <a class="code" href="group__threads.html#ga94a5727ecdbe0f738dfc8e1ede1c3409" title="Blocks the execution of the invoking thread until the specified thread terminates then the exit code ...">chThdWait</a>(tp);
.
.
}
</pre></div> </div>
<hr size="1"><address style="text-align: right;"><small>
Generated on Sun Oct 24 2010 09:40:44 for ChibiOS/RT by&nbsp;<a href="http://www.doxygen.org/index.html"><img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.7.1</small></address>
</body>
</html>