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