]> begriffs open source - freertos/blob - Source/portable/GCC/AVR32_UC3/portmacro.h
Small mods, and update file headers.
[freertos] / Source / portable / GCC / AVR32_UC3 / portmacro.h
1 /*This file has been prepared for Doxygen automatic documentation generation.*/\r
2 /*! \file *********************************************************************\r
3  *\r
4  * \brief FreeRTOS port source for AVR32 UC3.\r
5  *\r
6  * - Compiler:           GNU GCC for AVR32\r
7  * - Supported devices:  All AVR32 devices can be used.\r
8  * - AppNote:\r
9  *\r
10  * \author               Atmel Corporation: http://www.atmel.com \n\r
11  *                       Support and FAQ: http://support.atmel.no/\r
12  *\r
13  *****************************************************************************/\r
14 \r
15 /*\r
16         FreeRTOS.org V4.8.0 - Copyright (C) 2003-2008 Richard Barry.\r
17 \r
18         This file is part of the FreeRTOS.org distribution.\r
19 \r
20         FreeRTOS.org is free software; you can redistribute it and/or modify\r
21         it under the terms of the GNU General Public License as published by\r
22         the Free Software Foundation; either version 2 of the License, or\r
23         (at your option) any later version.\r
24 \r
25         FreeRTOS.org is distributed in the hope that it will be useful,\r
26         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
27         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
28         GNU General Public License for more details.\r
29 \r
30         You should have received a copy of the GNU General Public License\r
31         along with FreeRTOS.org; if not, write to the Free Software\r
32         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
33 \r
34         A special exception to the GPL can be applied should you wish to distribute\r
35         a combined work that includes FreeRTOS.org, without being obliged to provide\r
36         the source code for any proprietary components.  See the licensing section\r
37         of http://www.FreeRTOS.org for full details of how and when the exception\r
38         can be applied.\r
39 \r
40     ***************************************************************************\r
41     ***************************************************************************\r
42     *                                                                         *\r
43     * SAVE TIME AND MONEY!  We can port FreeRTOS.org to your own hardware,    *\r
44     * and even write all or part of your application on your behalf.          *\r
45     * See http://www.OpenRTOS.com for details of the services we provide to   *\r
46     * expedite your project.                                                  *\r
47     *                                                                         *\r
48     ***************************************************************************\r
49     ***************************************************************************\r
50 \r
51         Please ensure to read the configuration and relevant port sections of the\r
52         online documentation.\r
53 \r
54         http://www.FreeRTOS.org - Documentation, latest information, license and \r
55         contact details.\r
56 \r
57         http://www.SafeRTOS.com - A version that is certified for use in safety \r
58         critical systems.\r
59 \r
60         http://www.OpenRTOS.com - Commercial support, development, porting, \r
61         licensing and training services.\r
62 */\r
63 \r
64 \r
65 #ifndef PORTMACRO_H\r
66 #define PORTMACRO_H\r
67 \r
68 /*-----------------------------------------------------------\r
69  * Port specific definitions.\r
70  *\r
71  * The settings in this file configure FreeRTOS correctly for the\r
72  * given hardware and compiler.\r
73  *\r
74  * These settings should not be altered.\r
75  *-----------------------------------------------------------\r
76  */\r
77 #include <avr32/io.h>\r
78 #include "intc.h"\r
79 #include "compiler.h"\r
80 \r
81 #ifdef __cplusplus\r
82 extern "C" {\r
83 #endif\r
84 \r
85 \r
86 /* Type definitions. */\r
87 #define portCHAR        char\r
88 #define portFLOAT       float\r
89 #define portDOUBLE      double\r
90 #define portLONG        long\r
91 #define portSHORT       short\r
92 #define portSTACK_TYPE  unsigned portLONG\r
93 #define portBASE_TYPE   portLONG\r
94 \r
95 #define TASK_DELAY_MS(x)   ( (x)        /portTICK_RATE_MS )\r
96 #define TASK_DELAY_S(x)    ( (x)*1000   /portTICK_RATE_MS )\r
97 #define TASK_DELAY_MIN(x)  ( (x)*60*1000/portTICK_RATE_MS )\r
98 \r
99 #define configTICK_TC_IRQ             ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)\r
100 \r
101 #if( configUSE_16_BIT_TICKS == 1 )\r
102         typedef unsigned portSHORT portTickType;\r
103         #define portMAX_DELAY ( portTickType ) 0xffff\r
104 #else\r
105         typedef unsigned portLONG portTickType;\r
106         #define portMAX_DELAY ( portTickType ) 0xffffffff\r
107 #endif\r
108 /*-----------------------------------------------------------*/\r
109 \r
110 /* Architecture specifics. */\r
111 #define portSTACK_GROWTH      ( -1 )\r
112 #define portTICK_RATE_MS      ( ( portTickType ) 1000 / configTICK_RATE_HZ )\r
113 #define portBYTE_ALIGNMENT    4\r
114 #define portNOP()             {__asm__ __volatile__ ("nop");}\r
115 /*-----------------------------------------------------------*/\r
116 \r
117 \r
118 /*-----------------------------------------------------------*/\r
119 \r
120 /* INTC-specific. */\r
121 #define DISABLE_ALL_EXCEPTIONS()    Disable_global_exception()\r
122 #define ENABLE_ALL_EXCEPTIONS()     Enable_global_exception()\r
123 \r
124 #define DISABLE_ALL_INTERRUPTS()    Disable_global_interrupt()\r
125 #define ENABLE_ALL_INTERRUPTS()     Enable_global_interrupt()\r
126 \r
127 #define DISABLE_INT_LEVEL(int_lev)  Disable_interrupt_level(int_lev)\r
128 #define ENABLE_INT_LEVEL(int_lev)   Enable_interrupt_level(int_lev)\r
129 \r
130 \r
131 /*\r
132  * Debug trace.\r
133  * Activated if and only if configDBG is nonzero.\r
134  * Prints a formatted string to stdout.\r
135  * The current source file name and line number are output with a colon before\r
136  * the formatted string.\r
137  * A carriage return and a linefeed are appended to the output.\r
138  * stdout is redirected to the USART configured by configDBG_USART.\r
139  * The parameters are the same as for the standard printf function.\r
140  * There is no return value.\r
141  * SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,\r
142  * which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.\r
143  */\r
144 #if configDBG\r
145 #define portDBG_TRACE(...) \\r
146 {\\r
147   fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout);\\r
148   printf(__VA_ARGS__);\\r
149   fputs("\r\n", stdout);\\r
150 }\r
151 #else\r
152 #define portDBG_TRACE(...)\r
153 #endif\r
154 \r
155 \r
156 /* Critical section management. */\r
157 #define portDISABLE_INTERRUPTS()  DISABLE_ALL_INTERRUPTS()\r
158 #define portENABLE_INTERRUPTS()   ENABLE_ALL_INTERRUPTS()\r
159 \r
160 \r
161 extern void vPortEnterCritical( void );\r
162 extern void vPortExitCritical( void );\r
163 \r
164 #define portENTER_CRITICAL()      vPortEnterCritical();\r
165 #define portEXIT_CRITICAL()       vPortExitCritical();\r
166 \r
167 \r
168 /* Added as there is no such function in FreeRTOS. */\r
169 extern void *pvPortRealloc( void *pv, size_t xSize );\r
170 /*-----------------------------------------------------------*/\r
171 \r
172 \r
173 /*=============================================================================================*/\r
174 \r
175 /*\r
176  * Restore Context for cases other than INTi.\r
177  */\r
178 #define portRESTORE_CONTEXT()                                                                                                                   \\r
179 {                                                                                                                                                                               \\r
180   extern volatile unsigned portLONG ulCriticalNesting;                                                                  \\r
181   extern volatile void *volatile pxCurrentTCB;                                                                                  \\r
182                                                                                                                                                                                 \\r
183   __asm__ __volatile__ (                                                                                                                                \\r
184     /* Set SP to point to new stack */                                                                                                  \\r
185     "mov     r8, LO(%[pxCurrentTCB])                                                                                                    \n\t"\\r
186     "orh     r8, HI(%[pxCurrentTCB])                                                                                                    \n\t"\\r
187     "ld.w    r0, r8[0]                                                                                                                                  \n\t"\\r
188     "ld.w    sp, r0[0]                                                                                                                                  \n\t"\\r
189                                                                                                                                                                                 \\r
190     /* Restore ulCriticalNesting variable */                                                                                    \\r
191     "ld.w    r0, sp++                                                                                                                                   \n\t"\\r
192     "mov     r8, LO(%[ulCriticalNesting])                                                                                               \n\t"\\r
193     "orh     r8, HI(%[ulCriticalNesting])                                                                                               \n\t"\\r
194     "st.w    r8[0], r0                                                                                                                                  \n\t"\\r
195                                                                                                                                                                                 \\r
196     /* Restore R0..R7 */                                                                                                                                \\r
197     "ldm     sp++, r0-r7                                                                                                                                \n\t"\\r
198     /* R0-R7 should not be used below this line */                                                                              \\r
199     /* Skip PC and SR (will do it at the end) */                                                                                \\r
200     "sub     sp, -2*4                                                                                                                                   \n\t"\\r
201     /* Restore R8..R12 and LR */                                                                                                                \\r
202     "ldm     sp++, r8-r12, lr                                                                                                                   \n\t"\\r
203     /* Restore SR */                                                                                                                                    \\r
204     "ld.w    r0, sp[-8*4]\n\t" /* R0 is modified, is restored later. */                                 \\r
205     "mtsr    %[SR], r0                                                                                                                                  \n\t"\\r
206     /* Restore r0 */                                                                                                                                    \\r
207     "ld.w    r0, sp[-9*4]                                                                                                                               \n\t"\\r
208     /* Restore PC */                                                                                                                                    \\r
209     "ld.w    pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */               \\r
210     :                                                                                                                                                                   \\r
211     : [ulCriticalNesting] "i" (&ulCriticalNesting),                                                                             \\r
212       [pxCurrentTCB] "i" (&pxCurrentTCB),                                                                                               \\r
213       [SR] "i" (AVR32_SR)                                                                                                                               \\r
214   );                                                                                                                                                                    \\r
215 }\r
216 \r
217 \r
218 /*\r
219  * portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.\r
220  * portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.\r
221  *\r
222  * Had to make different versions because registers saved on the system stack\r
223  * are not the same between INT0..3 exceptions and the scall exception.\r
224  */\r
225 \r
226 // Task context stack layout:\r
227   // R8  (*)\r
228   // R9  (*)\r
229   // R10 (*)\r
230   // R11 (*)\r
231   // R12 (*)\r
232   // R14/LR (*)\r
233   // R15/PC (*)\r
234   // SR (*)\r
235   // R0\r
236   // R1\r
237   // R2\r
238   // R3\r
239   // R4\r
240   // R5\r
241   // R6\r
242   // R7\r
243   // ulCriticalNesting\r
244 // (*) automatically done for INT0..INT3, but not for SCALL\r
245 \r
246 /*\r
247  * The ISR used for the scheduler tick depends on whether the cooperative or\r
248  * the preemptive scheduler is being used.\r
249  */\r
250 #if configUSE_PREEMPTION == 0\r
251 \r
252 /*\r
253  * portSAVE_CONTEXT_OS_INT() for OS Tick exception.\r
254  */\r
255 #define portSAVE_CONTEXT_OS_INT()                                                                                                               \\r
256 {                                                                                                                                                                               \\r
257   /* Save R0..R7 */                                                                                                                                             \\r
258   __asm__ __volatile__ ("stm     --sp, r0-r7");                                                                                 \\r
259                                                                                                                                                                                 \\r
260   /* With the cooperative scheduler, as there is no context switch by interrupt, */             \\r
261   /* there is also no context save. */                                                                                                  \\r
262 }\r
263 \r
264 /*\r
265  * portRESTORE_CONTEXT_OS_INT() for Tick exception.\r
266  */\r
267 #define portRESTORE_CONTEXT_OS_INT()                                                                                                    \\r
268 {                                                                                                                                                                               \\r
269   __asm__ __volatile__ (                                                                                                                                \\r
270     /* Restore R0..R7 */                                                                                                                                \\r
271     "ldm     sp++, r0-r7\n\t"                                                                                                                   \\r
272                                                                                                                                                                                 \\r
273     /* With the cooperative scheduler, as there is no context switch by interrupt, */   \\r
274     /* there is also no context restore. */                                                                                             \\r
275     "rete"                                                                                                                                                              \\r
276   );                                                                                                                                                                    \\r
277 }\r
278 \r
279 #else\r
280 \r
281 /*\r
282  * portSAVE_CONTEXT_OS_INT() for OS Tick exception.\r
283  */\r
284 #define portSAVE_CONTEXT_OS_INT()                                                                                                                                       \\r
285 {                                                                                                                                                                                                       \\r
286   extern volatile unsigned portLONG ulCriticalNesting;                                                                                          \\r
287   extern volatile void *volatile pxCurrentTCB;                                                                                                          \\r
288                                                                                                                                                                                                         \\r
289   /* When we come here */                                                                                                                                                       \\r
290   /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */                                        \\r
291                                                                                                                                                                                                         \\r
292   __asm__ __volatile__ (                                                                                                                                                        \\r
293     /* Save R0..R7 */                                                                                                                                                           \\r
294     "stm     --sp, r0-r7                                                                                                                                                        \n\t"\\r
295                                                                                                                                                                                                         \\r
296     /* Save ulCriticalNesting variable  - R0 is overwritten */                                                                          \\r
297     "mov     r8, LO(%[ulCriticalNesting])\n\t"                                                                                                          \\r
298     "orh     r8, HI(%[ulCriticalNesting])\n\t"                                                                                                          \\r
299     "ld.w    r0, r8[0]                                                                                                                                                          \n\t"\\r
300     "st.w    --sp, r0                                                                                                                                                           \n\t"\\r
301                                                                                                                                                                                                         \\r
302     /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */        \\r
303     /* interrupt handler (which was of a higher priority level but decided to lower its priority */     \\r
304     /* level and allow other lower interrupt level to occur). */                                                                        \\r
305     /* In this case we don't want to do a task switch because we don't know what the stack */           \\r
306     /* currently looks like (we don't know what the interrupted interrupt handler was doing). */        \\r
307     /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */           \\r
308     /* will just be restoring the interrupt handler, no way!!! */                                                                       \\r
309     /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */                                      \\r
310     "ld.w    r0, sp[9*4]\n\t" /* Read SR in stack */                                                                                            \\r
311     "bfextu  r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */                                                                      \\r
312     "cp.w    r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */                                         \\r
313     "brhi    LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]                                                                                                        \n\t"\\r
314                                                                                                                                                                                                         \\r
315     /* Store SP in the first member of the structure pointed to by pxCurrentTCB */                                      \\r
316     /* NOTE: we don't enter a critical section here because all interrupt handlers */                           \\r
317     /* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */                                                        \\r
318     /* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */                        \\r
319     /* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */            \\r
320     "mov     r8, LO(%[pxCurrentTCB])\n\t"                                                                                                                       \\r
321     "orh     r8, HI(%[pxCurrentTCB])\n\t"                                                                                                                       \\r
322     "ld.w    r0, r8[0]\n\t"                                                                                                                                                     \\r
323     "st.w    r0[0], sp\n"                                                                                                                                                       \\r
324                                                                                                                                                                                                         \\r
325     "LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:"                                                                                                                      \\r
326     :                                                                                                                                                                                           \\r
327     : [ulCriticalNesting] "i" (&ulCriticalNesting),                                                                                                     \\r
328       [pxCurrentTCB] "i" (&pxCurrentTCB),                                                                                                                       \\r
329       [LINE] "i" (__LINE__)                                                                                                                                                     \\r
330   );                                                                                                                                                                                            \\r
331 }\r
332 \r
333 /*\r
334  * portRESTORE_CONTEXT_OS_INT() for Tick exception.\r
335  */\r
336 #define portRESTORE_CONTEXT_OS_INT()                                                                                                                            \\r
337 {                                                                                                                                                                                                       \\r
338   extern volatile unsigned portLONG ulCriticalNesting;                                                                                          \\r
339   extern volatile void *volatile pxCurrentTCB;                                                                                                          \\r
340                                                                                                                                                                                                         \\r
341   /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */          \\r
342   /* interrupt handler (which was of a higher priority level but decided to lower its priority */       \\r
343   /* level and allow other lower interrupt level to occur). */                                                                          \\r
344   /* In this case we don't want to do a task switch because we don't know what the stack */                     \\r
345   /* currently looks like (we don't know what the interrupted interrupt handler was doing). */          \\r
346   /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */                     \\r
347   /* will just be restoring the interrupt handler, no way!!! */                                                                         \\r
348   __asm__ __volatile__ (                                                                                                                                                        \\r
349     "ld.w    r0, sp[9*4]\n\t" /* Read SR in stack */                                                                                            \\r
350     "bfextu  r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */                                                                      \\r
351     "cp.w    r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */                                         \\r
352     "brhi    LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]"                                                                                            \\r
353     :                                                                                                                                                                                           \\r
354     : [LINE] "i" (__LINE__)                                                                                                                                                     \\r
355   );                                                                                                                                                                                            \\r
356                                                                                                                                                                                                         \\r
357   /* Else */                                                                                                                                                                            \\r
358   /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */            \\r
359   /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\\r
360   portENTER_CRITICAL();                                                                                                                                                         \\r
361   vTaskSwitchContext();                                                                                                                                                         \\r
362   portEXIT_CRITICAL();                                                                                                                                                          \\r
363                                                                                                                                                                                                         \\r
364   /* Restore all registers */                                                                                                                                           \\r
365                                                                                                                                                                                                         \\r
366   __asm__ __volatile__ (                                                                                                                                                        \\r
367     /* Set SP to point to new stack */                                                                                                                          \\r
368     "mov     r8, LO(%[pxCurrentTCB])                                                                                                                            \n\t"\\r
369     "orh     r8, HI(%[pxCurrentTCB])                                                                                                                            \n\t"\\r
370     "ld.w    r0, r8[0]                                                                                                                                                          \n\t"\\r
371     "ld.w    sp, r0[0]                                                                                                                                                          \n"\\r
372                                                                                                                                                                                                         \\r
373     "LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]:                                                                                                            \n\t"\\r
374                                                                                                                                                                                                         \\r
375     /* Restore ulCriticalNesting variable */                                                                                                            \\r
376     "ld.w    r0, sp++                                                                                                                                                           \n\t"                                                                                                                                                   \\r
377     "mov     r8, LO(%[ulCriticalNesting])                                                                                                                       \n\t"\\r
378     "orh     r8, HI(%[ulCriticalNesting])                                                                                                                       \n\t"\\r
379     "st.w    r8[0], r0                                                                                                                                                          \n\t"\\r
380                                                                                                                                                                                                         \\r
381     /* Restore R0..R7 */                                                                                                                                                        \\r
382     "ldm     sp++, r0-r7                                                                                                                                                        \n\t"\\r
383                                                                                                                                                                                                         \\r
384     /* Now, the stack should be R8..R12, LR, PC and SR */                                                                                       \\r
385     "rete"                                                                                                                                                                                      \\r
386     :                                                                                                                                                                                           \\r
387     : [ulCriticalNesting] "i" (&ulCriticalNesting),                                                                                                     \\r
388       [pxCurrentTCB] "i" (&pxCurrentTCB),                                                                                                                       \\r
389       [LINE] "i" (__LINE__)                                                                                                                                                     \\r
390   );                                                                                                                                                                                            \\r
391 }\r
392 \r
393 #endif\r
394 \r
395 \r
396 /*\r
397  * portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.\r
398  *\r
399  * NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.\r
400  *\r
401  */\r
402 #define portSAVE_CONTEXT_SCALL()                                                                                                                        \\r
403 {                                                                                                                                                                                       \\r
404   extern volatile unsigned portLONG ulCriticalNesting;                                                                          \\r
405   extern volatile void *volatile pxCurrentTCB;                                                                                          \\r
406                                                                                                                                                                                         \\r
407   /* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */         \\r
408   /* If SR[M2:M0] == 001 */                                                                                                                                     \\r
409   /*    PC and SR are on the stack.  */                                                                                                         \\r
410   /* Else (other modes) */                                                                                                                                      \\r
411   /*    Nothing on the stack. */                                                                                                                        \\r
412                                                                                                                                                                                         \\r
413   /* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */           \\r
414   /* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */          \\r
415   /* in an interrupt|exception handler. */                                                                                                      \\r
416                                                                                                                                                                                         \\r
417   __asm__ __volatile__ (                                                                                                                                        \\r
418     /* in order to save R0-R7 */                                                                                                                        \\r
419     "sub     sp, 6*4                                                                                                                                            \n\t"\\r
420     /* Save R0..R7 */                                                                                                                                           \\r
421     "stm     --sp, r0-r7                                                                                                                                        \n\t"\\r
422                                                                                                                                                                                         \\r
423     /* in order to save R8-R12 and LR */                                                                                                        \\r
424     /* do not use SP if interrupts occurs, SP must be left at bottom of stack */                        \\r
425     "sub     r7, sp,-16*4                                                                                                                                       \n\t"\\r
426     /* Copy PC and SR in other places in the stack. */                                                                          \\r
427     "ld.w    r0, r7[-2*4]                                                                                                                                       \n\t" /* Read SR */\\r
428     "st.w    r7[-8*4], r0                                                                                                                                       \n\t" /* Copy SR */\\r
429     "ld.w    r0, r7[-1*4]                                                                                                                                       \n\t" /* Read PC */\\r
430     "st.w    r7[-7*4], r0                                                                                                                                       \n\t" /* Copy PC */\\r
431                                                                                                                                                                                         \\r
432     /* Save R8..R12 and LR on the stack. */                                                                                                     \\r
433     "stm     --r7, r8-r12, lr                                                                                                                           \n\t"\\r
434                                                                                                                                                                                         \\r
435     /* Arriving here we have the following stack organizations: */                                                      \\r
436     /* R8..R12, LR, PC, SR, R0..R7. */                                                                                                          \\r
437                                                                                                                                                                                         \\r
438     /* Now we can finalize the save. */                                                                                                         \\r
439                                                                                                                                                                                         \\r
440     /* Save ulCriticalNesting variable  - R0 is overwritten */                                                          \\r
441     "mov     r8, LO(%[ulCriticalNesting])                                                                                                       \n\t"\\r
442     "orh     r8, HI(%[ulCriticalNesting])                                                                                                       \n\t"\\r
443     "ld.w    r0, r8[0]                                                                                                                                          \n\t"\\r
444     "st.w    --sp, r0"                                                                                                                                          \\r
445     :                                                                                                                                                                           \\r
446     : [ulCriticalNesting] "i" (&ulCriticalNesting)                                                                                      \\r
447   );                                                                                                                                                                            \\r
448                                                                                                                                                                                         \\r
449   /* Disable the its which may cause a context switch (i.e. cause a change of */                        \\r
450   /* pxCurrentTCB). */                                                                                                                                          \\r
451   /* Basically, all accesses to the pxCurrentTCB structure should be put in a */                        \\r
452   /* critical section because it is a global structure. */                                                                      \\r
453   portENTER_CRITICAL();                                                                                                                                         \\r
454                                                                                                                                                                                         \\r
455   /* Store SP in the first member of the structure pointed to by pxCurrentTCB */                        \\r
456   __asm__ __volatile__ (                                                                                                                                        \\r
457     "mov     r8, LO(%[pxCurrentTCB])                                                                                                            \n\t"\\r
458     "orh     r8, HI(%[pxCurrentTCB])                                                                                                            \n\t"\\r
459     "ld.w    r0, r8[0]                                                                                                                                          \n\t"\\r
460     "st.w    r0[0], sp"                                                                                                                                         \\r
461     :                                                                                                                                                                           \\r
462     : [pxCurrentTCB] "i" (&pxCurrentTCB)                                                                                                        \\r
463   );                                                                                                                                                                            \\r
464 }\r
465 \r
466 /*\r
467  * portRESTORE_CONTEXT() for SupervisorCALL exception.\r
468  */\r
469 #define portRESTORE_CONTEXT_SCALL()                                                                                                                     \\r
470 {                                                                                                                                                                                       \\r
471   extern volatile unsigned portLONG ulCriticalNesting;                                                                          \\r
472   extern volatile void *volatile pxCurrentTCB;                                                                                          \\r
473                                                                                                                                                                                         \\r
474   /* Restore all registers */                                                                                                                           \\r
475                                                                                                                                                                                         \\r
476   /* Set SP to point to new stack */                                                                                                            \\r
477   __asm__ __volatile__ (                                                                                                                                        \\r
478     "mov     r8, LO(%[pxCurrentTCB])                                                                                                            \n\t"\\r
479     "orh     r8, HI(%[pxCurrentTCB])                                                                                                            \n\t"\\r
480     "ld.w    r0, r8[0]                                                                                                                                          \n\t"\\r
481     "ld.w    sp, r0[0]"                                                                                                                                         \\r
482     :                                                                                                                                                                           \\r
483     : [pxCurrentTCB] "i" (&pxCurrentTCB)                                                                                                        \\r
484   );                                                                                                                                                                            \\r
485                                                                                                                                                                                         \\r
486   /* Leave pxCurrentTCB variable access critical section */                                                                     \\r
487   portEXIT_CRITICAL();                                                                                                                                          \\r
488                                                                                                                                                                                         \\r
489   __asm__ __volatile__ (                                                                                                                                        \\r
490     /* Restore ulCriticalNesting variable */                                                                                            \\r
491     "ld.w    r0, sp++                                                                                                                                           \n\t"\\r
492     "mov     r8, LO(%[ulCriticalNesting])                                                                                                       \n\t"\\r
493     "orh     r8, HI(%[ulCriticalNesting])                                                                                                       \n\t"\\r
494     "st.w    r8[0], r0                                                                                                                                          \n\t"\\r
495                                                                                                                                                                                         \\r
496     /* skip PC and SR */                                                                                                                                        \\r
497     /* do not use SP if interrupts occurs, SP must be left at bottom of stack */                        \\r
498     "sub     r7, sp, -10*4                                                                                                                                      \n\t"\\r
499     /* Restore r8-r12 and LR */                                                                                                                         \\r
500     "ldm     r7++, r8-r12, lr                                                                                                                           \n\t"\\r
501                                                                                                                                                                                         \\r
502     /* RETS will take care of the extra PC and SR restore. */                                                           \\r
503     /* So, we have to prepare the stack for this. */                                                                            \\r
504     "ld.w    r0, r7[-8*4]                                                                                                                                       \n\t" /* Read SR */\\r
505     "st.w    r7[-2*4], r0                                                                                                                                       \n\t" /* Copy SR */\\r
506     "ld.w    r0, r7[-7*4]                                                                                                                                       \n\t" /* Read PC */\\r
507     "st.w    r7[-1*4], r0                                                                                                                                       \n\t" /* Copy PC */\\r
508                                                                                                                                                                                         \\r
509     /* Restore R0..R7 */                                                                                                                                        \\r
510     "ldm     sp++, r0-r7                                                                                                                                        \n\t"\\r
511                                                                                                                                                                                         \\r
512     "sub     sp, -6*4                                                                                                                                           \n\t"\\r
513                                                                                                                                                                                         \\r
514     "rets"                                                                                                                                                                      \\r
515     :                                                                                                                                                                           \\r
516     : [ulCriticalNesting] "i" (&ulCriticalNesting)                                                                                      \\r
517   );                                                                                                                                                                            \\r
518 }\r
519 \r
520 \r
521 /*\r
522  * The ISR used depends on whether the cooperative or\r
523  * the preemptive scheduler is being used.\r
524  */\r
525 #if configUSE_PREEMPTION == 0\r
526 \r
527 /*\r
528  * ISR entry and exit macros.  These are only required if a task switch\r
529  * is required from the ISR.\r
530  */\r
531 #define portENTER_SWITCHING_ISR()                                                                                                                       \\r
532 {                                                                                                                                                                                       \\r
533   /* Save R0..R7 */                                                                                                                                                     \\r
534   __asm__ __volatile__ ("stm     --sp, r0-r7");                                                                                         \\r
535                                                                                                                                                                                         \\r
536   /* With the cooperative scheduler, as there is no context switch by interrupt, */                     \\r
537   /* there is also no context save. */                                                                                                          \\r
538 }\r
539 \r
540 /*\r
541  * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1\r
542  */\r
543 #define portEXIT_SWITCHING_ISR()                                                                                                                        \\r
544 {                                                                                                                                                                                       \\r
545   __asm__ __volatile__ (                                                                                                                                        \\r
546     /* Restore R0..R7 */                                                                                                                                        \\r
547     "ldm     sp++, r0-r7                                                                                                                                        \n\t"\\r
548                                                                                                                                                                                         \\r
549     /* With the cooperative scheduler, as there is no context switch by interrupt, */           \\r
550     /* there is also no context restore. */                                                                                                     \\r
551     "rete"                                                                                                                                                                      \\r
552   );                                                                                                                                                                            \\r
553 }\r
554 \r
555 #else\r
556 \r
557 /*\r
558  * ISR entry and exit macros.  These are only required if a task switch\r
559  * is required from the ISR.\r
560  */\r
561 #define portENTER_SWITCHING_ISR()                                                                                                                       \\r
562 {                                                                                                                                                                                       \\r
563   extern volatile unsigned portLONG ulCriticalNesting;                                                                          \\r
564   extern volatile void *volatile pxCurrentTCB;                                                                                          \\r
565                                                                                                                                                                                         \\r
566   /* When we come here */                                                                                                                                       \\r
567   /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */                        \\r
568                                                                                                                                                                                         \\r
569   __asm__ __volatile__ (                                                                                                                                        \\r
570     /* Save R0..R7 */                                                                                                                                           \\r
571     "stm     --sp, r0-r7                                                                                                                                        \n\t"\\r
572                                                                                                                                                                                         \\r
573     /* Save ulCriticalNesting variable  - R0 is overwritten */                                                          \\r
574     "mov     r8, LO(%[ulCriticalNesting])                                                                                                       \n\t"\\r
575     "orh     r8, HI(%[ulCriticalNesting])                                                                                                       \n\t"\\r
576     "ld.w    r0, r8[0]                                                                                                                                          \n\t"\\r
577     "st.w    --sp, r0                                                                                                                                           \n\t"\\r
578                                                                                                                                                                                                         \\r
579     /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */        \\r
580     /* interrupt handler (which was of a higher priority level but decided to lower its priority */     \\r
581     /* level and allow other lower interrupt level to occur). */                                                                        \\r
582     /* In this case we don't want to do a task switch because we don't know what the stack */           \\r
583     /* currently looks like (we don't know what the interrupted interrupt handler was doing). */        \\r
584     /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */           \\r
585     /* will just be restoring the interrupt handler, no way!!! */                                                                       \\r
586     /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */                                      \\r
587     "ld.w    r0, sp[9*4]                                                                                                                                        \n\t" /* Read SR in stack */\\r
588     "bfextu  r0, r0, 22, 3                                                                                                                                      \n\t" /* Extract the mode bits to R0. */\\r
589     "cp.w    r0, 1                                                                                                                                                      \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
590     "brhi    LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]                                                                                        \n\t"\\r
591                                                                                                                                                                                         \\r
592     /* Store SP in the first member of the structure pointed to by pxCurrentTCB */                      \\r
593     "mov     r8, LO(%[pxCurrentTCB])                                                                                                            \n\t"\\r
594     "orh     r8, HI(%[pxCurrentTCB])                                                                                                            \n\t"\\r
595     "ld.w    r0, r8[0]                                                                                                                                          \n\t"\\r
596     "st.w    r0[0], sp                                                                                                                                          \n"\\r
597                                                                                                                                                                                         \\r
598     "LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:"                                                                                                      \\r
599     :                                                                                                                                                                           \\r
600     : [ulCriticalNesting] "i" (&ulCriticalNesting),                                                                                     \\r
601       [pxCurrentTCB] "i" (&pxCurrentTCB),                                                                                                       \\r
602       [LINE] "i" (__LINE__)                                                                                                                                     \\r
603   );                                                                                                                                                                            \\r
604 }\r
605 \r
606 /*\r
607  * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1\r
608  */\r
609 #define portEXIT_SWITCHING_ISR()                                                                                                                        \\r
610 {                                                                                                                                                                                       \\r
611   extern volatile unsigned portLONG ulCriticalNesting;                                                                          \\r
612   extern volatile void *volatile pxCurrentTCB;                                                                                          \\r
613                                                                                                                                                                                         \\r
614   __asm__ __volatile__ (                                                                                                                                        \\r
615     /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */                \\r
616     /* interrupt handler (which was of a higher priority level but decided to lower its priority */             \\r
617     /* level and allow other lower interrupt level to occur). */                                                                                \\r
618     /* In this case it's of no use to switch context and restore a new SP because we purposedly */              \\r
619     /* did not previously save SP in its TCB. */                                                                                                                                                                \\r
620     "ld.w    r0, sp[9*4]                                                                                                                                        \n\t" /* Read SR in stack */\\r
621     "bfextu  r0, r0, 22, 3                                                                                                                                      \n\t" /* Extract the mode bits to R0. */\\r
622     "cp.w    r0, 1                                                                                                                                                      \n\t" /* Compare the mode bits with supervisor mode(b'001) */\\r
623     "brhi    LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]                                                                                     \n\t"\\r
624                                                                                                                                                                                         \\r
625     /* If a switch is required then we just need to call */                                                                     \\r
626     /* vTaskSwitchContext() as the context has already been */                                                          \\r
627     /* saved. */                                                                                                                                                        \\r
628     "cp.w    r12, 1                                                                                                                                                     \n\t" /* Check if Switch context is required. */\\r
629     "brne    LABEL_ISR_RESTORE_CONTEXT_%[LINE]"                                                                                         \\r
630     :                                                                                                                                                                           \\r
631     : [LINE] "i" (__LINE__)                                                                                                                                     \\r
632   );                                                                                                                                                                            \\r
633                                                                                                                                                                                         \\r
634   /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */        \\r
635   portENTER_CRITICAL();                                                                                                                                         \\r
636   vTaskSwitchContext();                                                                                                                                         \\r
637   portEXIT_CRITICAL();                                                                                                                                          \\r
638                                                                                                                                                                                         \\r
639   __asm__ __volatile__ (                                                                                                                                        \\r
640     "LABEL_ISR_RESTORE_CONTEXT_%[LINE]:                                                                                                         \n\t"\\r
641     /* Restore the context of which ever task is now the highest */                                                     \\r
642     /* priority that is ready to run. */                                                                                                        \\r
643                                                                                                                                                                                         \\r
644     /* Restore all registers */                                                                                                                         \\r
645                                                                                                                                                                                         \\r
646     /* Set SP to point to new stack */                                                                                                          \\r
647     "mov     r8, LO(%[pxCurrentTCB])                                                                                                            \n\t"\\r
648     "orh     r8, HI(%[pxCurrentTCB])                                                                                                            \n\t"\\r
649     "ld.w    r0, r8[0]                                                                                                                                          \n\t"\\r
650     "ld.w    sp, r0[0]                                                                                                                                          \n"\\r
651                                                                                                                                                                                         \\r
652     "LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]:                                                                                            \n\t"\\r
653                                                                                                                                                                                         \\r
654     /* Restore ulCriticalNesting variable */                                                                                            \\r
655     "ld.w    r0, sp++                                                                                                                                           \n\t"\\r
656     "mov     r8, LO(%[ulCriticalNesting])                                                                                                       \n\t"\\r
657     "orh     r8, HI(%[ulCriticalNesting])                                                                                                       \n\t"\\r
658     "st.w    r8[0], r0                                                                                                                                          \n\t"\\r
659                                                                                                                                                                                         \\r
660     /* Restore R0..R7 */                                                                                                                                        \\r
661     "ldm     sp++, r0-r7                                                                                                                                        \n\t"\\r
662                                                                                                                                                                                         \\r
663     /* Now, the stack should be R8..R12, LR, PC and SR  */                                                                      \\r
664     "rete"                                                                                                                                                                      \\r
665     :                                                                                                                                                                           \\r
666     : [ulCriticalNesting] "i" (&ulCriticalNesting),                                                                                     \\r
667       [pxCurrentTCB] "i" (&pxCurrentTCB),                                                                                                       \\r
668       [LINE] "i" (__LINE__)                                                                                                                                     \\r
669   );                                                                                                                                                                            \\r
670 }\r
671 \r
672 #endif\r
673 \r
674 \r
675 #define portYIELD()                 {__asm__ __volatile__ ("scall");}\r
676 \r
677 /* Task function macros as described on the FreeRTOS.org WEB site. */\r
678 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
679 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )\r
680 \r
681 #ifdef __cplusplus\r
682 }\r
683 #endif\r
684 \r
685 #endif /* PORTMACRO_H */\r