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