Lines Matching full:the
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
11 * the Software, and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in all
15 * copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 * Implementation of functions defined in portable.h for the ARM CM4F port.
38 …#error This port can only be used when the project options are configured to enable hardware float…
44 /* Constants required to manipulate the core. Registers first... */
50 /* ...then bits in the registers. */
59 /* Constants used to detect a Cortex-M7 r0p1 core, which should use the ARM_CM7
69 /* Constants used to check the installation of the FreeRTOS interrupt handlers. */
74 /* Constants required to check the validity of an interrupt priority. */
84 /* Masks off all bits but the VECTACTIVE bits in the ICSR register. */
87 /* Constants required to manipulate the VFP. */
91 /* Constants required to set up the initial stack. */
95 /* The systick is a 24-bit counter. */
98 /* For strict compliance with the Cortex-M spec the task start address should
99 * have bit-0 clear, as it is loaded into the PC on exit from an ISR. */
102 /* A fiddle factor to estimate the number of SysTick counts that would have
103 * occurred while the SysTick counter is stopped during tickless idle
107 /* Let the user override the default SysTick clock rate. If defined by the
108 * user, this symbol must equal the SysTick clock rate when the CLK bit is 0 in the
112 /* Ensure the SysTick is clocked at the same frequency as the core. */
115 /* Select the option to clock SysTick not at the same frequency as the core. */
119 /* Let the user override the pre-loading of the initial LR with the address of
120 * prvTaskExitError() in case it messes up unwinding of the stack in the
129 * Setup the timer to generate the tick interrupts. The implementation in this
130 * file is weak to allow application writers to change the timer used to
131 * generate the tick interrupt.
148 * Function to enable the VFP.
159 /* Each task maintains its own interrupt status in the critical nesting
164 * The number of SysTick increments that make up one tick period.
171 * The maximum number of tick periods that can be suppressed is limited by the
172 * 24 bit resolution of the SysTick timer.
179 * Compensate for the CPU cycles that pass while the SysTick is stopped (low
187 * Used by the portASSERT_IF_INTERRUPT_PRIORITY_INVALID() macro to ensure
206 /* Simulate the stack frame as it would be created by a context switch in pxPortInitialiseStack()
209 /* Offset added to account for the way the MCU uses the stack on entry/exit in pxPortInitialiseStack()
243 * defined, then stop here so application writers can catch the error. */ in prvTaskExitError()
249 /* This file calls prvTaskExitError() after the scheduler has been in prvTaskExitError()
250 * started to remove a compiler warning about the function being defined in prvTaskExitError()
253 * volatile makes the compiler think the function could return and in prvTaskExitError()
263 " ldr r3, pxCurrentTCBConst2 \n" /* Restore the context. */ in vPortSVCHandler()
264 …" ldr r1, [r3] \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. … in vPortSVCHandler()
265 …" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack… in vPortSVCHandler()
266 …ia r0!, {r4-r11, r14} \n" /* Pop the registers that are not automatically saved on exceptio… in vPortSVCHandler()
267 " msr psp, r0 \n" /* Restore the task stack pointer. */ in vPortSVCHandler()
281 /* Start the first task. This also clears the bit that indicates the FPU is in prvPortStartFirstTask()
282 * in use in case the FPU was used before the scheduler was started - which in prvPortStartFirstTask()
283 * would otherwise result in the unnecessary leaving of space in the SVC stack in prvPortStartFirstTask()
286 " ldr r0, =0xE000ED08 \n" /* Use the NVIC offset register to locate the stack. */ in prvPortStartFirstTask()
289 " msr msp, r0 \n" /* Set the msp back to the start of the stack. */ in prvPortStartFirstTask()
290 …" mov r0, #0 \n" /* Clear the bit that indicates the FPU is in use, see comment above. … in prvPortStartFirstTask()
308 /* This port can be used on all revisions of the Cortex-M7 core other than in xPortStartScheduler()
309 * the r0p1 parts. r0p1 parts should use the port from the in xPortStartScheduler()
314 /* An application can install FreeRTOS interrupt handlers in one of the in xPortStartScheduler()
316 * 1. Direct Routing - Install the functions vPortSVCHandler and in xPortStartScheduler()
330 /* Validate that the application has correctly installed the FreeRTOS in xPortStartScheduler()
331 * handlers for SVCall and PendSV interrupts. We do not check the in xPortStartScheduler()
332 * installation of the SysTick handler because the application may in xPortStartScheduler()
333 * choose to drive the RTOS tick using a timer other than the SysTick in xPortStartScheduler()
334 * timer by overriding the weak function vPortSetupTimerInterrupt(). in xPortStartScheduler()
336 * Assertion failures here indicate incorrect installation of the in xPortStartScheduler()
337 * FreeRTOS handlers. For help installing the FreeRTOS handlers, see in xPortStartScheduler()
340 * Systems with a configurable address for the interrupt vector table in xPortStartScheduler()
342 * VTOR is not set correctly to point to the application's vector table. */ in xPortStartScheduler()
355 /* Determine the maximum priority from which ISR safe FreeRTOS API in xPortStartScheduler()
360 * Save the interrupt priority value that is about to be clobbered. */ in xPortStartScheduler()
363 /* Determine the number of priority bits available. First write to all in xPortStartScheduler()
367 /* Read the value back to see how many bits stuck. */ in xPortStartScheduler()
370 /* Use the same mask on the maximum system call priority. */ in xPortStartScheduler()
373 /* Check that the maximum system call priority is nonzero after in xPortStartScheduler()
374 * accounting for the number of priority bits supported by the in xPortStartScheduler()
375 * hardware. A priority of 0 is invalid because setting the BASEPRI in xPortStartScheduler()
381 /* Check that the bits not implemented in hardware are zero in in xPortStartScheduler()
385 /* Calculate the maximum acceptable priority group value for the number in xPortStartScheduler()
396 /* When the hardware implements 8 priority bits, there is no way for in xPortStartScheduler()
397 * the software to configure PRIGROUP to not have sub-priorities. As in xPortStartScheduler()
398 * a result, the least significant bit is always used for sub-priority in xPortStartScheduler()
404 * are at the same preemption priority. This may appear confusing as in xPortStartScheduler()
408 * to 4, this confusion does not happen and the behaviour remains the same. in xPortStartScheduler()
410 * The following assert ensures that the sub-priority bit in the in xPortStartScheduler()
411 * configMAX_SYSCALL_INTERRUPT_PRIORITY is clear to avoid the above mentioned in xPortStartScheduler()
421 /* Shift the priority group value back to its position within the AIRCR in xPortStartScheduler()
426 /* Restore the clobbered interrupt priority register to its original in xPortStartScheduler()
432 /* Make PendSV and SysTick the lowest priority interrupts, and make SVCall in xPortStartScheduler()
433 * the highest priority. */ in xPortStartScheduler()
438 /* Start the timer that generates the tick ISR. Interrupts are disabled in xPortStartScheduler()
442 /* Initialise the critical nesting count ready for the first task. */ in xPortStartScheduler()
445 /* Ensure the VFP is enabled - it should be anyway. */ in xPortStartScheduler()
451 /* Start the first task. */ in xPortStartScheduler()
454 /* Should never get here as the tasks will now be executing! Call the task in xPortStartScheduler()
456 * not being called in the case that the application writer overrides this in xPortStartScheduler()
458 * vTaskSwitchContext() so link time optimisation does not remove the in xPortStartScheduler()
481 /* This is not the interrupt safe version of the enter critical function so in vPortEnterCritical()
484 * the critical nesting count is 1 to protect against recursive calls if the in vPortEnterCritical()
514 " ldr r3, pxCurrentTCBConst \n" /* Get the location of the current TCB. */ in xPortPendSVHandler()
517 …" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, push hig… in xPortPendSVHandler()
521 " stmdb r0!, {r4-r11, r14} \n" /* Save the core registers. */ in xPortPendSVHandler()
522 …" str r0, [r2] \n" /* Save the new top of stack into the first member of … in xPortPendSVHandler()
534 …" ldr r1, [r3] \n" /* The first item in pxCurrentTCB is the task top of s… in xPortPendSVHandler()
537 " ldmia r0!, {r4-r11, r14} \n" /* Pop the core registers. */ in xPortPendSVHandler()
539 …" tst r14, #0x10 \n" /* Is the task using the FPU context? If so, pop the … in xPortPendSVHandler()
564 /* The SysTick runs at the lowest interrupt priority, so when this interrupt in xPortSysTickHandler()
566 * save and then restore the interrupt mask value as its value is already in xPortSysTickHandler()
571 /* Increment the RTOS tick. */ in xPortSysTickHandler()
577 * the PendSV interrupt. Pend the PendSV interrupt. */ in xPortSysTickHandler()
596 /* Make sure the SysTick reload value does not overflow the counter. */ in vPortSuppressTicksAndSleep()
602 /* Enter a critical section but don't use the taskENTER_CRITICAL() in vPortSuppressTicksAndSleep()
608 /* If a context switch is pending or a task is waiting for the scheduler in vPortSuppressTicksAndSleep()
609 * to be unsuspended then abandon the low power entry. */ in vPortSuppressTicksAndSleep()
612 /* Re-enable interrupts - see comments above the cpsid instruction in vPortSuppressTicksAndSleep()
618 /* Stop the SysTick momentarily. The time the SysTick is stopped for in vPortSuppressTicksAndSleep()
619 * is accounted for as best it can be, but using the tickless mode will in vPortSuppressTicksAndSleep()
620 * inevitably result in some tiny drift of the time maintained by the in vPortSuppressTicksAndSleep()
624 /* Use the SysTick current-value register to determine the number of in vPortSuppressTicksAndSleep()
625 * SysTick decrements remaining until the next tick interrupt. If the in vPortSuppressTicksAndSleep()
627 * ulTimerCountsForOneTick decrements remaining, not zero, because the in vPortSuppressTicksAndSleep()
628 * SysTick requests the interrupt when decrementing from 1 to 0. */ in vPortSuppressTicksAndSleep()
636 /* Calculate the reload value required to wait xExpectedIdleTime in vPortSuppressTicksAndSleep()
638 * way through the first tick period. But if the SysTick IRQ is now in vPortSuppressTicksAndSleep()
639 * pending, then clear the IRQ, suppressing the first tick, and correct in vPortSuppressTicksAndSleep()
640 * the reload value to reflect that the second tick period is already in vPortSuppressTicksAndSleep()
641 * underway. The expected idle time is always at least two ticks. */ in vPortSuppressTicksAndSleep()
655 /* Set the new reload value. */ in vPortSuppressTicksAndSleep()
658 /* Clear the SysTick count flag and set the count value back to in vPortSuppressTicksAndSleep()
668 * should not be executed again. However, the original expected idle in vPortSuppressTicksAndSleep()
682 /* Re-enable interrupts to allow the interrupt that brought the MCU in vPortSuppressTicksAndSleep()
684 * the cpsid instruction above. */ in vPortSuppressTicksAndSleep()
689 /* Disable interrupts again because the clock is about to be stopped in vPortSuppressTicksAndSleep()
690 * and interrupts that execute while the clock is stopped will increase in vPortSuppressTicksAndSleep()
691 * any slippage between the time maintained by the RTOS and calendar in vPortSuppressTicksAndSleep()
697 /* Disable the SysTick clock without reading the in vPortSuppressTicksAndSleep()
698 * portNVIC_SYSTICK_CTRL_REG register to ensure the in vPortSuppressTicksAndSleep()
700 * the time the SysTick is stopped for is accounted for as best it can in vPortSuppressTicksAndSleep()
701 * be, but using the tickless mode will inevitably result in some tiny in vPortSuppressTicksAndSleep()
702 * drift of the time maintained by the kernel with respect to calendar in vPortSuppressTicksAndSleep()
706 /* Determine whether the SysTick has already counted to zero. */ in vPortSuppressTicksAndSleep()
711 /* The tick interrupt ended the sleep (or is now pending), and in vPortSuppressTicksAndSleep()
713 * with whatever remains of the new tick period. */ in vPortSuppressTicksAndSleep()
717 * underflowed because the post sleep hook did something in vPortSuppressTicksAndSleep()
718 * that took too long or because the SysTick current-value register in vPortSuppressTicksAndSleep()
727 /* As the pending tick will be processed as soon as this in vPortSuppressTicksAndSleep()
728 * function exits, the tick value maintained by the tick is stepped in vPortSuppressTicksAndSleep()
729 * forward by one less than the time spent waiting. */ in vPortSuppressTicksAndSleep()
734 /* Something other than the tick interrupt ended the sleep. */ in vPortSuppressTicksAndSleep()
736 /* Use the SysTick current-value register to determine the in vPortSuppressTicksAndSleep()
737 * number of SysTick decrements remaining until the expected idle in vPortSuppressTicksAndSleep()
742 /* If the SysTick is not using the core clock, the current- in vPortSuppressTicksAndSleep()
743 * value register might still be zero here. In that case, the in vPortSuppressTicksAndSleep()
744 * SysTick didn't load from the reload register, and there are in vPortSuppressTicksAndSleep()
745 * ulReloadValue decrements remaining in the expected idle in vPortSuppressTicksAndSleep()
754 /* Work out how long the sleep lasted rounded to complete tick in vPortSuppressTicksAndSleep()
755 * periods (not the ulReload value which accounted for part in vPortSuppressTicksAndSleep()
759 /* How many complete tick periods passed while the processor in vPortSuppressTicksAndSleep()
763 /* The reload value is set to whatever fraction of a single tick in vPortSuppressTicksAndSleep()
770 * the SysTick is not using the core clock, temporarily configure it to in vPortSuppressTicksAndSleep()
771 * use the core clock. This configuration forces the SysTick to load in vPortSuppressTicksAndSleep()
772 * from portNVIC_SYSTICK_LOAD_REG immediately instead of at the next in vPortSuppressTicksAndSleep()
773 * cycle of the other clock. Then portNVIC_SYSTICK_LOAD_REG is ready in vPortSuppressTicksAndSleep()
774 * to receive the standard value immediately. */ in vPortSuppressTicksAndSleep()
783 /* The temporary usage of the core clock has served its purpose, in vPortSuppressTicksAndSleep()
784 * as described above. Resume usage of the other clock. */ in vPortSuppressTicksAndSleep()
789 /* The partial tick period already ended. Be sure the SysTick in vPortSuppressTicksAndSleep()
799 /* Step the tick to account for any tick periods that elapsed. */ in vPortSuppressTicksAndSleep()
811 * Setup the systick timer to generate the tick interrupts at the required
816 /* Calculate the constants required to configure the tick interrupt. */ in vPortSetupTimerInterrupt()
825 /* Stop and clear the SysTick. */ in vPortSetupTimerInterrupt()
829 /* Configure SysTick to interrupt at the requested rate. */ in vPortSetupTimerInterrupt()
840 " ldr.w r0, =0xE000ED88 \n" /* The FPU enable bits are in the CPACR. */ in vPortEnableVFP()
858 /* Obtain the number of the currently executing interrupt. */ in vPortValidateInterruptPriority()
861 /* Is the interrupt number a user defined interrupt? */ in vPortValidateInterruptPriority()
864 /* Look up the interrupt's priority. */ in vPortValidateInterruptPriority()
867 /* The following assertion will fail if a service routine (ISR) for in vPortValidateInterruptPriority()
875 * interrupt priorities, therefore the priority of the interrupt must in vPortValidateInterruptPriority()
879 * Interrupts that use the FreeRTOS API must not be left at their in vPortValidateInterruptPriority()
880 * default priority of zero as that is the highest possible priority, in vPortValidateInterruptPriority()
887 * The following links provide detailed information: in vPortValidateInterruptPriority()
893 /* Priority grouping: The interrupt controller (NVIC) allows the bits in vPortValidateInterruptPriority()
895 * define the interrupt's pre-emption priority bits and bits that define in vPortValidateInterruptPriority()
896 * the interrupt's sub-priority. For simplicity all bits must be defined in vPortValidateInterruptPriority()
897 * to be pre-emption priority bits. The following assertion will fail if in vPortValidateInterruptPriority()
898 * this is not the case (if some bits represent a sub-priority). in vPortValidateInterruptPriority()
900 * If the application only uses CMSIS libraries for interrupt in vPortValidateInterruptPriority()
901 * configuration then the correct setting can be achieved on all Cortex-M in vPortValidateInterruptPriority()
902 * devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the in vPortValidateInterruptPriority()