?? group__isr.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: Interrupt Service Routines</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 Page</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> </ul></div><h1>Interrupt Service Routines</h1><table border="0" cellpadding="0" cellspacing="0"><tr><td></td></tr><tr><td colspan="2"><br><h2>Defines</h2></td></tr><tr><td class="memItemLeft" nowrap align="right" valign="top">#define </td><td class="memItemRight" valign="bottom"><a class="el" href="group__isr.html#g3d04938242a5060aac8a64b72c055eb0">TASK_ISR</a>(vector, do_task_switch)</td></tr><tr><td class="mdescLeft"> </td><td class="mdescRight">The macro for ISRs. <a href="#g3d04938242a5060aac8a64b72c055eb0"></a><br></td></tr></table><hr><a name="_details"></a><h2>Detailed Description</h2>Interrupt Service Routines are functions that are called when an interrupt occurs, and are defined with the <a class="el" href="group__isr.html#g3d04938242a5060aac8a64b72c055eb0" title="The macro for ISRs.">TASK_ISR()</a> macro. <hr><h2>Define Documentation</h2><a class="anchor" name="g3d04938242a5060aac8a64b72c055eb0"></a><!-- doxytag: member="task.h::TASK_ISR" ref="g3d04938242a5060aac8a64b72c055eb0" args="(vector, do_task_switch)" --><div class="memitem"><div class="memproto"> <table class="memname"> <tr> <td class="memname">#define TASK_ISR </td> <td>(</td> <td class="paramtype">vector, <tr> <td class="paramkey"></td> <td></td> <td class="paramtype">do_task_switch </td> <td class="paramname"> </td> <td> ) </td> <td width="100%"></td> </tr> </table></div><div class="memdoc"><p>The macro for ISRs. <p>The arguments are <ul><li><code>vector</code> the ISR vector </li><li><code>do_task_switch</code> something that evaluates non-zero if the ISR should trigger a task switch. This could be a constant, a function call, a macro, anything. Note that the tick interrupt <b>must</b>, by definition, trigger a task switch. It is highly recommended that this macro always evaluates to non-zero - the only time where it would be safe for it to evaluate to zero is if it does absolutely nothing to any task, semaphore, mailbox or mutex (i.e. if it doesn't do anything that could un-suspend a suspended task).</li></ul>See <a class="el" href="example.html">the example application</a> and <a class="el" href="howdoi.html#how-write-isr">how do I write an ISR</a> for examples of usage.<p>The WinAVR™ ISR() macro can also be used to define ISRs - however, when using ISR() as opposed to <a class="el" href="group__isr.html#g3d04938242a5060aac8a64b72c055eb0" title="The macro for ISRs.">TASK_ISR()</a>, you cannot make use of any YAVRTOS API call from within your ISR, and your ISR will not (necessarily) be using the system stack.<p>Taking this macro apart line-by-line, we have<p><div class="fragment"><pre class="fragment"> <span class="comment">// The standard way of calling an ISR</span> <span class="keywordtype">void</span> vector(<span class="keywordtype">void</span>) __attribute__ ((signal,naked,__INTR_ATTRS)); <span class="comment">// The ISR itself</span> <span class="keywordtype">void</span> vector(<span class="keywordtype">void</span>) { <span class="comment">// Save the entire CPU context to the stack (which could be a task stack or the system stack)</span> <a class="code" href="task_8h.html#bedcaab91615f58a55ed4135438618e8" title="Save the CPU context to the stack, and disable interrupts">save_cpu_context</a>(); <span class="comment">// Global interrupts were enabled just before this ISR was launched (otherwise it would not have</span> <span class="comment">// launched), and are disabled upon entry into the ISR. Set the interrupt enable bit at the location of</span> <span class="comment">// the saved status register on the saved stack so that when we restore the CPU context, interrupts will</span> <span class="comment">// be re-enabled.</span> *(((uint8_t*)SP)+1) |= _BV(SREG_I); <span class="comment">// Now, we have either interrupted a task or interrupted another ISR. system.interrupted_task will</span> <span class="comment">// be non-zero if a task has already been interrupted - i.e. if we have interrupted an ISR</span> <span class="comment">// Note that task_switch() also sets system.interrupted_task - any ISRs that manage to run during</span> <span class="comment">// the brief period when task_switch() enables interrupts should not subsequently run task_switch()!</span> <span class="keywordflow">if</span> (<a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#0ffafae88663b0d12161b161d2b87ea1" title="non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required...">interrupted_task</a>) { <span class="comment">// We have interrupted an ISR (or we have interrupted task_switch())</span> <span class="comment">// Execute the macro to see if we should do a task switch</span> <span class="keywordflow">if</span> (do_task_switch) { <span class="comment">// The macro may have enabled interrupts - disable them again</span> cli(); <span class="comment">// Set bit 1 of system.interrupted_task - the bit that signals that a task switch is</span> <span class="comment">// required. We don't do the task switch just yet, as we have interrupted another ISR,</span> <span class="comment">// so we need to return to that ISR first. The ISR that interrupted the task will be the one</span> <span class="comment">// to actually perform the task switch (see below)</span> <span class="comment">// If we have actually interrupted task_switch(), then setting bit 1 of system.interrupted_task</span> <span class="comment">// will have no effect - but we were doing a task switch anyway!</span> <a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#0ffafae88663b0d12161b161d2b87ea1" title="non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required...">interrupted_task</a> = 3; } <span class="keywordflow">else</span> { <span class="comment">// Task switch not required (this time). Make sure that interrupts are still disabled</span> cli(); } } <span class="keywordflow">else</span> { <span class="comment">// We have interrupted a task</span> <span class="comment">// Save the stack pointer</span> <a class="code" href="group__task.html#g4743b3673a8794b8e7bd0b6c91a63cd5" title="The current task.">current_task</a>-><a class="code" href="structtask__t.html#61dcd38718f0b8754f93c77644e9bce0" title="The stack pointer as at the last time this task was suspended">sp</a> = (uint8_t *)SP; <span class="comment">// Switch to the system stack</span> SP = (uint16_t) <a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#ee9b90c55094ba09ac8705e8084ce9b9" title="The top of the system stack.">stack_top</a>; <span class="comment">// Set the system.interrupted_task so that subsequent ISRs will know that they have interrupted</span> <span class="comment">// an ISR, not a task. This has the side-effect of disabling switch_task() - all API calls check</span> <span class="comment">// system.interrupted_task and do NOT perform a task switch if it is non-zero.</span> <a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#0ffafae88663b0d12161b161d2b87ea1" title="non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required...">interrupted_task</a> = 1; <span class="comment">// Execute the macro and see if we should do a task switch</span> if (do_task_switch) { <span class="comment">// The macro could have enabled interrupts - disable them</span> cli(); <span class="comment">// Signal to ourselves that we need a task switch - bit 1 of system.interrupted_task is set</span> <span class="comment">// when a task switch is required</span> <a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#0ffafae88663b0d12161b161d2b87ea1" title="non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required...">interrupted_task</a> = 3; } <span class="keywordflow">else</span> { <span class="comment">// Make sure that interrupts are disabled</span> cli(); } <span class="comment">// At this point, any ISRs that interrupted us have finished.</span> <span class="comment">// Now, if a task switch is required, perform it!</span> <span class="keywordflow">if</span> (<a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#0ffafae88663b0d12161b161d2b87ea1" title="non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required...">interrupted_task</a> & 2) { <span class="comment">// switch_task() will (eventually) reset system.interrupted_task, and never "returns"</span> <a class="code" href="task_8c.html#aa4ee75536398ba2bd21466b13bdcd57" title="Perform a task switch">switch_task</a>(); } <span class="comment">// A task switch is not required - restore the stack pointer so that we return to the task</span> SP = (uint16_t) <a class="code" href="group__task.html#g4743b3673a8794b8e7bd0b6c91a63cd5" title="The current task.">current_task</a>-><a class="code" href="structtask__t.html#61dcd38718f0b8754f93c77644e9bce0" title="The stack pointer as at the last time this task was suspended">sp</a>; <span class="comment">// We are about to return to the task - reset system.interrupted_task</span> <a class="code" href="task_8c.html#8e20fafa56301aad5b476cbd2c9e5b48" title="The system stack, and a flag indicating whether the CPU is currently processing an...">system</a>.<a class="code" href="structsystem__struct.html#0ffafae88663b0d12161b161d2b87ea1" title="non-zero if we are executing an ISR. Also, bit 1 is set if a task switch is required...">interrupted_task</a> = 0; } <span class="comment">// Return to whatever we were doing before this ISR was called</span> <a class="code" href="task_8h.html#7e11bac5a51572c5db72502c47cf90d3" title="Restore the CPU context from the stack, possibly re-enabling interrupts">restore_cpu_context</a>(); __asm__ <span class="keyword">volatile</span> (<span class="stringliteral">"ret"</span> ::); }</pre></div> </div></div><p><hr><p align="center"><font size="-1">YAVRTOS and YAVRTOS documentation Copyright © 2007-2008 Chris O'Byrne. Email - chris <at> obyrne <dot> com</font></p></body></html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -