]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/ARM_CM3_MPU/port.c
Improve QueueSet.c test coverage by reading the queue set from an ISR to force paths...
[freertos] / FreeRTOS / Source / portable / GCC / ARM_CM3_MPU / port.c
1 /*\r
2     FreeRTOS V7.3.0 - Copyright (C) 2012 Real Time Engineers Ltd.\r
3 \r
4     FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT\r
5     http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
10      *    Complete, revised, and edited pdf reference manuals are also       *\r
11      *    available.                                                         *\r
12      *                                                                       *\r
13      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
14      *    ensuring you get running as quickly as possible and with an        *\r
15      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
16      *    the FreeRTOS project to continue with its mission of providing     *\r
17      *    professional grade, cross platform, de facto standard solutions    *\r
18      *    for microcontrollers - completely free of charge!                  *\r
19      *                                                                       *\r
20      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
21      *                                                                       *\r
22      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
23      *                                                                       *\r
24     ***************************************************************************\r
25 \r
26 \r
27     This file is part of the FreeRTOS distribution.\r
28 \r
29     FreeRTOS is free software; you can redistribute it and/or modify it under\r
30     the terms of the GNU General Public License (version 2) as published by the\r
31     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
32     >>>NOTE<<< The modification to the GPL is included to allow you to\r
33     distribute a combined work that includes FreeRTOS without being obliged to\r
34     provide the source code for proprietary components outside of the FreeRTOS\r
35     kernel.  FreeRTOS is distributed in the hope that it will be useful, but\r
36     WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
37     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for\r
38     more details. You should have received a copy of the GNU General Public\r
39     License and the FreeRTOS license exception along with FreeRTOS; if not it\r
40     can be viewed here: http://www.freertos.org/a00114.html and also obtained\r
41     by writing to Richard Barry, contact details for whom are available on the\r
42     FreeRTOS WEB site.\r
43 \r
44     1 tab == 4 spaces!\r
45 \r
46     ***************************************************************************\r
47      *                                                                       *\r
48      *    Having a problem?  Start by reading the FAQ "My application does   *\r
49      *    not run, what could be wrong?"                                     *\r
50      *                                                                       *\r
51      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
52      *                                                                       *\r
53     ***************************************************************************\r
54 \r
55 \r
56     http://www.FreeRTOS.org - Documentation, training, latest versions, license\r
57     and contact details.\r
58 \r
59     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
60     including FreeRTOS+Trace - an indispensable productivity tool.\r
61 \r
62     Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell\r
63     the code with commercial support, indemnification, and middleware, under\r
64     the OpenRTOS brand: http://www.OpenRTOS.com.  High Integrity Systems also\r
65     provide a safety engineered and independently SIL3 certified version under\r
66     the SafeRTOS brand: http://www.SafeRTOS.com.\r
67 */\r
68 \r
69 /*-----------------------------------------------------------\r
70  * Implementation of functions defined in portable.h for the ARM CM3 port.\r
71  *----------------------------------------------------------*/\r
72 \r
73 /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining\r
74 all the API functions to use the MPU wrappers.  That should only be done when\r
75 task.h is included from an application file. */\r
76 #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
77 \r
78 /* Scheduler includes. */\r
79 #include "FreeRTOS.h"\r
80 #include "task.h"\r
81 #include "queue.h"\r
82 \r
83 #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE\r
84 \r
85 /* Constants required to access and manipulate the NVIC. */\r
86 #define portNVIC_SYSTICK_CTRL                                   ( ( volatile unsigned long * ) 0xe000e010 )\r
87 #define portNVIC_SYSTICK_LOAD                                   ( ( volatile unsigned long * ) 0xe000e014 )\r
88 #define portNVIC_SYSPRI2                                                ( ( volatile unsigned long * ) 0xe000ed20 )\r
89 #define portNVIC_SYSPRI1                                                ( ( volatile unsigned long * ) 0xe000ed1c )\r
90 #define portNVIC_SYS_CTRL_STATE                                 ( ( volatile unsigned long * ) 0xe000ed24 )\r
91 #define portNVIC_MEM_FAULT_ENABLE                               ( 1UL << 16UL )\r
92 \r
93 /* Constants required to access and manipulate the MPU. */\r
94 #define portMPU_TYPE                                                    ( ( volatile unsigned long * ) 0xe000ed90 )\r
95 #define portMPU_REGION_BASE_ADDRESS                             ( ( volatile unsigned long * ) 0xe000ed9C )\r
96 #define portMPU_REGION_ATTRIBUTE                                ( ( volatile unsigned long * ) 0xe000edA0 )\r
97 #define portMPU_CTRL                                                    ( ( volatile unsigned long * ) 0xe000ed94 )\r
98 #define portEXPECTED_MPU_TYPE_VALUE                             ( 8UL << 8UL ) /* 8 regions, unified. */\r
99 #define portMPU_ENABLE                                                  ( 0x01UL )\r
100 #define portMPU_BACKGROUND_ENABLE                               ( 1UL << 2UL )\r
101 #define portPRIVILEGED_EXECUTION_START_ADDRESS  ( 0UL )\r
102 #define portMPU_REGION_VALID                                    ( 0x10UL )\r
103 #define portMPU_REGION_ENABLE                                   ( 0x01UL )\r
104 #define portPERIPHERALS_START_ADDRESS                   0x40000000UL\r
105 #define portPERIPHERALS_END_ADDRESS                             0x5FFFFFFFUL\r
106 \r
107 /* Constants required to access and manipulate the SysTick. */\r
108 #define portNVIC_SYSTICK_CLK                                    ( 0x00000004UL )\r
109 #define portNVIC_SYSTICK_INT                                    ( 0x00000002UL )\r
110 #define portNVIC_SYSTICK_ENABLE                                 ( 0x00000001UL )\r
111 #define portNVIC_PENDSV_PRI                                             ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16UL )\r
112 #define portNVIC_SYSTICK_PRI                                    ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )\r
113 #define portNVIC_SVC_PRI                                                ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24UL )\r
114 \r
115 /* Constants required to set up the initial stack. */\r
116 #define portINITIAL_XPSR                                                ( 0x01000000 )\r
117 #define portINITIAL_CONTROL_IF_UNPRIVILEGED             ( 0x03 )\r
118 #define portINITIAL_CONTROL_IF_PRIVILEGED               ( 0x02 )\r
119 \r
120 /* Offsets in the stack to the parameters when inside the SVC handler. */\r
121 #define portOFFSET_TO_PC                                                ( 6 )\r
122 \r
123 /* Set the privilege level to user mode if xRunningPrivileged is false. */\r
124 #define portRESET_PRIVILEGE( xRunningPrivileged ) if( xRunningPrivileged != pdTRUE ) __asm volatile ( " mrs r0, control \n orr r0, #1 \n msr control, r0" :::"r0" )\r
125 \r
126 /* Each task maintains its own interrupt status in the critical nesting\r
127 variable.  Note this is not saved as part of the task context as context\r
128 switches can only occur when uxCriticalNesting is zero. */\r
129 static unsigned portBASE_TYPE uxCriticalNesting = 0xaaaaaaaa;\r
130 \r
131 /*\r
132  * Setup the timer to generate the tick interrupts.\r
133  */\r
134 static void prvSetupTimerInterrupt( void ) PRIVILEGED_FUNCTION;\r
135 \r
136 /*\r
137  * Configure a number of standard MPU regions that are used by all tasks.\r
138  */\r
139 static void prvSetupMPU( void ) PRIVILEGED_FUNCTION;\r
140 \r
141 /*\r
142  * Return the smallest MPU region size that a given number of bytes will fit\r
143  * into.  The region size is returned as the value that should be programmed\r
144  * into the region attribute register for that region.\r
145  */\r
146 static unsigned long prvGetMPURegionSizeSetting( unsigned long ulActualSizeInBytes ) PRIVILEGED_FUNCTION;\r
147 \r
148 /*\r
149  * Checks to see if being called from the context of an unprivileged task, and\r
150  * if so raises the privilege level and returns false - otherwise does nothing\r
151  * other than return true.\r
152  */\r
153 static portBASE_TYPE prvRaisePrivilege( void ) __attribute__(( naked ));\r
154 \r
155 /*\r
156  * Standard FreeRTOS exception handlers.\r
157  */\r
158 void xPortPendSVHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;\r
159 void xPortSysTickHandler( void )  __attribute__ ((optimize("3"))) PRIVILEGED_FUNCTION;\r
160 void vPortSVCHandler( void ) __attribute__ (( naked )) PRIVILEGED_FUNCTION;\r
161 \r
162 /*\r
163  * Starts the scheduler by restoring the context of the first task to run.\r
164  */\r
165 static void prvRestoreContextOfFirstTask( void ) __attribute__(( naked )) PRIVILEGED_FUNCTION;\r
166 \r
167 /*\r
168  * C portion of the SVC handler.  The SVC handler is split between an asm entry\r
169  * and a C wrapper for simplicity of coding and maintenance.\r
170  */\r
171 static void prvSVCHandler( unsigned long *pulRegisters ) __attribute__(( noinline )) PRIVILEGED_FUNCTION;\r
172 \r
173 /*\r
174  * Prototypes for all the MPU wrappers.\r
175  */\r
176 signed portBASE_TYPE MPU_xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions );\r
177 void MPU_vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const xRegions );\r
178 void MPU_vTaskDelete( xTaskHandle pxTaskToDelete );\r
179 void MPU_vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement );\r
180 void MPU_vTaskDelay( portTickType xTicksToDelay );\r
181 unsigned portBASE_TYPE MPU_uxTaskPriorityGet( xTaskHandle pxTask );\r
182 void MPU_vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority );\r
183 eTaskState MPU_eTaskGetState( xTaskHandle pxTask );\r
184 void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend );\r
185 signed portBASE_TYPE MPU_xTaskIsTaskSuspended( xTaskHandle xTask );\r
186 void MPU_vTaskResume( xTaskHandle pxTaskToResume );\r
187 void MPU_vTaskSuspendAll( void );\r
188 signed portBASE_TYPE MPU_xTaskResumeAll( void );\r
189 portTickType MPU_xTaskGetTickCount( void );\r
190 unsigned portBASE_TYPE MPU_uxTaskGetNumberOfTasks( void );\r
191 void MPU_vTaskList( signed char *pcWriteBuffer );\r
192 void MPU_vTaskGetRunTimeStats( signed char *pcWriteBuffer );\r
193 void MPU_vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue );\r
194 pdTASK_HOOK_CODE MPU_xTaskGetApplicationTaskTag( xTaskHandle xTask );\r
195 portBASE_TYPE MPU_xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter );\r
196 unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask );\r
197 xTaskHandle MPU_xTaskGetCurrentTaskHandle( void );\r
198 portBASE_TYPE MPU_xTaskGetSchedulerState( void );\r
199 xTaskHandle MPU_xTaskGetIdleTaskHandle( void );\r
200 xQueueHandle MPU_xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType );\r
201 signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
202 portBASE_TYPE MPU_xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue );\r
203 unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue );\r
204 signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
205 xQueueHandle MPU_xQueueCreateMutex( void );\r
206 xQueueHandle MPU_xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount );\r
207 portBASE_TYPE MPU_xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime );\r
208 portBASE_TYPE MPU_xQueueGiveMutexRecursive( xQueueHandle xMutex );\r
209 signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition );\r
210 signed portBASE_TYPE MPU_xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking );\r
211 void MPU_vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName );\r
212 void MPU_vQueueDelete( xQueueHandle xQueue );\r
213 void *MPU_pvPortMalloc( size_t xSize );\r
214 void MPU_vPortFree( void *pv );\r
215 void MPU_vPortInitialiseBlocks( void );\r
216 size_t MPU_xPortGetFreeHeapSize( void );\r
217 xQueueSetHandle MPU_xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength );\r
218 xQueueSetMemberHandle MPU_xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks );\r
219 portBASE_TYPE MPU_xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );\r
220 portBASE_TYPE MPU_xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet );\r
221 \r
222 /*-----------------------------------------------------------*/\r
223 \r
224 /*\r
225  * See header file for description.\r
226  */\r
227 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters, portBASE_TYPE xRunPrivileged )\r
228 {\r
229         /* Simulate the stack frame as it would be created by a context switch\r
230         interrupt. */\r
231         pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */\r
232         *pxTopOfStack = portINITIAL_XPSR;       /* xPSR */\r
233         pxTopOfStack--;\r
234         *pxTopOfStack = ( portSTACK_TYPE ) pxCode;      /* PC */\r
235         pxTopOfStack--;\r
236         *pxTopOfStack = 0;      /* LR */\r
237         pxTopOfStack -= 5;      /* R12, R3, R2 and R1. */\r
238         *pxTopOfStack = ( portSTACK_TYPE ) pvParameters;        /* R0 */\r
239         pxTopOfStack -= 9;      /* R11, R10, R9, R8, R7, R6, R5 and R4. */\r
240 \r
241         if( xRunPrivileged == pdTRUE )\r
242         {\r
243                 *pxTopOfStack = portINITIAL_CONTROL_IF_PRIVILEGED;\r
244         }\r
245         else\r
246         {\r
247                 *pxTopOfStack = portINITIAL_CONTROL_IF_UNPRIVILEGED;\r
248         }\r
249 \r
250         return pxTopOfStack;\r
251 }\r
252 /*-----------------------------------------------------------*/\r
253 \r
254 void vPortSVCHandler( void )\r
255 {\r
256         /* Assumes psp was in use. */\r
257         __asm volatile\r
258         (\r
259                 #ifndef USE_PROCESS_STACK       /* Code should not be required if a main() is using the process stack. */\r
260                         "       tst lr, #4                                              \n"\r
261                         "       ite eq                                                  \n"\r
262                         "       mrseq r0, msp                                   \n"\r
263                         "       mrsne r0, psp                                   \n"\r
264                 #else\r
265                         "       mrs r0, psp                                             \n"\r
266                 #endif\r
267                         "       b %0                                                    \n"\r
268                         ::"i"(prvSVCHandler):"r0"\r
269         );\r
270 }\r
271 /*-----------------------------------------------------------*/\r
272 \r
273 static void prvSVCHandler(      unsigned long *pulParam )\r
274 {\r
275 unsigned char ucSVCNumber;\r
276 \r
277         /* The stack contains: r0, r1, r2, r3, r12, r14, the return address and\r
278         xPSR.  The first argument (r0) is pulParam[ 0 ]. */\r
279         ucSVCNumber = ( ( unsigned char * ) pulParam[ portOFFSET_TO_PC ] )[ -2 ];\r
280         switch( ucSVCNumber )\r
281         {\r
282                 case portSVC_START_SCHEDULER    :       *(portNVIC_SYSPRI1) |= portNVIC_SVC_PRI;\r
283                                                                                         prvRestoreContextOfFirstTask();\r
284                                                                                         break;\r
285 \r
286                 case portSVC_YIELD                              :       *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
287                                                                                         break;\r
288 \r
289                 case portSVC_RAISE_PRIVILEGE    :       __asm volatile\r
290                                                                                         (\r
291                                                                                                 "       mrs r1, control         \n" /* Obtain current control value. */\r
292                                                                                                 "       bic r1, #1                      \n" /* Set privilege bit. */\r
293                                                                                                 "       msr control, r1         \n" /* Write back new control value. */\r
294                                                                                                 :::"r1"\r
295                                                                                         );\r
296                                                                                         break;\r
297 \r
298                 default                                                 :       /* Unknown SVC call. */\r
299                                                                                         break;\r
300         }\r
301 }\r
302 /*-----------------------------------------------------------*/\r
303 \r
304 static void prvRestoreContextOfFirstTask( void )\r
305 {\r
306         __asm volatile\r
307         (\r
308                 "       ldr r0, =0xE000ED08                             \n" /* Use the NVIC offset register to locate the stack. */\r
309                 "       ldr r0, [r0]                                    \n"\r
310                 "       ldr r0, [r0]                                    \n"\r
311                 "       msr msp, r0                                             \n" /* Set the msp back to the start of the stack. */\r
312                 "       ldr     r3, pxCurrentTCBConst2          \n" /* Restore the context. */\r
313                 "       ldr r1, [r3]                                    \n"\r
314                 "       ldr r0, [r1]                                    \n" /* The first item in the TCB is the task top of stack. */\r
315                 "       add r1, r1, #4                                  \n" /* Move onto the second item in the TCB... */\r
316                 "       ldr r2, =0xe000ed9c                             \n" /* Region Base Address register. */\r
317                 "       ldmia r1!, {r4-r11}                             \n" /* Read 4 sets of MPU registers. */\r
318                 "       stmia r2!, {r4-r11}                             \n" /* Write 4 sets of MPU registers. */\r
319                 "       ldmia r0!, {r3, r4-r11}                 \n" /* Pop the registers that are not automatically saved on exception entry. */\r
320                 "       msr control, r3                                 \n"\r
321                 "       msr psp, r0                                             \n" /* Restore the task stack pointer. */\r
322                 "       mov r0, #0                                              \n"\r
323                 "       msr     basepri, r0                                     \n"\r
324                 "       ldr r14, =0xfffffffd                    \n" /* Load exec return code. */\r
325                 "       bx r14                                                  \n"\r
326                 "                                                                       \n"\r
327                 "       .align 2                                                \n"\r
328                 "pxCurrentTCBConst2: .word pxCurrentTCB \n"\r
329         );\r
330 }\r
331 /*-----------------------------------------------------------*/\r
332 \r
333 /*\r
334  * See header file for description.\r
335  */\r
336 portBASE_TYPE xPortStartScheduler( void )\r
337 {\r
338         /* configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See\r
339         http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */\r
340         configASSERT( ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) );\r
341 \r
342         /* Make PendSV and SysTick the same priority as the kernel. */\r
343         *(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;\r
344         *(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PRI;\r
345 \r
346         /* Configure the regions in the MPU that are common to all tasks. */\r
347         prvSetupMPU();\r
348 \r
349         /* Start the timer that generates the tick ISR.  Interrupts are disabled\r
350         here already. */\r
351         prvSetupTimerInterrupt();\r
352 \r
353         /* Initialise the critical nesting count ready for the first task. */\r
354         uxCriticalNesting = 0;\r
355 \r
356         /* Start the first task. */\r
357         __asm volatile( "       svc %0                  \n"\r
358                                         :: "i" (portSVC_START_SCHEDULER) );\r
359 \r
360         /* Should not get here! */\r
361         return 0;\r
362 }\r
363 /*-----------------------------------------------------------*/\r
364 \r
365 void vPortEndScheduler( void )\r
366 {\r
367         /* It is unlikely that the CM3 port will require this function as there\r
368         is nothing to return to.  */\r
369 }\r
370 /*-----------------------------------------------------------*/\r
371 \r
372 void vPortEnterCritical( void )\r
373 {\r
374 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
375 \r
376         portDISABLE_INTERRUPTS();\r
377         uxCriticalNesting++;\r
378 \r
379         portRESET_PRIVILEGE( xRunningPrivileged );\r
380 }\r
381 /*-----------------------------------------------------------*/\r
382 \r
383 void vPortExitCritical( void )\r
384 {\r
385 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
386 \r
387         uxCriticalNesting--;\r
388         if( uxCriticalNesting == 0 )\r
389         {\r
390                 portENABLE_INTERRUPTS();\r
391         }\r
392         portRESET_PRIVILEGE( xRunningPrivileged );\r
393 }\r
394 /*-----------------------------------------------------------*/\r
395 \r
396 void xPortPendSVHandler( void )\r
397 {\r
398         /* This is a naked function. */\r
399 \r
400         __asm volatile\r
401         (\r
402                 "       mrs r0, psp                                                     \n"\r
403                 "                                                                               \n"\r
404                 "       ldr     r3, pxCurrentTCBConst                   \n" /* Get the location of the current TCB. */\r
405                 "       ldr     r2, [r3]                                                \n"\r
406                 "                                                                               \n"\r
407                 "       mrs r1, control                                         \n"\r
408                 "       stmdb r0!, {r1, r4-r11}                         \n" /* Save the remaining registers. */\r
409                 "       str r0, [r2]                                            \n" /* Save the new top of stack into the first member of the TCB. */\r
410                 "                                                                               \n"\r
411                 "       stmdb sp!, {r3, r14}                            \n"\r
412                 "       mov r0, %0                                                      \n"\r
413                 "       msr basepri, r0                                         \n"\r
414                 "       bl vTaskSwitchContext                           \n"\r
415                 "       mov r0, #0                                                      \n"\r
416                 "       msr basepri, r0                                         \n"\r
417                 "       ldmia sp!, {r3, r14}                            \n"\r
418                 "                                                                               \n"     /* Restore the context. */\r
419                 "       ldr r1, [r3]                                            \n"\r
420                 "       ldr r0, [r1]                                            \n" /* The first item in the TCB is the task top of stack. */\r
421                 "       add r1, r1, #4                                          \n" /* Move onto the second item in the TCB... */\r
422                 "       ldr r2, =0xe000ed9c                                     \n" /* Region Base Address register. */\r
423                 "       ldmia r1!, {r4-r11}                                     \n" /* Read 4 sets of MPU registers. */\r
424                 "       stmia r2!, {r4-r11}                                     \n" /* Write 4 sets of MPU registers. */\r
425                 "       ldmia r0!, {r3, r4-r11}                         \n" /* Pop the registers that are not automatically saved on exception entry. */\r
426                 "       msr control, r3                                         \n"\r
427                 "                                                                               \n"\r
428                 "       msr psp, r0                                                     \n"\r
429                 "       bx r14                                                          \n"\r
430                 "                                                                               \n"\r
431                 "       .align 2                                                        \n"\r
432                 "pxCurrentTCBConst: .word pxCurrentTCB  \n"\r
433                 ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY)\r
434         );\r
435 }\r
436 /*-----------------------------------------------------------*/\r
437 \r
438 void xPortSysTickHandler( void )\r
439 {\r
440 unsigned long ulDummy;\r
441 \r
442         /* If using preemption, also force a context switch. */\r
443         #if configUSE_PREEMPTION == 1\r
444                 *(portNVIC_INT_CTRL) = portNVIC_PENDSVSET;\r
445         #endif\r
446 \r
447         ulDummy = portSET_INTERRUPT_MASK_FROM_ISR();\r
448         {\r
449                 vTaskIncrementTick();\r
450         }\r
451         portCLEAR_INTERRUPT_MASK_FROM_ISR( ulDummy );\r
452 }\r
453 /*-----------------------------------------------------------*/\r
454 \r
455 /*\r
456  * Setup the systick timer to generate the tick interrupts at the required\r
457  * frequency.\r
458  */\r
459 static void prvSetupTimerInterrupt( void )\r
460 {\r
461         /* Configure SysTick to interrupt at the requested rate. */\r
462         *(portNVIC_SYSTICK_LOAD) = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;\r
463         *(portNVIC_SYSTICK_CTRL) = portNVIC_SYSTICK_CLK | portNVIC_SYSTICK_INT | portNVIC_SYSTICK_ENABLE;\r
464 }\r
465 /*-----------------------------------------------------------*/\r
466 \r
467 static void prvSetupMPU( void )\r
468 {\r
469 extern unsigned long __privileged_functions_end__[];\r
470 extern unsigned long __FLASH_segment_start__[];\r
471 extern unsigned long __FLASH_segment_end__[];\r
472 extern unsigned long __privileged_data_start__[];\r
473 extern unsigned long __privileged_data_end__[];\r
474 \r
475         /* Check the expected MPU is present. */\r
476         if( *portMPU_TYPE == portEXPECTED_MPU_TYPE_VALUE )\r
477         {\r
478                 /* First setup the entire flash for unprivileged read only access. */\r
479         *portMPU_REGION_BASE_ADDRESS =  ( ( unsigned long ) __FLASH_segment_start__ ) | /* Base address. */\r
480                                                                                 ( portMPU_REGION_VALID ) |\r
481                                                                                 ( portUNPRIVILEGED_FLASH_REGION );\r
482 \r
483                 *portMPU_REGION_ATTRIBUTE =             ( portMPU_REGION_READ_ONLY ) |\r
484                                                                                 ( portMPU_REGION_CACHEABLE_BUFFERABLE ) |\r
485                                                                                 ( prvGetMPURegionSizeSetting( ( unsigned long ) __FLASH_segment_end__ - ( unsigned long ) __FLASH_segment_start__ ) ) |\r
486                                                                                 ( portMPU_REGION_ENABLE );\r
487 \r
488                 /* Setup the first 16K for privileged only access (even though less\r
489                 than 10K is actually being used).  This is where the kernel code is\r
490                 placed. */\r
491         *portMPU_REGION_BASE_ADDRESS =  ( ( unsigned long ) __FLASH_segment_start__ ) | /* Base address. */\r
492                                                                                 ( portMPU_REGION_VALID ) |\r
493                                                                                 ( portPRIVILEGED_FLASH_REGION );\r
494 \r
495                 *portMPU_REGION_ATTRIBUTE =             ( portMPU_REGION_PRIVILEGED_READ_ONLY ) |\r
496                                                                                 ( portMPU_REGION_CACHEABLE_BUFFERABLE ) |\r
497                                                                                 ( prvGetMPURegionSizeSetting( ( unsigned long ) __privileged_functions_end__ - ( unsigned long ) __FLASH_segment_start__ ) ) |\r
498                                                                                 ( portMPU_REGION_ENABLE );\r
499 \r
500                 /* Setup the privileged data RAM region.  This is where the kernel data\r
501                 is placed. */\r
502                 *portMPU_REGION_BASE_ADDRESS =  ( ( unsigned long ) __privileged_data_start__ ) | /* Base address. */\r
503                                                                                 ( portMPU_REGION_VALID ) |\r
504                                                                                 ( portPRIVILEGED_RAM_REGION );\r
505 \r
506                 *portMPU_REGION_ATTRIBUTE =             ( portMPU_REGION_PRIVILEGED_READ_WRITE ) |\r
507                                                                                 ( portMPU_REGION_CACHEABLE_BUFFERABLE ) |\r
508                                                                                 prvGetMPURegionSizeSetting( ( unsigned long ) __privileged_data_end__ - ( unsigned long ) __privileged_data_start__ ) |\r
509                                                                                 ( portMPU_REGION_ENABLE );\r
510 \r
511                 /* By default allow everything to access the general peripherals.  The\r
512                 system peripherals and registers are protected. */\r
513                 *portMPU_REGION_BASE_ADDRESS =  ( portPERIPHERALS_START_ADDRESS ) |\r
514                                                                                 ( portMPU_REGION_VALID ) |\r
515                                                                                 ( portGENERAL_PERIPHERALS_REGION );\r
516 \r
517                 *portMPU_REGION_ATTRIBUTE =             ( portMPU_REGION_READ_WRITE | portMPU_REGION_EXECUTE_NEVER ) |\r
518                                                                                 ( prvGetMPURegionSizeSetting( portPERIPHERALS_END_ADDRESS - portPERIPHERALS_START_ADDRESS ) ) |\r
519                                                                                 ( portMPU_REGION_ENABLE );\r
520 \r
521                 /* Enable the memory fault exception. */\r
522                 *portNVIC_SYS_CTRL_STATE |= portNVIC_MEM_FAULT_ENABLE;\r
523 \r
524                 /* Enable the MPU with the background region configured. */\r
525                 *portMPU_CTRL |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE );\r
526         }\r
527 }\r
528 /*-----------------------------------------------------------*/\r
529 \r
530 static unsigned long prvGetMPURegionSizeSetting( unsigned long ulActualSizeInBytes )\r
531 {\r
532 unsigned long ulRegionSize, ulReturnValue = 4;\r
533 \r
534         /* 32 is the smallest region size, 31 is the largest valid value for\r
535         ulReturnValue. */\r
536         for( ulRegionSize = 32UL; ulReturnValue < 31UL; ( ulRegionSize <<= 1UL ) )\r
537         {\r
538                 if( ulActualSizeInBytes <= ulRegionSize )\r
539                 {\r
540                         break;\r
541                 }\r
542                 else\r
543                 {\r
544                         ulReturnValue++;\r
545                 }\r
546         }\r
547 \r
548         /* Shift the code by one before returning so it can be written directly\r
549         into the the correct bit position of the attribute register. */\r
550         return ( ulReturnValue << 1UL );\r
551 }\r
552 /*-----------------------------------------------------------*/\r
553 \r
554 static portBASE_TYPE prvRaisePrivilege( void )\r
555 {\r
556         __asm volatile\r
557         (\r
558                 "       mrs r0, control                                         \n"\r
559                 "       tst r0, #1                                                      \n" /* Is the task running privileged? */\r
560                 "       itte ne                                                         \n"\r
561                 "       movne r0, #0                                            \n" /* CONTROL[0]!=0, return false. */\r
562                 "       svcne %0                                                        \n" /* Switch to privileged. */\r
563                 "       moveq r0, #1                                            \n" /* CONTROL[0]==0, return true. */\r
564                 "       bx lr                                                           \n"\r
565                 :: "i" (portSVC_RAISE_PRIVILEGE) : "r0"\r
566         );\r
567 \r
568         return 0;\r
569 }\r
570 /*-----------------------------------------------------------*/\r
571 \r
572 void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMORY_REGION * const xRegions, portSTACK_TYPE *pxBottomOfStack, unsigned short usStackDepth )\r
573 {\r
574 extern unsigned long __SRAM_segment_start__[];\r
575 extern unsigned long __SRAM_segment_end__[];\r
576 extern unsigned long __privileged_data_start__[];\r
577 extern unsigned long __privileged_data_end__[];\r
578 long lIndex;\r
579 unsigned long ul;\r
580 \r
581         if( xRegions == NULL )\r
582         {\r
583                 /* No MPU regions are specified so allow access to all RAM. */\r
584         xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =\r
585                                 ( ( unsigned long ) __SRAM_segment_start__ ) | /* Base address. */\r
586                                 ( portMPU_REGION_VALID ) |\r
587                                 ( portSTACK_REGION );\r
588 \r
589                 xMPUSettings->xRegion[ 0 ].ulRegionAttribute =\r
590                                 ( portMPU_REGION_READ_WRITE ) |\r
591                                 ( portMPU_REGION_CACHEABLE_BUFFERABLE ) |\r
592                                 ( prvGetMPURegionSizeSetting( ( unsigned long ) __SRAM_segment_end__ - ( unsigned long ) __SRAM_segment_start__ ) ) |\r
593                                 ( portMPU_REGION_ENABLE );\r
594 \r
595                 /* Re-instate the privileged only RAM region as xRegion[ 0 ] will have\r
596                 just removed the privileged only parameters. */\r
597                 xMPUSettings->xRegion[ 1 ].ulRegionBaseAddress =\r
598                                 ( ( unsigned long ) __privileged_data_start__ ) | /* Base address. */\r
599                                 ( portMPU_REGION_VALID ) |\r
600                                 ( portSTACK_REGION + 1 );\r
601 \r
602                 xMPUSettings->xRegion[ 1 ].ulRegionAttribute =\r
603                                 ( portMPU_REGION_PRIVILEGED_READ_WRITE ) |\r
604                                 ( portMPU_REGION_CACHEABLE_BUFFERABLE ) |\r
605                                 prvGetMPURegionSizeSetting( ( unsigned long ) __privileged_data_end__ - ( unsigned long ) __privileged_data_start__ ) |\r
606                                 ( portMPU_REGION_ENABLE );\r
607 \r
608                 /* Invalidate all other regions. */\r
609                 for( ul = 2; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ )\r
610                 {\r
611                         xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID;\r
612                         xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL;\r
613                 }\r
614         }\r
615         else\r
616         {\r
617                 /* This function is called automatically when the task is created - in\r
618                 which case the stack region parameters will be valid.  At all other\r
619                 times the stack parameters will not be valid and it is assumed that the\r
620                 stack region has already been configured. */\r
621                 if( usStackDepth > 0 )\r
622                 {\r
623                         /* Define the region that allows access to the stack. */\r
624                         xMPUSettings->xRegion[ 0 ].ulRegionBaseAddress =\r
625                                         ( ( unsigned long ) pxBottomOfStack ) |\r
626                                         ( portMPU_REGION_VALID ) |\r
627                                         ( portSTACK_REGION ); /* Region number. */\r
628 \r
629                         xMPUSettings->xRegion[ 0 ].ulRegionAttribute =\r
630                                         ( portMPU_REGION_READ_WRITE ) | /* Read and write. */\r
631                                         ( prvGetMPURegionSizeSetting( ( unsigned long ) usStackDepth * ( unsigned long ) sizeof( portSTACK_TYPE ) ) ) |\r
632                                         ( portMPU_REGION_CACHEABLE_BUFFERABLE ) |\r
633                                         ( portMPU_REGION_ENABLE );\r
634                 }\r
635 \r
636                 lIndex = 0;\r
637 \r
638                 for( ul = 1; ul <= portNUM_CONFIGURABLE_REGIONS; ul++ )\r
639                 {\r
640                         if( ( xRegions[ lIndex ] ).ulLengthInBytes > 0UL )\r
641                         {\r
642                                 /* Translate the generic region definition contained in\r
643                                 xRegions into the CM3 specific MPU settings that are then\r
644                                 stored in xMPUSettings. */\r
645                                 xMPUSettings->xRegion[ ul ].ulRegionBaseAddress =\r
646                                                 ( ( unsigned long ) xRegions[ lIndex ].pvBaseAddress ) |\r
647                                                 ( portMPU_REGION_VALID ) |\r
648                                                 ( portSTACK_REGION + ul ); /* Region number. */\r
649 \r
650                                 xMPUSettings->xRegion[ ul ].ulRegionAttribute =\r
651                                                 ( prvGetMPURegionSizeSetting( xRegions[ lIndex ].ulLengthInBytes ) ) |\r
652                                                 ( xRegions[ lIndex ].ulParameters ) |\r
653                                                 ( portMPU_REGION_ENABLE );\r
654                         }\r
655                         else\r
656                         {\r
657                                 /* Invalidate the region. */\r
658                                 xMPUSettings->xRegion[ ul ].ulRegionBaseAddress = ( portSTACK_REGION + ul ) | portMPU_REGION_VALID;\r
659                                 xMPUSettings->xRegion[ ul ].ulRegionAttribute = 0UL;\r
660                         }\r
661 \r
662                         lIndex++;\r
663                 }\r
664         }\r
665 }\r
666 /*-----------------------------------------------------------*/\r
667 \r
668 signed portBASE_TYPE MPU_xTaskGenericCreate( pdTASK_CODE pvTaskCode, const signed char * const pcName, unsigned short usStackDepth, void *pvParameters, unsigned portBASE_TYPE uxPriority, xTaskHandle *pxCreatedTask, portSTACK_TYPE *puxStackBuffer, const xMemoryRegion * const xRegions )\r
669 {\r
670 signed portBASE_TYPE xReturn;\r
671 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
672 \r
673         xReturn = xTaskGenericCreate( pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pxCreatedTask, puxStackBuffer, xRegions );\r
674         portRESET_PRIVILEGE( xRunningPrivileged );\r
675         return xReturn;\r
676 }\r
677 /*-----------------------------------------------------------*/\r
678 \r
679 void MPU_vTaskAllocateMPURegions( xTaskHandle xTask, const xMemoryRegion * const xRegions )\r
680 {\r
681 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
682 \r
683         vTaskAllocateMPURegions( xTask, xRegions );\r
684         portRESET_PRIVILEGE( xRunningPrivileged );\r
685 }\r
686 /*-----------------------------------------------------------*/\r
687 \r
688 #if ( INCLUDE_vTaskDelete == 1 )\r
689         void MPU_vTaskDelete( xTaskHandle pxTaskToDelete )\r
690         {\r
691     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
692 \r
693                 vTaskDelete( pxTaskToDelete );\r
694         portRESET_PRIVILEGE( xRunningPrivileged );\r
695         }\r
696 #endif\r
697 /*-----------------------------------------------------------*/\r
698 \r
699 #if ( INCLUDE_vTaskDelayUntil == 1 )\r
700         void MPU_vTaskDelayUntil( portTickType * const pxPreviousWakeTime, portTickType xTimeIncrement )\r
701         {\r
702     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
703 \r
704                 vTaskDelayUntil( pxPreviousWakeTime, xTimeIncrement );\r
705         portRESET_PRIVILEGE( xRunningPrivileged );\r
706         }\r
707 #endif\r
708 /*-----------------------------------------------------------*/\r
709 \r
710 #if ( INCLUDE_vTaskDelay == 1 )\r
711         void MPU_vTaskDelay( portTickType xTicksToDelay )\r
712         {\r
713     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
714 \r
715                 vTaskDelay( xTicksToDelay );\r
716         portRESET_PRIVILEGE( xRunningPrivileged );\r
717         }\r
718 #endif\r
719 /*-----------------------------------------------------------*/\r
720 \r
721 #if ( INCLUDE_uxTaskPriorityGet == 1 )\r
722         unsigned portBASE_TYPE MPU_uxTaskPriorityGet( xTaskHandle pxTask )\r
723         {\r
724         unsigned portBASE_TYPE uxReturn;\r
725     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
726 \r
727                 uxReturn = uxTaskPriorityGet( pxTask );\r
728         portRESET_PRIVILEGE( xRunningPrivileged );\r
729                 return uxReturn;\r
730         }\r
731 #endif\r
732 /*-----------------------------------------------------------*/\r
733 \r
734 #if ( INCLUDE_vTaskPrioritySet == 1 )\r
735         void MPU_vTaskPrioritySet( xTaskHandle pxTask, unsigned portBASE_TYPE uxNewPriority )\r
736         {\r
737     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
738 \r
739                 vTaskPrioritySet( pxTask, uxNewPriority );\r
740         portRESET_PRIVILEGE( xRunningPrivileged );\r
741         }\r
742 #endif\r
743 /*-----------------------------------------------------------*/\r
744 \r
745 #if ( INCLUDE_eTaskGetState == 1 )\r
746         eTaskState MPU_eTaskGetState( xTaskHandle pxTask )\r
747         {\r
748     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
749         eTaskState eReturn;\r
750 \r
751                 eReturn = eTaskGetState( pxTask );\r
752         portRESET_PRIVILEGE( xRunningPrivileged );\r
753                 return eReturn;\r
754         }\r
755 #endif\r
756 /*-----------------------------------------------------------*/\r
757 \r
758 #if ( INCLUDE_xTaskGetIdleTaskHandle == 1 )\r
759         xTaskHandle MPU_xTaskGetIdleTaskHandle( void )\r
760         {\r
761         xTaskHandle xReturn;\r
762     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
763 \r
764                 xReturn = xTaskGetIdleTaskHandle();\r
765         portRESET_PRIVILEGE( xRunningPrivileged );\r
766                 return eReturn;\r
767         }\r
768 #endif\r
769 /*-----------------------------------------------------------*/\r
770 \r
771 #if ( INCLUDE_vTaskSuspend == 1 )\r
772         void MPU_vTaskSuspend( xTaskHandle pxTaskToSuspend )\r
773         {\r
774     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
775 \r
776                 vTaskSuspend( pxTaskToSuspend );\r
777         portRESET_PRIVILEGE( xRunningPrivileged );\r
778         }\r
779 #endif\r
780 /*-----------------------------------------------------------*/\r
781 \r
782 #if ( INCLUDE_vTaskSuspend == 1 )\r
783         signed portBASE_TYPE MPU_xTaskIsTaskSuspended( xTaskHandle xTask )\r
784         {\r
785         signed portBASE_TYPE xReturn;\r
786     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
787 \r
788                 xReturn = xTaskIsTaskSuspended( xTask );\r
789         portRESET_PRIVILEGE( xRunningPrivileged );\r
790                 return xReturn;\r
791         }\r
792 #endif\r
793 /*-----------------------------------------------------------*/\r
794 \r
795 #if ( INCLUDE_vTaskSuspend == 1 )\r
796         void MPU_vTaskResume( xTaskHandle pxTaskToResume )\r
797         {\r
798     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
799 \r
800                 vTaskResume( pxTaskToResume );\r
801         portRESET_PRIVILEGE( xRunningPrivileged );\r
802         }\r
803 #endif\r
804 /*-----------------------------------------------------------*/\r
805 \r
806 void MPU_vTaskSuspendAll( void )\r
807 {\r
808 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
809 \r
810         vTaskSuspendAll();\r
811     portRESET_PRIVILEGE( xRunningPrivileged );\r
812 }\r
813 /*-----------------------------------------------------------*/\r
814 \r
815 signed portBASE_TYPE MPU_xTaskResumeAll( void )\r
816 {\r
817 signed portBASE_TYPE xReturn;\r
818 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
819 \r
820         xReturn = xTaskResumeAll();\r
821     portRESET_PRIVILEGE( xRunningPrivileged );\r
822     return xReturn;\r
823 }\r
824 /*-----------------------------------------------------------*/\r
825 \r
826 portTickType MPU_xTaskGetTickCount( void )\r
827 {\r
828 portTickType xReturn;\r
829 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
830 \r
831         xReturn = xTaskGetTickCount();\r
832     portRESET_PRIVILEGE( xRunningPrivileged );\r
833         return xReturn;\r
834 }\r
835 /*-----------------------------------------------------------*/\r
836 \r
837 unsigned portBASE_TYPE MPU_uxTaskGetNumberOfTasks( void )\r
838 {\r
839 unsigned portBASE_TYPE uxReturn;\r
840 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
841 \r
842         uxReturn = uxTaskGetNumberOfTasks();\r
843     portRESET_PRIVILEGE( xRunningPrivileged );\r
844         return uxReturn;\r
845 }\r
846 /*-----------------------------------------------------------*/\r
847 \r
848 #if ( configUSE_TRACE_FACILITY == 1 )\r
849         void MPU_vTaskList( signed char *pcWriteBuffer )\r
850         {\r
851         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
852 \r
853                 vTaskList( pcWriteBuffer );\r
854                 portRESET_PRIVILEGE( xRunningPrivileged );\r
855         }\r
856 #endif\r
857 /*-----------------------------------------------------------*/\r
858 \r
859 #if ( configGENERATE_RUN_TIME_STATS == 1 )\r
860         void MPU_vTaskGetRunTimeStats( signed char *pcWriteBuffer )\r
861         {\r
862     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
863 \r
864                 vTaskGetRunTimeStats( pcWriteBuffer );\r
865         portRESET_PRIVILEGE( xRunningPrivileged );\r
866         }\r
867 #endif\r
868 /*-----------------------------------------------------------*/\r
869 \r
870 #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
871         void MPU_vTaskSetApplicationTaskTag( xTaskHandle xTask, pdTASK_HOOK_CODE pxTagValue )\r
872         {\r
873     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
874 \r
875                 vTaskSetApplicationTaskTag( xTask, pxTagValue );\r
876         portRESET_PRIVILEGE( xRunningPrivileged );\r
877         }\r
878 #endif\r
879 /*-----------------------------------------------------------*/\r
880 \r
881 #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
882         pdTASK_HOOK_CODE MPU_xTaskGetApplicationTaskTag( xTaskHandle xTask )\r
883         {\r
884         pdTASK_HOOK_CODE xReturn;\r
885     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
886 \r
887                 xReturn = xTaskGetApplicationTaskTag( xTask );\r
888         portRESET_PRIVILEGE( xRunningPrivileged );\r
889                 return xReturn;\r
890         }\r
891 #endif\r
892 /*-----------------------------------------------------------*/\r
893 \r
894 #if ( configUSE_APPLICATION_TASK_TAG == 1 )\r
895         portBASE_TYPE MPU_xTaskCallApplicationTaskHook( xTaskHandle xTask, void *pvParameter )\r
896         {\r
897         portBASE_TYPE xReturn;\r
898     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
899 \r
900                 xReturn = xTaskCallApplicationTaskHook( xTask, pvParameter );\r
901         portRESET_PRIVILEGE( xRunningPrivileged );\r
902                 return xReturn;\r
903         }\r
904 #endif\r
905 /*-----------------------------------------------------------*/\r
906 \r
907 #if ( INCLUDE_uxTaskGetStackHighWaterMark == 1 )\r
908         unsigned portBASE_TYPE MPU_uxTaskGetStackHighWaterMark( xTaskHandle xTask )\r
909         {\r
910         unsigned portBASE_TYPE uxReturn;\r
911     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
912 \r
913                 uxReturn = uxTaskGetStackHighWaterMark( xTask );\r
914         portRESET_PRIVILEGE( xRunningPrivileged );\r
915                 return uxReturn;\r
916         }\r
917 #endif\r
918 /*-----------------------------------------------------------*/\r
919 \r
920 #if ( INCLUDE_xTaskGetCurrentTaskHandle == 1 )\r
921         xTaskHandle MPU_xTaskGetCurrentTaskHandle( void )\r
922         {\r
923         xTaskHandle xReturn;\r
924     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
925 \r
926                 xReturn = xTaskGetCurrentTaskHandle();\r
927         portRESET_PRIVILEGE( xRunningPrivileged );\r
928                 return xReturn;\r
929         }\r
930 #endif\r
931 /*-----------------------------------------------------------*/\r
932 \r
933 #if ( INCLUDE_xTaskGetSchedulerState == 1 )\r
934         portBASE_TYPE MPU_xTaskGetSchedulerState( void )\r
935         {\r
936         portBASE_TYPE xReturn;\r
937     portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
938 \r
939                 xReturn = xTaskGetSchedulerState();\r
940         portRESET_PRIVILEGE( xRunningPrivileged );\r
941                 return xReturn;\r
942         }\r
943 #endif\r
944 /*-----------------------------------------------------------*/\r
945 \r
946 xQueueHandle MPU_xQueueGenericCreate( unsigned portBASE_TYPE uxQueueLength, unsigned portBASE_TYPE uxItemSize, unsigned char ucQueueType )\r
947 {\r
948 xQueueHandle xReturn;\r
949 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
950 \r
951         xReturn = xQueueGenericCreate( uxQueueLength, uxItemSize, ucQueueType );\r
952         portRESET_PRIVILEGE( xRunningPrivileged );\r
953         return xReturn;\r
954 }\r
955 /*-----------------------------------------------------------*/\r
956 \r
957 portBASE_TYPE MPU_xQueueGenericReset( xQueueHandle pxQueue, portBASE_TYPE xNewQueue )\r
958 {\r
959 portBASE_TYPE xReturn;\r
960 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
961 \r
962         xReturn = xQueueGenericReset( pxQueue, xNewQueue );\r
963         portRESET_PRIVILEGE( xRunningPrivileged );\r
964         return xReturn;\r
965 }\r
966 /*-----------------------------------------------------------*/\r
967 \r
968 signed portBASE_TYPE MPU_xQueueGenericSend( xQueueHandle xQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
969 {\r
970 signed portBASE_TYPE xReturn;\r
971 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
972 \r
973         xReturn = xQueueGenericSend( xQueue, pvItemToQueue, xTicksToWait, xCopyPosition );\r
974         portRESET_PRIVILEGE( xRunningPrivileged );\r
975         return xReturn;\r
976 }\r
977 /*-----------------------------------------------------------*/\r
978 \r
979 unsigned portBASE_TYPE MPU_uxQueueMessagesWaiting( const xQueueHandle pxQueue )\r
980 {\r
981 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
982 unsigned portBASE_TYPE uxReturn;\r
983 \r
984         uxReturn = uxQueueMessagesWaiting( pxQueue );\r
985         portRESET_PRIVILEGE( xRunningPrivileged );\r
986         return uxReturn;\r
987 }\r
988 /*-----------------------------------------------------------*/\r
989 \r
990 signed portBASE_TYPE MPU_xQueueGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
991 {\r
992 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
993 signed portBASE_TYPE xReturn;\r
994 \r
995         xReturn = xQueueGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking );\r
996         portRESET_PRIVILEGE( xRunningPrivileged );\r
997         return xReturn;\r
998 }\r
999 /*-----------------------------------------------------------*/\r
1000 \r
1001 #if ( configUSE_MUTEXES == 1 )\r
1002         xQueueHandle MPU_xQueueCreateMutex( void )\r
1003         {\r
1004     xQueueHandle xReturn;\r
1005         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1006 \r
1007                 xReturn = xQueueCreateMutex( queueQUEUE_TYPE_MUTEX );\r
1008                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1009                 return xReturn;\r
1010         }\r
1011 #endif\r
1012 /*-----------------------------------------------------------*/\r
1013 \r
1014 #if configUSE_COUNTING_SEMAPHORES == 1\r
1015         xQueueHandle MPU_xQueueCreateCountingSemaphore( unsigned portBASE_TYPE uxCountValue, unsigned portBASE_TYPE uxInitialCount )\r
1016         {\r
1017     xQueueHandle xReturn;\r
1018         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1019 \r
1020                 xReturn = xQueueCreateCountingSemaphore( uxCountValue, uxInitialCount );\r
1021                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1022                 return xReturn;\r
1023         }\r
1024 #endif\r
1025 /*-----------------------------------------------------------*/\r
1026 \r
1027 #if ( configUSE_MUTEXES == 1 )\r
1028         portBASE_TYPE MPU_xQueueTakeMutexRecursive( xQueueHandle xMutex, portTickType xBlockTime )\r
1029         {\r
1030         portBASE_TYPE xReturn;\r
1031         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1032 \r
1033                 xReturn = xQueueTakeMutexRecursive( xMutex, xBlockTime );\r
1034                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1035                 return xReturn;\r
1036         }\r
1037 #endif\r
1038 /*-----------------------------------------------------------*/\r
1039 \r
1040 #if ( configUSE_MUTEXES == 1 )\r
1041         portBASE_TYPE MPU_xQueueGiveMutexRecursive( xQueueHandle xMutex )\r
1042         {\r
1043         portBASE_TYPE xReturn;\r
1044         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1045 \r
1046                 xReturn = xQueueGiveMutexRecursive( xMutex );\r
1047                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1048                 return xReturn;\r
1049         }\r
1050 #endif\r
1051 /*-----------------------------------------------------------*/\r
1052 \r
1053 #if ( configUSE_QUEUE_SETS == 1 )\r
1054         xQueueSetHandle MPU_xQueueCreateSet( unsigned portBASE_TYPE uxEventQueueLength )\r
1055         {\r
1056         xQueueSetHandle xReturn;\r
1057         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1058 \r
1059                 xReturn = xQueueCreateSet( uxEventQueueLength );\r
1060                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1061                 return xReturn;\r
1062         }\r
1063 #endif\r
1064 /*-----------------------------------------------------------*/\r
1065 \r
1066 #if ( configUSE_QUEUE_SETS == 1 )\r
1067         xQueueSetMemberHandle MPU_xQueueSelectFromSet( xQueueSetHandle xQueueSet, portTickType xBlockTimeTicks )\r
1068         {\r
1069         xQueueSetMemberHandle xReturn;\r
1070         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1071 \r
1072                 xReturn = xQueueSelectFromSet( xQueueSet, xBlockTimeTicks );\r
1073                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1074                 return xReturn;\r
1075         }\r
1076 #endif\r
1077 /*-----------------------------------------------------------*/\r
1078 \r
1079 #if ( configUSE_QUEUE_SETS == 1 )\r
1080         portBASE_TYPE MPU_xQueueAddToSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )\r
1081         {\r
1082         portBASE_TYPE xReturn;\r
1083         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1084 \r
1085                 xReturn = xQueueAddToSet( xQueueOrSemaphore, xQueueSet );\r
1086                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1087                 return xReturn;\r
1088         }\r
1089 #endif\r
1090 /*-----------------------------------------------------------*/\r
1091 \r
1092 #if ( configUSE_QUEUE_SETS == 1 )\r
1093         portBASE_TYPE MPU_xQueueRemoveFromSet( xQueueSetMemberHandle xQueueOrSemaphore, xQueueSetHandle xQueueSet )\r
1094         {\r
1095         portBASE_TYPE xReturn;\r
1096         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1097 \r
1098                 xReturn = xQueueRemoveFromSet( xQueueOrSemaphore, xQueueSet );\r
1099                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1100                 return xReturn;\r
1101         }\r
1102 #endif\r
1103 /*-----------------------------------------------------------*/\r
1104 \r
1105 #if configUSE_ALTERNATIVE_API == 1\r
1106         signed portBASE_TYPE MPU_xQueueAltGenericSend( xQueueHandle pxQueue, const void * const pvItemToQueue, portTickType xTicksToWait, portBASE_TYPE xCopyPosition )\r
1107         {\r
1108         signed portBASE_TYPE xReturn;\r
1109         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1110 \r
1111                 xReturn =       signed portBASE_TYPE xQueueAltGenericSend( pxQueue, pvItemToQueue, xTicksToWait, xCopyPosition );\r
1112                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1113                 return xReturn;\r
1114         }\r
1115 #endif\r
1116 /*-----------------------------------------------------------*/\r
1117 \r
1118 #if configUSE_ALTERNATIVE_API == 1\r
1119         signed portBASE_TYPE MPU_xQueueAltGenericReceive( xQueueHandle pxQueue, void * const pvBuffer, portTickType xTicksToWait, portBASE_TYPE xJustPeeking )\r
1120         {\r
1121     signed portBASE_TYPE xReturn;\r
1122         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1123 \r
1124                 xReturn = xQueueAltGenericReceive( pxQueue, pvBuffer, xTicksToWait, xJustPeeking );\r
1125                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1126                 return xReturn;\r
1127         }\r
1128 #endif\r
1129 /*-----------------------------------------------------------*/\r
1130 \r
1131 #if configQUEUE_REGISTRY_SIZE > 0\r
1132         void MPU_vQueueAddToRegistry( xQueueHandle xQueue, signed char *pcName )\r
1133         {\r
1134         portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1135 \r
1136                 vQueueAddToRegistry( xQueue, pcName );\r
1137 \r
1138                 portRESET_PRIVILEGE( xRunningPrivileged );\r
1139         }\r
1140 #endif\r
1141 /*-----------------------------------------------------------*/\r
1142 \r
1143 void MPU_vQueueDelete( xQueueHandle xQueue )\r
1144 {\r
1145 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1146 \r
1147         vQueueDelete( xQueue );\r
1148 \r
1149         portRESET_PRIVILEGE( xRunningPrivileged );\r
1150 }\r
1151 /*-----------------------------------------------------------*/\r
1152 \r
1153 void *MPU_pvPortMalloc( size_t xSize )\r
1154 {\r
1155 void *pvReturn;\r
1156 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1157 \r
1158         pvReturn = pvPortMalloc( xSize );\r
1159 \r
1160         portRESET_PRIVILEGE( xRunningPrivileged );\r
1161 \r
1162         return pvReturn;\r
1163 }\r
1164 /*-----------------------------------------------------------*/\r
1165 \r
1166 void MPU_vPortFree( void *pv )\r
1167 {\r
1168 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1169 \r
1170         vPortFree( pv );\r
1171 \r
1172         portRESET_PRIVILEGE( xRunningPrivileged );\r
1173 }\r
1174 /*-----------------------------------------------------------*/\r
1175 \r
1176 void MPU_vPortInitialiseBlocks( void )\r
1177 {\r
1178 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1179 \r
1180         vPortInitialiseBlocks();\r
1181 \r
1182         portRESET_PRIVILEGE( xRunningPrivileged );\r
1183 }\r
1184 /*-----------------------------------------------------------*/\r
1185 \r
1186 size_t MPU_xPortGetFreeHeapSize( void )\r
1187 {\r
1188 size_t xReturn;\r
1189 portBASE_TYPE xRunningPrivileged = prvRaisePrivilege();\r
1190 \r
1191         xReturn = xPortGetFreeHeapSize();\r
1192 \r
1193         portRESET_PRIVILEGE( xRunningPrivileged );\r
1194 \r
1195         return xReturn;\r
1196 }\r
1197 \r