]> git.sur5r.net Git - freertos/blob - Source/portable/Softune/MB96340/port.c
Add Fujitsu 16bit port files.
[freertos] / Source / portable / Softune / MB96340 / port.c
1 /*\r
2         FreeRTOS.org V4.7.1 - Copyright (C) 2003-2008 Richard Barry.\r
3 \r
4         This file is part of the FreeRTOS.org distribution.\r
5 \r
6         FreeRTOS.org is free software; you can redistribute it and/or modify\r
7         it under the terms of the GNU General Public License as published by\r
8         the Free Software Foundation; either version 2 of the License, or\r
9         (at your option) any later version.\r
10 \r
11         FreeRTOS.org is distributed in the hope that it will be useful,\r
12         but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14         GNU General Public License for more details.\r
15 \r
16         You should have received a copy of the GNU General Public License\r
17         along with FreeRTOS.org; if not, write to the Free Software\r
18         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
19 \r
20         A special exception to the GPL can be applied should you wish to distribute\r
21         a combined work that includes FreeRTOS.org, without being obliged to provide\r
22         the source code for any proprietary components.  See the licensing section\r
23         of http://www.FreeRTOS.org for full details of how and when the exception\r
24         can be applied.\r
25 \r
26         ***************************************************************************\r
27 \r
28         Please ensure to read the configuration and relevant port sections of the \r
29         online documentation.\r
30 \r
31         +++ http://www.FreeRTOS.org +++\r
32         Documentation, latest information, license and contact details.  \r
33 \r
34         +++ http://www.SafeRTOS.com +++\r
35         A version that is certified for use in safety critical systems.\r
36 \r
37         +++ http://www.OpenRTOS.com +++\r
38         Commercial support, development, porting, licensing and training services.\r
39 \r
40         ***************************************************************************\r
41 */\r
42 \r
43 #include "FreeRTOS.h"\r
44 #include "task.h"\r
45 #include "mb96348hs.h"\r
46 \r
47 /*-----------------------------------------------------------\r
48  * Implementation of functions defined in portable.h for the 16FX port.\r
49  *----------------------------------------------------------*/\r
50 \r
51 /* ------- Memory models ---------      default address size */\r
52                                  /*     data      code       */\r
53 #define SMALL     0              /*    16 Bit    16 Bit      */\r
54 #define MEDIUM    1              /*    16 Bit    24 Bit      */\r
55 #define COMPACT   2              /*    24 Bit    16 Bit      */\r
56 #define LARGE     3              /*    24 Bit    24 Bit      */\r
57 \r
58 /* \r
59  * The below define should be same as the option selected by the Memory \r
60  * Model (Project->Setup Project->C Compiler->Catagory->Target Depend ) \r
61  */\r
62 #define MEMMODEL MEDIUM\r
63 \r
64 /*-----------------------------------------------------------*/\r
65 \r
66 /* \r
67  * We require the address of the pxCurrentTCB variable, but don't want to know\r
68  * any details of its type. \r
69  */\r
70 typedef void tskTCB;\r
71 extern volatile tskTCB * volatile pxCurrentTCB;\r
72 \r
73 /*-----------------------------------------------------------*/\r
74 \r
75 /* Get current value of DPR and ADB registers */\r
76 portSTACK_TYPE Get_DPR_ADB_bank(void); \r
77 \r
78 /* Get current value of DTB and PCB registers */\r
79 portSTACK_TYPE Get_DTB_PCB_bank(void);\r
80 \r
81 /* Get current register pointer */ \r
82 portCHAR           Get_RP(void);           \r
83 \r
84 /*-----------------------------------------------------------*/         \r
85 \r
86 /* \r
87  * Macro to save a task context to the task stack. This macro  copies the \r
88  * saved context (AH:AL, DPR:ADB, DTB:PCB , PC and PS) from  the   system \r
89  * stack to task stack pointed by user stack pointer ( USP  for SMALL and \r
90  * MEDIUM memory model amd USB:USP for COMPACT  and LARGE memory model ),\r
91  * then  it pushes the general purpose registers RW0-RW7  on  to the task \r
92  * stack. Finally the  resultant  stack  pointer  value is saved into the \r
93  * task  control  block  so  it  can  be retrieved the next time the task \r
94  * executes.\r
95  */\r
96  \r
97 #if (MEMMODEL == SMALL || MEMMODEL == MEDIUM)                           \r
98 #define portSAVE_CONTEXT()                                                                                      \\r
99             {   __asm(" POPW  A ");                                                                             \\r
100                     __asm(" AND  CCR,#H'DF ");                                                          \\r
101                         __asm(" PUSHW  A ");                                                                    \\r
102                         __asm(" OR   CCR,#H'20 ");                                                              \\r
103                 __asm(" POPW  A ");                                                                             \\r
104                     __asm(" AND  CCR,#H'DF ");                                                          \\r
105                         __asm(" PUSHW  A ");                                                                    \\r
106                         __asm(" OR   CCR,#H'20 ");                                                              \\r
107                         __asm(" POPW  A ");                                                                             \\r
108                     __asm(" AND  CCR,#H'DF ");                                                          \\r
109                         __asm(" PUSHW  A ");                                                                    \\r
110                         __asm(" OR   CCR,#H'20 ");                                                              \\r
111                         __asm(" POPW  A ");                                                                             \\r
112                     __asm(" AND  CCR,#H'DF ");                                                          \\r
113                         __asm(" PUSHW  A ");                                                                    \\r
114                         __asm(" OR   CCR,#H'20 ");                                                              \\r
115                         __asm(" POPW  A ");                                                                             \\r
116                     __asm(" AND  CCR,#H'DF ");                                                          \\r
117                         __asm(" PUSHW  A ");                                                                    \\r
118                         __asm(" OR   CCR,#H'20 ");                                                              \\r
119                         __asm(" POPW  A ");                                                                             \\r
120                     __asm(" AND  CCR,#H'DF ");                                                          \\r
121                         __asm(" PUSHW  A ");                                                                    \\r
122                         __asm(" PUSHW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) ");             \\r
123                         __asm(" MOVW A, _pxCurrentTCB ");                                               \\r
124                         __asm(" MOVW A, SP ");                                                                  \\r
125                         __asm(" SWAPW ");                                                                               \\r
126                     __asm(" MOVW @AL, AH ");                                                            \\r
127                     __asm(" OR   CCR,#H'20 ");                                                          \\r
128                 }\r
129 \r
130 /* \r
131  * Macro to restore a task context from the task stack.  This is effecti-\r
132  * vely the reverse of portSAVE_CONTEXT(). First the stack pointer  value\r
133  * (USP for SMALL and MEDIUM memory model amd  USB:USP  for  COMPACT  and \r
134  * LARGE memory model ) is loaded from the task  control block.  Next the \r
135  * value of all the general purpose registers RW0-RW7 is retrieved. Fina-\r
136  * lly it copies of the context ( AH:AL,  DPR:ADB, DTB:PCB, PC and PS) of \r
137  * the task to be executed upon RETI from user stack to system stack.  \r
138  */\r
139  \r
140 #define portRESTORE_CONTEXT()                                                                           \\r
141                 {       __asm(" MOVW A, _pxCurrentTCB ");                                               \\r
142                         __asm(" MOVW A, @A ");                                                                  \\r
143                         __asm(" AND  CCR,#H'DF ");                                                      \\r
144                         __asm(" MOVW SP, A ");                                                                  \\r
145                         __asm(" POPW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) ");              \\r
146                         __asm(" POPW  A ");                                                                             \\r
147                         __asm(" OR   CCR,#H'20 ");                                                              \\r
148                         __asm(" PUSHW  A ");                                                                    \\r
149                         __asm(" AND  CCR,#H'DF ");                                                      \\r
150                         __asm(" POPW  A ");                                                                             \\r
151                         __asm(" OR   CCR,#H'20 ");                                                              \\r
152                         __asm(" PUSHW  A ");                                                                    \\r
153                         __asm(" AND  CCR,#H'DF ");                                                      \\r
154                         __asm(" POPW  A ");                                                                             \\r
155                         __asm(" OR   CCR,#H'20 ");                                                              \\r
156                         __asm(" PUSHW  A ");                                                                    \\r
157                         __asm(" AND  CCR,#H'DF ");                                                      \\r
158                         __asm(" POPW  A ");                                                                             \\r
159                         __asm(" OR   CCR,#H'20 ");                                                              \\r
160                         __asm(" PUSHW  A ");                                                                    \\r
161                         __asm(" AND  CCR,#H'DF ");                                                      \\r
162                         __asm(" POPW  A ");                                                                             \\r
163                         __asm(" OR   CCR,#H'20 ");                                                              \\r
164                         __asm(" PUSHW  A ");                                                                    \\r
165                         __asm(" AND  CCR,#H'DF ");                                                      \\r
166                         __asm(" POPW  A ");                                                                             \\r
167                         __asm(" OR   CCR,#H'20 ");                                                              \\r
168                         __asm(" PUSHW  A ");                                                                    \\r
169                 }\r
170                 \r
171 #elif (MEMMODEL == COMPACT || MEMMODEL == LARGE)                        \r
172 #define portSAVE_CONTEXT()                                                                                      \\r
173             {   __asm(" POPW  A ");                                                                             \\r
174                     __asm(" AND  CCR,#H'DF ");                                                          \\r
175                         __asm(" PUSHW  A ");                                                                    \\r
176                         __asm(" OR   CCR,#H'20 ");                                                              \\r
177                 __asm(" POPW  A ");                                                                             \\r
178                     __asm(" AND  CCR,#H'DF ");                                                          \\r
179                         __asm(" PUSHW  A ");                                                                    \\r
180                         __asm(" OR   CCR,#H'20 ");                                                              \\r
181                         __asm(" POPW  A ");                                                                             \\r
182                     __asm(" AND  CCR,#H'DF ");                                                          \\r
183                         __asm(" PUSHW  A ");                                                                    \\r
184                         __asm(" OR   CCR,#H'20 ");                                                              \\r
185                         __asm(" POPW  A ");                                                                             \\r
186                     __asm(" AND  CCR,#H'DF ");                                                          \\r
187                         __asm(" PUSHW  A ");                                                                    \\r
188                         __asm(" OR   CCR,#H'20 ");                                                              \\r
189                         __asm(" POPW  A ");                                                                             \\r
190                     __asm(" AND  CCR,#H'DF ");                                                          \\r
191                         __asm(" PUSHW  A ");                                                                    \\r
192                         __asm(" OR   CCR,#H'20 ");                                                              \\r
193                         __asm(" POPW  A ");                                                                             \\r
194                     __asm(" AND  CCR,#H'DF ");                                                          \\r
195                         __asm(" PUSHW  A ");                                                                    \\r
196                         __asm(" PUSHW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) ");             \\r
197                         __asm(" MOVL A, _pxCurrentTCB ");                                               \\r
198                         __asm(" MOVL RL2, A ");                                                                 \\r
199                         __asm(" MOVW A, SP ");                                                                  \\r
200                     __asm(" MOVW @RL2+0, A ");                                                          \\r
201             __asm(" MOV A, USB ");                                                                      \\r
202             __asm(" MOV @RL2+2, A ");                                                           \\r
203                 }       \r
204             \r
205 #define portRESTORE_CONTEXT()                                                                           \\r
206                 {       __asm(" MOVL A, _pxCurrentTCB ");                                               \\r
207                         __asm(" MOVL RL2, A ");                                                                 \\r
208                         __asm(" MOVW A, @RL2+0 ");                                                              \\r
209             __asm(" AND  CCR,#H'DF ");                                                          \\r
210             __asm(" MOVW SP, A ");                                                                      \\r
211             __asm(" MOV A, @RL2+2 ");                                                           \\r
212                         __asm(" MOV USB, A ");                                                                  \\r
213                         __asm(" POPW (RW0,RW1,RW2,RW3,RW4,RW5,RW6,RW7) ");              \\r
214                         __asm(" POPW  A ");                                                                             \\r
215                         __asm(" OR   CCR,#H'20 ");                                                              \\r
216                         __asm(" PUSHW  A ");                                                                    \\r
217                         __asm(" AND  CCR,#H'DF ");                                                      \\r
218                         __asm(" POPW  A ");                                                                             \\r
219                         __asm(" OR   CCR,#H'20 ");                                                              \\r
220                         __asm(" PUSHW  A ");                                                                    \\r
221                         __asm(" AND  CCR,#H'DF ");                                                      \\r
222                         __asm(" POPW  A ");                                                                             \\r
223                         __asm(" OR   CCR,#H'20 ");                                                              \\r
224                         __asm(" PUSHW  A ");                                                                    \\r
225                         __asm(" AND  CCR,#H'DF ");                                                      \\r
226                         __asm(" POPW  A ");                                                                             \\r
227                         __asm(" OR   CCR,#H'20 ");                                                              \\r
228                         __asm(" PUSHW  A ");                                                                    \\r
229                         __asm(" AND  CCR,#H'DF ");                                                      \\r
230                         __asm(" POPW  A ");                                                                             \\r
231                         __asm(" OR   CCR,#H'20 ");                                                              \\r
232                         __asm(" PUSHW  A ");                                                                    \\r
233                         __asm(" AND  CCR,#H'DF ");                                                      \\r
234                         __asm(" POPW  A ");                                                                             \\r
235                         __asm(" OR   CCR,#H'20 ");                                                              \\r
236                         __asm(" PUSHW  A ");                                                                    \\r
237                 }\r
238 #endif\r
239 \r
240 /*-----------------------------------------------------------*/ \r
241 \r
242 /* \r
243  * The below are the functions for getting the current value  of  DPR:ADB, \r
244  * DTB:PCB bank registers\r
245  */\r
246  \r
247 #pragma asm\r
248         .GLOBAL    _Get_DPR_ADB_bank\r
249         .GLOBAL    _Get_DTB_PCB_bank\r
250         .GLOBAL    _Get_RP\r
251         .SECTION   CODE, CODE, ALIGN=1\r
252 _Get_DPR_ADB_bank:\r
253     MOV A, DPR\r
254     SWAP\r
255     MOV A, ADB\r
256     ORW A\r
257 #if MEMMODEL == MEDIUM || MEMMODEL == LARGE\r
258     RETP\r
259 #elif MEMMODEL == SMALL || MEMMODEL == COMPACT   \r
260     RET\r
261 #endif \r
262 \r
263 _Get_DTB_PCB_bank:\r
264     MOV A, DTB\r
265     SWAP\r
266     MOV A, PCB\r
267     ORW A\r
268 #if MEMMODEL == MEDIUM || MEMMODEL == LARGE\r
269     RETP\r
270 #elif MEMMODEL == SMALL || MEMMODEL == COMPACT   \r
271     RET\r
272 #endif \r
273 \r
274 _Get_RP:\r
275     PUSHW PS\r
276     POPW  A\r
277     SWAP\r
278     ANDW  A,#0x1f\r
279  #if MEMMODEL == MEDIUM || MEMMODEL == LARGE\r
280     RETP\r
281 #elif MEMMODEL == SMALL || MEMMODEL == COMPACT   \r
282     RET\r
283 #endif \r
284 #pragma endasm\r
285 /*-----------------------------------------------------------*/\r
286 \r
287 /*\r
288  * Sets up the periodic ISR used for the RTOS tick.  This uses RLT0, but\r
289  * can be done using any given RLT.\r
290  */\r
291 static void prvSetupRLT0Interrupt( void );\r
292 /*-----------------------------------------------------------*/\r
293 \r
294 /* \r
295  * Initialise the stack of a task to look exactly as if a call to \r
296  * portSAVE_CONTEXT had been called.\r
297  * \r
298  * See the header file portable.h.\r
299  */\r
300 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
301 {\r
302         /* Place a few bytes of known values on the bottom of the stack. \r
303         This is just useful for debugging. */\r
304 \r
305         *pxTopOfStack = 0x1111;\r
306         pxTopOfStack--;\r
307         *pxTopOfStack = 0x2222;\r
308         pxTopOfStack--;\r
309         *pxTopOfStack = 0x3333;\r
310         pxTopOfStack--;\r
311 \r
312         /* Once the task is called the called  would  push  the  pointer to the\r
313         parameter on to the stack. Hence here the pointer would be copied first\r
314         to  the  stack.  In  case of COMPACT or LARGE memory model such pointer \r
315         would be 24 bit and in  case of SMALL or MEDIUM memory model such pointer \r
316         would be 16 bit */ \r
317 #if MEMMODEL == COMPACT || MEMMODEL == LARGE\r
318     *pxTopOfStack = (portSTACK_TYPE)((portLONG)(pvParameters)>>16);\r
319         pxTopOfStack--;         \r
320 #endif\r
321 \r
322     *pxTopOfStack = (portSTACK_TYPE)(pvParameters);\r
323     pxTopOfStack--;                  \r
324     \r
325     /* This is redundant push to the stack. This is required in order to introduce \r
326     an offset so that the task accesses a parameter correctly that is passed on to \r
327     the task stack. */\r
328 #if MEMMODEL == MEDIUM || MEMMODEL == LARGE\r
329     *pxTopOfStack = (Get_DTB_PCB_bank() & 0xff00) |\r
330            (((portLONG)(pxCode) >>16) & 0xff);      \r
331     pxTopOfStack--;       \r
332 #endif\r
333 \r
334     /* This is redundant push to the stack. This is required in order to introduce \r
335     an offset so that the task accesses a parameter correctly that is passed on to \r
336     the task stack. */\r
337     *pxTopOfStack = ( portSTACK_TYPE )(pxCode);\r
338     pxTopOfStack--;       \r
339 \r
340     /* PS - User Mode, ILM=7, RB=0, Interrupts enabled,USP */\r
341     *pxTopOfStack = 0xE0C0;                                                     \r
342         pxTopOfStack--; \r
343 \r
344         /* PC                                                                                              */\r
345         *pxTopOfStack = ( portSTACK_TYPE )(pxCode);     \r
346     pxTopOfStack--;      \r
347     \r
348     /* DTB | PCB                                                                                   */\r
349 #if MEMMODEL == SMALL || MEMMODEL == COMPACT\r
350     *pxTopOfStack = Get_DTB_PCB_bank();                 \r
351     pxTopOfStack--;\r
352 #endif\r
353 \r
354         /* DTB | PCB, in case of MEDIUM or LARGE memory model PCB would be used\r
355         along with PC to indicate the start address of the functiom */\r
356 #if MEMMODEL == MEDIUM || MEMMODEL == LARGE\r
357     *pxTopOfStack = (Get_DTB_PCB_bank() & 0xff00) |\r
358            (((portLONG)(pxCode) >>16) & 0xff);      \r
359     pxTopOfStack--;       \r
360 #endif\r
361 \r
362         /* DPR | ADB                                                                              */\r
363         *pxTopOfStack = Get_DPR_ADB_bank();                             \r
364         pxTopOfStack--;\r
365     \r
366         /* AL                                                                                             */\r
367         *pxTopOfStack = ( portSTACK_TYPE ) 0x9999;              \r
368         pxTopOfStack--;\r
369 \r
370         /* AH                                                                                             */\r
371         *pxTopOfStack = ( portSTACK_TYPE ) 0xAAAA;              \r
372         pxTopOfStack--;\r
373         \r
374         /* Next the general purpose registers.                            */\r
375         *pxTopOfStack = ( portSTACK_TYPE ) 0x7777;      /* RW7 */\r
376         pxTopOfStack--;\r
377         *pxTopOfStack = ( portSTACK_TYPE ) 0x6666;      /* RW6 */\r
378         pxTopOfStack--;\r
379         *pxTopOfStack = ( portSTACK_TYPE ) 0x5555;      /* RW5 */\r
380         pxTopOfStack--;\r
381         *pxTopOfStack = ( portSTACK_TYPE ) 0x4444;      /* RW4 */\r
382         pxTopOfStack--;\r
383         *pxTopOfStack = ( portSTACK_TYPE ) 0x3333;      /* RW3 */\r
384         pxTopOfStack--;\r
385         *pxTopOfStack = ( portSTACK_TYPE ) 0x2222;      /* RW2 */\r
386         pxTopOfStack--;\r
387         *pxTopOfStack = ( portSTACK_TYPE ) 0x1111;      /* RW1 */\r
388         pxTopOfStack--;\r
389         *pxTopOfStack = ( portSTACK_TYPE ) 0x8888;      /* RW0 */\r
390                 \r
391         return pxTopOfStack;\r
392 }\r
393 /*-----------------------------------------------------------*/\r
394 /*\r
395  * Setup RLT0 to generate a tick interrupt.\r
396  */\r
397 static void prvSetupRLT0Interrupt( void )\r
398 {\r
399         /* set reload value = 34999+1, TICK Interrupt after 10 ms @ 56MHz of CLKP1 */\r
400         TMRLR0 = 0x88B7;    \r
401     \r
402     /* prescaler 1:16, reload, interrupt enable, count enable, trigger */\r
403     TMCSR0 = 0x041B;    \r
404 }\r
405 /*-----------------------------------------------------------*/\r
406 /*\r
407  * Start the scheduler.\r
408  */\r
409 portBASE_TYPE xPortStartScheduler( void )\r
410 {\r
411         /* Setup the hardware to generate the tick. */\r
412         prvSetupRLT0Interrupt();\r
413         \r
414         /* Restore the context of the first task that is going to run. */\r
415         portRESTORE_CONTEXT();\r
416 \r
417         /* Simulate a function call end as generated by the compiler.  We will now\r
418         jump to the start of the task the context of which we have just restored. */\r
419         \r
420         __asm(" reti ");\r
421 \r
422 \r
423         /* Should not get here. */\r
424         return pdTRUE;\r
425 }\r
426 /*-----------------------------------------------------------*/\r
427 \r
428 void vPortEndScheduler( void )\r
429 {\r
430         /* It is unlikely that the AVR port will get stopped.  If required simply\r
431         disable the tick interrupt here. */\r
432 }\r
433 \r
434 /*-----------------------------------------------------------*/\r
435 \r
436 /* \r
437  * The interrupt service routine used depends on whether the pre-emptive\r
438  * scheduler is being used or not.\r
439  */\r
440 \r
441 #if configUSE_PREEMPTION == 1\r
442 \r
443         /* \r
444          * Tick ISR for preemptive scheduler.  We can use a __nosavereg attribute\r
445          * as the context would be saved by PortSAVE_CONTEXT().  The tick count \r
446          * is incremented after the context is saved. \r
447          */\r
448         __nosavereg __interrupt void prvRLT0_TICKISR( void )\r
449         {\r
450                 /* Disable interrupts so that portSAVE_CONTEXT() is not interrupted */\r
451                 __DI();\r
452                 \r
453                 /* Save the context of the interrupted task. */\r
454                 portSAVE_CONTEXT();\r
455                 \r
456                 /* Enable interrupts */\r
457                 __EI();\r
458                 \r
459                 /* Clear RLT0 interrupt flag */\r
460                 TMCSR0_UF = 0;      \r
461                 \r
462                 /* Increment the tick count then switch to the highest priority task\r
463                 that is ready to run. */\r
464                 vTaskIncrementTick();\r
465                 vTaskSwitchContext();\r
466 \r
467                 /* Disable interrupts so that portRESTORE_CONTEXT() is not interrupted */\r
468                 __DI();\r
469                 \r
470                 /* Restore the context of the new task. */\r
471                 portRESTORE_CONTEXT();\r
472                 \r
473                 /* Enable interrupts */\r
474                 __EI();\r
475         }\r
476 \r
477 #else\r
478 \r
479         /*\r
480          * Tick ISR for the cooperative scheduler.  All this does is increment the\r
481          * tick count.  We don't need to switch context, this can only be done by\r
482          * manual calls to taskYIELD();\r
483          */\r
484         __interrupt void prvRLT0_TICKISR( void )\r
485         {\r
486                 /* Clear RLT0 interrupt flag */\r
487                 TMCSR0_UF = 0;  \r
488                 \r
489                 vTaskIncrementTick();\r
490         }\r
491 #endif\r
492 \r
493 /*-----------------------------------------------------------*/\r
494 \r
495 /*\r
496  * Manual context switch. We can use a __nosavereg attribute  as the context \r
497  * would be saved by PortSAVE_CONTEXT().  The context is switched and then \r
498  * the context of the new task is restored saved. \r
499  */\r
500 __nosavereg __interrupt void vPortYield( void )\r
501 {\r
502         /* Save the context of the interrupted task. */\r
503         portSAVE_CONTEXT();\r
504         \r
505         /* Switch to the highest priority task that is ready to run. */\r
506         vTaskSwitchContext();\r
507         \r
508         /* Restore the context of the new task. */\r
509         portRESTORE_CONTEXT();\r
510 }\r
511 \r
512 __nosavereg __interrupt void vPortYieldDelayed( void )\r
513 {    \r
514     /* Disable interrupts so that portSAVE_CONTEXT() is not interrupted */      \r
515         __DI();\r
516         \r
517         /* Save the context of the interrupted task. */\r
518         portSAVE_CONTEXT();\r
519         \r
520         /* Enable interrupts */\r
521         __EI();\r
522                                 \r
523         /* Clear delayed interrupt flag */\r
524     __asm (" CLRB  03A4H:0 ");\r
525         \r
526         /* Switch to the highest priority task that is ready to run. */\r
527         vTaskSwitchContext();\r
528         \r
529         /* Disable interrupts so that portSAVE_CONTEXT() is not interrupted */   \r
530         __DI();\r
531         \r
532         /* Restore the context of the new task. */\r
533         portRESTORE_CONTEXT();\r
534 \r
535         /* Enable interrupts */\r
536         __EI();\r
537 }       \r