⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 howdoi.html

📁 yavrtos,一款用于广泛用于AVR单片机的RTOS,文件里是这款OS的源码
💻 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>YAVRTOS: How do I?</title><link href="doxygen.css" rel="stylesheet" type="text/css"><link href="tabs.css" rel="stylesheet" type="text/css"></head><body><!-- Generated by Doxygen 1.5.4 --><div class="tabs">  <ul>    <li><a href="index.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>    <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>  </ul></div><h1><a class="anchor" name="howdoI">How do I? </a></h1><h2><a class="anchor" name="malloc">How do I use malloc() and free() safely?</a></h2>It depends on whether you intend to use malloc() or free() from within ISRs (which is highly discouraged) or from within idle tasks (i.e. tasks with a zero priority). Note that <a class="el" href="group__task.html#g9b849c9a0e0b29417cf47da99226dcc3" title="Create a task, ready to be run.">create_task()</a> and <a class="el" href="group__task.html#g934155282a1d689b554e90b5138e5135" title="Tasks are kept in a linked list in memory - this function reserves an &quot;empty&quot;...">reserve_task()</a> can call malloc().<h3><a class="anchor" name="malloc-isr">Using malloc() and free() when they are going to be used from within ISRs and/or idle tasks</a></h3>If you are going to use malloc() or free() from within an ISR and/or an idle task, you will need to disable interrupts either side of you call to malloc() and free()<p><div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> proc() {  <span class="keywordtype">int</span> *data = 0;  <a class="code" href="group__task.html#g42c4528688cb31827aa5efb696995642" title="A flag indicating whether interrupts were enabled - used by disable_interrupts()...">interrupt_store_t</a> interrupts;  interrupts = <a class="code" href="group__task.html#g6984a5336b36a4ca99682a2cf5ae044f" title="Disable interrupts system-wide.">disable_interrupts</a>();  data = malloc(REQUIRED_INTS * <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));  <a class="code" href="group__task.html#gecf8a8e43c2afae89e46503ff1c887bf" title="Restore the state of the system-wide interrupts.">restore_interrupts</a>(interrupts);  ...  interrupts = <a class="code" href="group__task.html#g6984a5336b36a4ca99682a2cf5ae044f" title="Disable interrupts system-wide.">disable_interrupts</a>();  free(data);  <a class="code" href="group__task.html#gecf8a8e43c2afae89e46503ff1c887bf" title="Restore the state of the system-wide interrupts.">restore_interrupts</a>(interrupts);  ...}</pre></div><p>The reason why we use the <code>interrupt_store_t</code> is because our <code>proc()</code> may have been called by another function that disabled interrupts for its own purposes, and it could be disastrous to unexpectedly enable interrupts on it.<p>We also want to disable interrupts for the shortest possible period of time, as disabling interrupts disables the all-important tick.<p>Note that interrupts will be disabled for the duration of the call to malloc() and free(). Depending on the algorithm used by malloc() and free(), and depending on what your time margin for the launch of ISRs is, interrupts could be disabled for "too long". And note that malloc() is called by <a class="el" href="group__task.html#g934155282a1d689b554e90b5138e5135" title="Tasks are kept in a linked list in memory - this function reserves an &quot;empty&quot;...">reserve_task()</a>, and can be called by <a class="el" href="group__task.html#g9b849c9a0e0b29417cf47da99226dcc3" title="Create a task, ready to be run.">create_task()</a>, so using <a class="el" href="group__task.html#g9b849c9a0e0b29417cf47da99226dcc3" title="Create a task, ready to be run.">create_task()</a> and <a class="el" href="group__task.html#g934155282a1d689b554e90b5138e5135" title="Tasks are kept in a linked list in memory - this function reserves an &quot;empty&quot;...">reserve_task()</a> in such time-critical situations could break your application.<h3><a class="anchor" name="malloc-no-isr">Using malloc() and free() when they are not going to be used from within ISRs or idle tasks</a></h3>If you are not going to use malloc() or free() from within ISRs or idle tasks, then you can create a <a class="el" href="group__mutex.html">mutex</a> for the microcontroller's memory.<p><div class="fragment"><pre class="fragment"><a class="code" href="structmutex__t.html" title="A structure describing a mutex.">mutex_t</a> memory_mutex;<span class="keywordtype">void</span> proc() {  <span class="keywordtype">int</span> *data = 0;  <a class="code" href="group__mutex.html#gdff77e0b451c30c07d2990e669f937c5" title="Lock on a mutex.">lock_on</a>(&amp;memory_mutex);  data = malloc(REQUIRED_INTS * <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));  <a class="code" href="group__mutex.html#g327f419711064b7407f6f47011221cc4" title="Unlock a mutex.">lock_off</a>(&amp;memory_mutex);  ...  <a class="code" href="group__mutex.html#gdff77e0b451c30c07d2990e669f937c5" title="Lock on a mutex.">lock_on</a>(&amp;memory_mutex);  free(data);  <a class="code" href="group__mutex.html#g327f419711064b7407f6f47011221cc4" title="Unlock a mutex.">lock_off</a>(&amp;memory_mutex);  ...}</pre></div><p>If you do this, then you <b>must</b> specify <code>wait_for_mutexes</code> in <a class="el" href="group__task.html#ge1337adc1d63d7cd874a376d6513c04a" title="Stop a task.">stop_task()</a> when stopping any task that uses the memory mutex. This is because <a class="el" href="group__task.html#ge1337adc1d63d7cd874a376d6513c04a" title="Stop a task.">stop_task()</a> could be called when the task is in the middle of executing malloc() or free(), and if malloc() or free() are not allowed to complete themselves, corruption of the tables used by malloc() and free() could result.<p>Using a memory mutex, however, has the significant advantage that interrupts are only disabled for a very short period of time during <a class="el" href="group__mutex.html#gdff77e0b451c30c07d2990e669f937c5" title="Lock on a mutex.">lock_on()</a> and <a class="el" href="group__mutex.html#g327f419711064b7407f6f47011221cc4" title="Unlock a mutex.">lock_off()</a>.<p>If you are using a mutex for the microcontrollers' memory, remember to use that mutex in all calls to <a class="el" href="group__task.html#g9b849c9a0e0b29417cf47da99226dcc3" title="Create a task, ready to be run.">create_task()</a> and <a class="el" href="group__task.html#g934155282a1d689b554e90b5138e5135" title="Tasks are kept in a linked list in memory - this function reserves an &quot;empty&quot;...">reserve_task()</a>. (If you haven't yet started the RTOS with <a class="el" href="group__task.html#g1398c4d9f97349ea3fa7d91349298521" title="Start the whole process running.">task_switcher_start()</a>, then the <code>memory_mutex</code> argument to <a class="el" href="group__task.html#g9b849c9a0e0b29417cf47da99226dcc3" title="Create a task, ready to be run.">create_task()</a> and <a class="el" href="group__task.html#g934155282a1d689b554e90b5138e5135" title="Tasks are kept in a linked list in memory - this function reserves an &quot;empty&quot;...">reserve_task()</a> will be ignored, and interrupts will be disabled during the calls to malloc()).<p><div class="fragment"><pre class="fragment"><a class="code" href="structmutex__t.html" title="A structure describing a mutex.">mutex_t</a> memory_mutex;<span class="keywordtype">void</span> proc() {  <span class="keywordtype">int</span> *data = 0;  <a class="code" href="group__mutex.html#gdff77e0b451c30c07d2990e669f937c5" title="Lock on a mutex.">lock_on</a>(&amp;memory_mutex);  data = malloc(REQUIRED_INTS * <span class="keyword">sizeof</span>(<span class="keywordtype">int</span>));  <a class="code" href="group__mutex.html#g327f419711064b7407f6f47011221cc4" title="Unlock a mutex.">lock_off</a>(&amp;memory_mutex);  ...  <span class="comment">// We must use the mutex in all calls to create_task() and reserve_task()!</span>  <a class="code" href="group__task.html#g9b849c9a0e0b29417cf47da99226dcc3" title="Create a task, ready to be run.">create_task</a>(task2, 0, 0, 55, 20, &amp;memory_mutex);  ...  <a class="code" href="group__mutex.html#gdff77e0b451c30c07d2990e669f937c5" title="Lock on a mutex.">lock_on</a>(&amp;memory_mutex);  free(data);  <a class="code" href="group__mutex.html#g327f419711064b7407f6f47011221cc4" title="Unlock a mutex.">lock_off</a>(&amp;memory_mutex);  ...}</pre></div><h2><a class="anchor" name="how-write-isr">How do I write my own ISR?</a></h2>For instance, we will write an ISR for the INT0 interrupt.<p><div class="fragment"><pre class="fragment"><span class="comment">// Define the ISR prototype, so that the TASK_ISR() macro can reference our ISR function "int0_isr()"</span>uint8_t int0_isr();<span class="comment">// Set up the INT0 vector so that it calls the ISR</span><a class="code" href="group__isr.html#g3d04938242a5060aac8a64b72c055eb0" title="The macro for ISRs.">TASK_ISR</a>(INT0_vect, int0_isr())<span class="comment">// Now, we can write the ISR function itself. It should return non-zero if a task switch should occur.</span><span class="comment">// It is recommended that it returns non-zero - the only time it would be safe for it to return zero</span><span class="comment">// would be if it didn't do anything to any task, semaphore, mailbox or mutex (i.e. if it didn't do anything</span><span class="comment">// that could un-suspend a suspended task).</span>uint8_t int0_isr() {  ...}</pre></div><p>Upon entry into the <code>int0_isr</code> function, interrupts will be disabled, and the system stack will be in use. <hr><p align="center"><font size="-1">YAVRTOS and YAVRTOS documentation Copyright &copy; 2007-2008 Chris O'Byrne. Email - chris &lt;at&gt; obyrne &lt;dot&gt; com</font></p></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -