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