1 /*This file has been prepared for Doxygen automatic documentation generation.*/
2 /*! \file *********************************************************************
4 * \brief FreeRTOS port source for AVR32 UC3.
6 * - Compiler: GNU GCC for AVR32
7 * - Supported devices: All AVR32 devices can be used.
10 * \author Atmel Corporation (Now Microchip):
11 * https://www.microchip.com \n
12 * Support and FAQ: https://www.microchip.com/support/
14 *****************************************************************************/
17 * FreeRTOS SMP Kernel V202110.00
18 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
20 * Permission is hereby granted, free of charge, to any person obtaining a copy of
21 * this software and associated documentation files (the "Software"), to deal in
22 * the Software without restriction, including without limitation the rights to
23 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
24 * the Software, and to permit persons to whom the Software is furnished to do so,
25 * subject to the following conditions:
27 * The above copyright notice and this permission notice shall be included in all
28 * copies or substantial portions of the Software.
30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
32 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
33 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
34 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
35 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 * https://www.FreeRTOS.org
38 * https://github.com/FreeRTOS
47 /*-----------------------------------------------------------
48 * Port specific definitions.
50 * The settings in this file configure FreeRTOS correctly for the
51 * given hardware and compiler.
53 * These settings should not be altered.
54 *-----------------------------------------------------------
65 /* Type definitions. */
67 #define portFLOAT float
68 #define portDOUBLE double
70 #define portSHORT short
71 #define portSTACK_TYPE uint32_t
72 #define portBASE_TYPE long
74 typedef portSTACK_TYPE StackType_t;
75 typedef long BaseType_t;
76 typedef unsigned long UBaseType_t;
78 #define TASK_DELAY_MS(x) ( (x) /portTICK_PERIOD_MS )
79 #define TASK_DELAY_S(x) ( (x)*1000 /portTICK_PERIOD_MS )
80 #define TASK_DELAY_MIN(x) ( (x)*60*1000/portTICK_PERIOD_MS )
82 #define configTICK_TC_IRQ ATPASTE2(AVR32_TC_IRQ, configTICK_TC_CHANNEL)
84 #if( configUSE_16_BIT_TICKS == 1 )
85 typedef uint16_t TickType_t;
86 #define portMAX_DELAY ( TickType_t ) 0xffff
88 typedef uint32_t TickType_t;
89 #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
91 /*-----------------------------------------------------------*/
93 /* Architecture specifics. */
94 #define portSTACK_GROWTH ( -1 )
95 #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
96 #define portBYTE_ALIGNMENT 4
97 #define portNOP() {__asm__ __volatile__ ("nop");}
98 /*-----------------------------------------------------------*/
101 /*-----------------------------------------------------------*/
104 #define DISABLE_ALL_EXCEPTIONS() Disable_global_exception()
105 #define ENABLE_ALL_EXCEPTIONS() Enable_global_exception()
107 #define DISABLE_ALL_INTERRUPTS() Disable_global_interrupt()
108 #define ENABLE_ALL_INTERRUPTS() Enable_global_interrupt()
110 #define DISABLE_INT_LEVEL(int_lev) Disable_interrupt_level(int_lev)
111 #define ENABLE_INT_LEVEL(int_lev) Enable_interrupt_level(int_lev)
116 * Activated if and only if configDBG is nonzero.
117 * Prints a formatted string to stdout.
118 * The current source file name and line number are output with a colon before
119 * the formatted string.
120 * A carriage return and a linefeed are appended to the output.
121 * stdout is redirected to the USART configured by configDBG_USART.
122 * The parameters are the same as for the standard printf function.
123 * There is no return value.
124 * SHALL NOT BE CALLED FROM WITHIN AN INTERRUPT as fputs and printf use malloc,
125 * which is interrupt-unsafe with the current __malloc_lock and __malloc_unlock.
128 #define portDBG_TRACE(...) \
130 fputs(__FILE__ ":" ASTRINGZ(__LINE__) ": ", stdout);\
131 printf(__VA_ARGS__);\
132 fputs("\r\n", stdout);\
135 #define portDBG_TRACE(...)
139 /* Critical section management. */
140 #define portDISABLE_INTERRUPTS() DISABLE_ALL_INTERRUPTS()
141 #define portENABLE_INTERRUPTS() ENABLE_ALL_INTERRUPTS()
144 extern void vPortEnterCritical( void );
145 extern void vPortExitCritical( void );
147 #define portENTER_CRITICAL() vPortEnterCritical();
148 #define portEXIT_CRITICAL() vPortExitCritical();
151 /* Added as there is no such function in FreeRTOS. */
152 extern void *pvPortRealloc( void *pv, size_t xSize );
153 /*-----------------------------------------------------------*/
156 /*=============================================================================================*/
159 * Restore Context for cases other than INTi.
161 #define portRESTORE_CONTEXT() \
163 extern volatile uint32_t ulCriticalNesting; \
164 extern volatile void *volatile pxCurrentTCB; \
166 __asm__ __volatile__ ( \
167 /* Set SP to point to new stack */ \
168 "mov r8, LO(%[pxCurrentTCB]) \n\t"\
169 "orh r8, HI(%[pxCurrentTCB]) \n\t"\
170 "ld.w r0, r8[0] \n\t"\
171 "ld.w sp, r0[0] \n\t"\
173 /* Restore ulCriticalNesting variable */ \
174 "ld.w r0, sp++ \n\t"\
175 "mov r8, LO(%[ulCriticalNesting]) \n\t"\
176 "orh r8, HI(%[ulCriticalNesting]) \n\t"\
177 "st.w r8[0], r0 \n\t"\
179 /* Restore R0..R7 */ \
180 "ldm sp++, r0-r7 \n\t"\
181 /* R0-R7 should not be used below this line */ \
182 /* Skip PC and SR (will do it at the end) */ \
184 /* Restore R8..R12 and LR */ \
185 "ldm sp++, r8-r12, lr \n\t"\
187 "ld.w r0, sp[-8*4]\n\t" /* R0 is modified, is restored later. */ \
188 "mtsr %[SR], r0 \n\t"\
190 "ld.w r0, sp[-9*4] \n\t"\
192 "ld.w pc, sp[-7*4]" /* Get PC from stack - PC is the 7th register saved */ \
194 : [ulCriticalNesting] "i" (&ulCriticalNesting), \
195 [pxCurrentTCB] "i" (&pxCurrentTCB), \
196 [SR] "i" (AVR32_SR) \
202 * portSAVE_CONTEXT_INT() and portRESTORE_CONTEXT_INT(): for INT0..3 exceptions.
203 * portSAVE_CONTEXT_SCALL() and portRESTORE_CONTEXT_SCALL(): for the scall exception.
205 * Had to make different versions because registers saved on the system stack
206 * are not the same between INT0..3 exceptions and the scall exception.
209 // Task context stack layout:
227 // (*) automatically done for INT0..INT3, but not for SCALL
230 * The ISR used for the scheduler tick depends on whether the cooperative or
231 * the preemptive scheduler is being used.
233 #if configUSE_PREEMPTION == 0
236 * portSAVE_CONTEXT_OS_INT() for OS Tick exception.
238 #define portSAVE_CONTEXT_OS_INT() \
241 __asm__ __volatile__ ("stm --sp, r0-r7"); \
243 /* With the cooperative scheduler, as there is no context switch by interrupt, */ \
244 /* there is also no context save. */ \
248 * portRESTORE_CONTEXT_OS_INT() for Tick exception.
250 #define portRESTORE_CONTEXT_OS_INT() \
252 __asm__ __volatile__ ( \
253 /* Restore R0..R7 */ \
254 "ldm sp++, r0-r7\n\t" \
256 /* With the cooperative scheduler, as there is no context switch by interrupt, */ \
257 /* there is also no context restore. */ \
265 * portSAVE_CONTEXT_OS_INT() for OS Tick exception.
267 #define portSAVE_CONTEXT_OS_INT() \
269 extern volatile uint32_t ulCriticalNesting; \
270 extern volatile void *volatile pxCurrentTCB; \
272 /* When we come here */ \
273 /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
275 __asm__ __volatile__ ( \
277 "stm --sp, r0-r7 \n\t"\
279 /* Save ulCriticalNesting variable - R0 is overwritten */ \
280 "mov r8, LO(%[ulCriticalNesting])\n\t" \
281 "orh r8, HI(%[ulCriticalNesting])\n\t" \
282 "ld.w r0, r8[0] \n\t"\
283 "st.w --sp, r0 \n\t"\
285 /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
286 /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
287 /* level and allow other lower interrupt level to occur). */ \
288 /* In this case we don't want to do a task switch because we don't know what the stack */ \
289 /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
290 /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
291 /* will just be restoring the interrupt handler, no way!!! */ \
292 /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
293 "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \
294 "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \
295 "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
296 "brhi LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
298 /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
299 /* NOTE: we don't enter a critical section here because all interrupt handlers */ \
300 /* MUST perform a SAVE_CONTEXT/RESTORE_CONTEXT in the same way as */ \
301 /* portSAVE_CONTEXT_OS_INT/port_RESTORE_CONTEXT_OS_INT if they call OS functions. */ \
302 /* => all interrupt handlers must use portENTER_SWITCHING_ISR/portEXIT_SWITCHING_ISR. */ \
303 "mov r8, LO(%[pxCurrentTCB])\n\t" \
304 "orh r8, HI(%[pxCurrentTCB])\n\t" \
305 "ld.w r0, r8[0]\n\t" \
308 "LABEL_INT_SKIP_SAVE_CONTEXT_%[LINE]:" \
310 : [ulCriticalNesting] "i" (&ulCriticalNesting), \
311 [pxCurrentTCB] "i" (&pxCurrentTCB), \
312 [LINE] "i" (__LINE__) \
317 * portRESTORE_CONTEXT_OS_INT() for Tick exception.
319 #define portRESTORE_CONTEXT_OS_INT() \
321 extern volatile uint32_t ulCriticalNesting; \
322 extern volatile void *volatile pxCurrentTCB; \
324 /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
325 /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
326 /* level and allow other lower interrupt level to occur). */ \
327 /* In this case we don't want to do a task switch because we don't know what the stack */ \
328 /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
329 /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
330 /* will just be restoring the interrupt handler, no way!!! */ \
331 __asm__ __volatile__ ( \
332 "ld.w r0, sp[9*4]\n\t" /* Read SR in stack */ \
333 "bfextu r0, r0, 22, 3\n\t" /* Extract the mode bits to R0. */ \
334 "cp.w r0, 1\n\t" /* Compare the mode bits with supervisor mode(b'001) */ \
335 "brhi LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]" \
337 : [LINE] "i" (__LINE__) \
341 /* because it is here safe, always call vTaskSwitchContext() since an OS tick occurred. */ \
342 /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */\
343 portENTER_CRITICAL(); \
344 vTaskSwitchContext(); \
345 portEXIT_CRITICAL(); \
347 /* Restore all registers */ \
349 __asm__ __volatile__ ( \
350 /* Set SP to point to new stack */ \
351 "mov r8, LO(%[pxCurrentTCB]) \n\t"\
352 "orh r8, HI(%[pxCurrentTCB]) \n\t"\
353 "ld.w r0, r8[0] \n\t"\
356 "LABEL_INT_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
358 /* Restore ulCriticalNesting variable */ \
359 "ld.w r0, sp++ \n\t" \
360 "mov r8, LO(%[ulCriticalNesting]) \n\t"\
361 "orh r8, HI(%[ulCriticalNesting]) \n\t"\
362 "st.w r8[0], r0 \n\t"\
364 /* Restore R0..R7 */ \
365 "ldm sp++, r0-r7 \n\t"\
367 /* Now, the stack should be R8..R12, LR, PC and SR */ \
370 : [ulCriticalNesting] "i" (&ulCriticalNesting), \
371 [pxCurrentTCB] "i" (&pxCurrentTCB), \
372 [LINE] "i" (__LINE__) \
380 * portSAVE_CONTEXT_SCALL() for SupervisorCALL exception.
382 * NOTE: taskYIELD()(== SCALL) MUST NOT be called in a mode > supervisor mode.
385 #define portSAVE_CONTEXT_SCALL() \
387 extern volatile uint32_t ulCriticalNesting; \
388 extern volatile void *volatile pxCurrentTCB; \
390 /* Warning: the stack layout after SCALL doesn't match the one after an interrupt. */ \
391 /* If SR[M2:M0] == 001 */ \
392 /* PC and SR are on the stack. */ \
393 /* Else (other modes) */ \
394 /* Nothing on the stack. */ \
396 /* WARNING NOTE: the else case cannot happen as it is strictly forbidden to call */ \
397 /* vTaskDelay() and vTaskDelayUntil() OS functions (that result in a taskYield()) */ \
398 /* in an interrupt|exception handler. */ \
400 __asm__ __volatile__ ( \
401 /* in order to save R0-R7 */ \
404 "stm --sp, r0-r7 \n\t"\
406 /* in order to save R8-R12 and LR */ \
407 /* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
408 "sub r7, sp,-16*4 \n\t"\
409 /* Copy PC and SR in other places in the stack. */ \
410 "ld.w r0, r7[-2*4] \n\t" /* Read SR */\
411 "st.w r7[-8*4], r0 \n\t" /* Copy SR */\
412 "ld.w r0, r7[-1*4] \n\t" /* Read PC */\
413 "st.w r7[-7*4], r0 \n\t" /* Copy PC */\
415 /* Save R8..R12 and LR on the stack. */ \
416 "stm --r7, r8-r12, lr \n\t"\
418 /* Arriving here we have the following stack organizations: */ \
419 /* R8..R12, LR, PC, SR, R0..R7. */ \
421 /* Now we can finalize the save. */ \
423 /* Save ulCriticalNesting variable - R0 is overwritten */ \
424 "mov r8, LO(%[ulCriticalNesting]) \n\t"\
425 "orh r8, HI(%[ulCriticalNesting]) \n\t"\
426 "ld.w r0, r8[0] \n\t"\
429 : [ulCriticalNesting] "i" (&ulCriticalNesting) \
432 /* Disable the its which may cause a context switch (i.e. cause a change of */ \
433 /* pxCurrentTCB). */ \
434 /* Basically, all accesses to the pxCurrentTCB structure should be put in a */ \
435 /* critical section because it is a global structure. */ \
436 portENTER_CRITICAL(); \
438 /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
439 __asm__ __volatile__ ( \
440 "mov r8, LO(%[pxCurrentTCB]) \n\t"\
441 "orh r8, HI(%[pxCurrentTCB]) \n\t"\
442 "ld.w r0, r8[0] \n\t"\
445 : [pxCurrentTCB] "i" (&pxCurrentTCB) \
450 * portRESTORE_CONTEXT() for SupervisorCALL exception.
452 #define portRESTORE_CONTEXT_SCALL() \
454 extern volatile uint32_t ulCriticalNesting; \
455 extern volatile void *volatile pxCurrentTCB; \
457 /* Restore all registers */ \
459 /* Set SP to point to new stack */ \
460 __asm__ __volatile__ ( \
461 "mov r8, LO(%[pxCurrentTCB]) \n\t"\
462 "orh r8, HI(%[pxCurrentTCB]) \n\t"\
463 "ld.w r0, r8[0] \n\t"\
466 : [pxCurrentTCB] "i" (&pxCurrentTCB) \
469 /* Leave pxCurrentTCB variable access critical section */ \
470 portEXIT_CRITICAL(); \
472 __asm__ __volatile__ ( \
473 /* Restore ulCriticalNesting variable */ \
474 "ld.w r0, sp++ \n\t"\
475 "mov r8, LO(%[ulCriticalNesting]) \n\t"\
476 "orh r8, HI(%[ulCriticalNesting]) \n\t"\
477 "st.w r8[0], r0 \n\t"\
479 /* skip PC and SR */ \
480 /* do not use SP if interrupts occurs, SP must be left at bottom of stack */ \
481 "sub r7, sp, -10*4 \n\t"\
482 /* Restore r8-r12 and LR */ \
483 "ldm r7++, r8-r12, lr \n\t"\
485 /* RETS will take care of the extra PC and SR restore. */ \
486 /* So, we have to prepare the stack for this. */ \
487 "ld.w r0, r7[-8*4] \n\t" /* Read SR */\
488 "st.w r7[-2*4], r0 \n\t" /* Copy SR */\
489 "ld.w r0, r7[-7*4] \n\t" /* Read PC */\
490 "st.w r7[-1*4], r0 \n\t" /* Copy PC */\
492 /* Restore R0..R7 */ \
493 "ldm sp++, r0-r7 \n\t"\
499 : [ulCriticalNesting] "i" (&ulCriticalNesting) \
505 * The ISR used depends on whether the cooperative or
506 * the preemptive scheduler is being used.
508 #if configUSE_PREEMPTION == 0
511 * ISR entry and exit macros. These are only required if a task switch
512 * is required from the ISR.
514 #define portENTER_SWITCHING_ISR() \
517 __asm__ __volatile__ ("stm --sp, r0-r7"); \
519 /* With the cooperative scheduler, as there is no context switch by interrupt, */ \
520 /* there is also no context save. */ \
524 * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
526 #define portEXIT_SWITCHING_ISR() \
528 __asm__ __volatile__ ( \
529 /* Restore R0..R7 */ \
530 "ldm sp++, r0-r7 \n\t"\
532 /* With the cooperative scheduler, as there is no context switch by interrupt, */ \
533 /* there is also no context restore. */ \
541 * ISR entry and exit macros. These are only required if a task switch
542 * is required from the ISR.
544 #define portENTER_SWITCHING_ISR() \
546 extern volatile uint32_t ulCriticalNesting; \
547 extern volatile void *volatile pxCurrentTCB; \
549 /* When we come here */ \
550 /* Registers R8..R12, LR, PC and SR had already been pushed to system stack */ \
552 __asm__ __volatile__ ( \
554 "stm --sp, r0-r7 \n\t"\
556 /* Save ulCriticalNesting variable - R0 is overwritten */ \
557 "mov r8, LO(%[ulCriticalNesting]) \n\t"\
558 "orh r8, HI(%[ulCriticalNesting]) \n\t"\
559 "ld.w r0, r8[0] \n\t"\
560 "st.w --sp, r0 \n\t"\
562 /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
563 /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
564 /* level and allow other lower interrupt level to occur). */ \
565 /* In this case we don't want to do a task switch because we don't know what the stack */ \
566 /* currently looks like (we don't know what the interrupted interrupt handler was doing). */ \
567 /* Saving SP in pxCurrentTCB and then later restoring it (thinking restoring the task) */ \
568 /* will just be restoring the interrupt handler, no way!!! */ \
569 /* So, since we won't do a vTaskSwitchContext(), it's of no use to save SP. */ \
570 "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
571 "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
572 "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
573 "brhi LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE] \n\t"\
575 /* Store SP in the first member of the structure pointed to by pxCurrentTCB */ \
576 "mov r8, LO(%[pxCurrentTCB]) \n\t"\
577 "orh r8, HI(%[pxCurrentTCB]) \n\t"\
578 "ld.w r0, r8[0] \n\t"\
581 "LABEL_ISR_SKIP_SAVE_CONTEXT_%[LINE]:" \
583 : [ulCriticalNesting] "i" (&ulCriticalNesting), \
584 [pxCurrentTCB] "i" (&pxCurrentTCB), \
585 [LINE] "i" (__LINE__) \
590 * Input parameter: in R12, boolean. Perform a vTaskSwitchContext() if 1
592 #define portEXIT_SWITCHING_ISR() \
594 extern volatile uint32_t ulCriticalNesting; \
595 extern volatile void *volatile pxCurrentTCB; \
597 __asm__ __volatile__ ( \
598 /* Check if INT0 or higher were being handled (case where the OS tick interrupted another */ \
599 /* interrupt handler (which was of a higher priority level but decided to lower its priority */ \
600 /* level and allow other lower interrupt level to occur). */ \
601 /* In this case it's of no use to switch context and restore a new SP because we purposedly */ \
602 /* did not previously save SP in its TCB. */ \
603 "ld.w r0, sp[9*4] \n\t" /* Read SR in stack */\
604 "bfextu r0, r0, 22, 3 \n\t" /* Extract the mode bits to R0. */\
605 "cp.w r0, 1 \n\t" /* Compare the mode bits with supervisor mode(b'001) */\
606 "brhi LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE] \n\t"\
608 /* If a switch is required then we just need to call */ \
609 /* vTaskSwitchContext() as the context has already been */ \
611 "cp.w r12, 1 \n\t" /* Check if Switch context is required. */\
612 "brne LABEL_ISR_RESTORE_CONTEXT_%[LINE]" \
614 : [LINE] "i" (__LINE__) \
617 /* A critical section has to be used here because vTaskSwitchContext handles FreeRTOS linked lists. */ \
618 portENTER_CRITICAL(); \
619 vTaskSwitchContext(); \
620 portEXIT_CRITICAL(); \
622 __asm__ __volatile__ ( \
623 "LABEL_ISR_RESTORE_CONTEXT_%[LINE]: \n\t"\
624 /* Restore the context of which ever task is now the highest */ \
625 /* priority that is ready to run. */ \
627 /* Restore all registers */ \
629 /* Set SP to point to new stack */ \
630 "mov r8, LO(%[pxCurrentTCB]) \n\t"\
631 "orh r8, HI(%[pxCurrentTCB]) \n\t"\
632 "ld.w r0, r8[0] \n\t"\
635 "LABEL_ISR_SKIP_RESTORE_CONTEXT_%[LINE]: \n\t"\
637 /* Restore ulCriticalNesting variable */ \
638 "ld.w r0, sp++ \n\t"\
639 "mov r8, LO(%[ulCriticalNesting]) \n\t"\
640 "orh r8, HI(%[ulCriticalNesting]) \n\t"\
641 "st.w r8[0], r0 \n\t"\
643 /* Restore R0..R7 */ \
644 "ldm sp++, r0-r7 \n\t"\
646 /* Now, the stack should be R8..R12, LR, PC and SR */ \
649 : [ulCriticalNesting] "i" (&ulCriticalNesting), \
650 [pxCurrentTCB] "i" (&pxCurrentTCB), \
651 [LINE] "i" (__LINE__) \
658 #define portYIELD() {__asm__ __volatile__ ("scall");}
660 /* Task function macros as described on the FreeRTOS.org WEB site. */
661 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
662 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
668 #endif /* PORTMACRO_H */