2 * FreeRTOS Kernel V10.6.2
3 * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5 * SPDX-License-Identifier: MIT
7 * Permission is hereby granted, free of charge, to any person obtaining a copy of
8 * this software and associated documentation files (the "Software"), to deal in
9 * the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
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
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 * https://www.FreeRTOS.org
25 * https://github.com/FreeRTOS
30 /*-----------------------------------------------------------
31 * Components that can be compiled to either ARM or THUMB mode are
32 * contained in port.c The ISR routines, which can only be compiled
33 * to ARM mode, are contained in this file.
34 *----------------------------------------------------------*/
39 /* Scheduler includes. */
43 /* Constants required to handle critical sections. */
44 #define portNO_CRITICAL_NESTING ( ( uint32_t ) 0 )
46 volatile uint32_t ulCriticalNesting = 9999UL;
48 /*-----------------------------------------------------------*/
51 * The scheduler can only be started from ARM mode, hence the inclusion of this
54 void vPortISRStartFirstTask( void );
55 /*-----------------------------------------------------------*/
57 void vPortISRStartFirstTask( void )
59 /* Simply start the scheduler. This is included here as it can only be
60 called from ARM mode. */
62 "LDR R0, =pxCurrentTCB \n\t" \
66 /* The critical nesting depth is the first item on the stack. */ \
67 /* Load it into the ulCriticalNesting variable. */ \
68 "LDR R0, =ulCriticalNesting \n\t" \
69 "LDMFD LR!, {R1} \n\t" \
72 /* Get the SPSR from the stack. */ \
73 "LDMFD LR!, {R0} \n\t" \
76 /* Restore all system mode registers for the task. */ \
77 "LDMFD LR, {R0-R14}^ \n\t" \
80 /* Restore the return address. */ \
81 "LDR LR, [LR, #+60] \n\t" \
83 /* And return - correcting the offset in the LR to obtain the */ \
84 /* correct address. */ \
85 "SUBS PC, LR, #4 \n\t" \
88 /*-----------------------------------------------------------*/
90 void vPortTickISR( void )
92 /* Increment the RTOS tick count, then look for the highest priority
93 task that is ready to run. */
94 if( xTaskIncrementTick() != pdFALSE )
99 /* Ready for the next interrupt. */
100 TB_ClearITPendingBit( TB_IT_Update );
103 /*-----------------------------------------------------------*/
106 * The interrupt management utilities can only be called from ARM mode. When
107 * THUMB_INTERWORK is defined the utilities are defined as functions here to
108 * ensure a switch to ARM mode. When THUMB_INTERWORK is not defined then
109 * the utilities are defined as macros in portmacro.h - as per other ports.
111 #ifdef THUMB_INTERWORK
113 void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
114 void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
116 void vPortDisableInterruptsFromThumb( void )
119 "STMDB SP!, {R0} \n\t" /* Push R0. */
120 "MRS R0, CPSR \n\t" /* Get CPSR. */
121 "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
122 "MSR CPSR, R0 \n\t" /* Write back modified value. */
123 "LDMIA SP!, {R0} \n\t" /* Pop R0. */
124 "BX R14" ); /* Return back to thumb. */
127 void vPortEnableInterruptsFromThumb( void )
130 "STMDB SP!, {R0} \n\t" /* Push R0. */
131 "MRS R0, CPSR \n\t" /* Get CPSR. */
132 "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
133 "MSR CPSR, R0 \n\t" /* Write back modified value. */
134 "LDMIA SP!, {R0} \n\t" /* Pop R0. */
135 "BX R14" ); /* Return back to thumb. */
138 #endif /* THUMB_INTERWORK */
139 /*-----------------------------------------------------------*/
141 void vPortEnterCritical( void )
143 /* Disable interrupts as per portDISABLE_INTERRUPTS(); */
145 "STMDB SP!, {R0} \n\t" /* Push R0. */
146 "MRS R0, CPSR \n\t" /* Get CPSR. */
147 "ORR R0, R0, #0xC0 \n\t" /* Disable IRQ, FIQ. */
148 "MSR CPSR, R0 \n\t" /* Write back modified value. */
149 "LDMIA SP!, {R0}" ); /* Pop R0. */
151 /* Now interrupts are disabled ulCriticalNesting can be accessed
152 directly. Increment ulCriticalNesting to keep a count of how many times
153 portENTER_CRITICAL() has been called. */
156 /*-----------------------------------------------------------*/
158 void vPortExitCritical( void )
160 if( ulCriticalNesting > portNO_CRITICAL_NESTING )
162 /* Decrement the nesting count as we are leaving a critical section. */
165 /* If the nesting level has reached zero then interrupts should be
167 if( ulCriticalNesting == portNO_CRITICAL_NESTING )
169 /* Enable interrupts as per portEXIT_CRITICAL(). */
171 "STMDB SP!, {R0} \n\t" /* Push R0. */
172 "MRS R0, CPSR \n\t" /* Get CPSR. */
173 "BIC R0, R0, #0xC0 \n\t" /* Enable IRQ, FIQ. */
174 "MSR CPSR, R0 \n\t" /* Write back modified value. */
175 "LDMIA SP!, {R0}" ); /* Pop R0. */