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