]> begriffs open source - freertos/blob - portable/GCC/STR75x/portISR.c
SMP version (#401)
[freertos] / portable / GCC / STR75x / portISR.c
1 /*
2  * FreeRTOS Kernel V202110.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  * 1 tab == 4 spaces!
26  */
27
28
29 /*-----------------------------------------------------------
30  * Components that can be compiled to either ARM or THUMB mode are
31  * contained in port.c  The ISR routines, which can only be compiled
32  * to ARM mode, are contained in this file.
33  *----------------------------------------------------------*/
34
35 /*
36 */
37
38 /* Scheduler includes. */
39 #include "FreeRTOS.h"
40 #include "task.h"
41
42 /* Constants required to handle critical sections. */
43 #define portNO_CRITICAL_NESTING         ( ( uint32_t ) 0 )
44
45 volatile uint32_t ulCriticalNesting = 9999UL;
46
47 /*-----------------------------------------------------------*/
48
49 /* 
50  * The scheduler can only be started from ARM mode, hence the inclusion of this
51  * function here.
52  */
53 void vPortISRStartFirstTask( void );
54 /*-----------------------------------------------------------*/
55
56 void vPortISRStartFirstTask( void )
57 {
58         /* Simply start the scheduler.  This is included here as it can only be
59         called from ARM mode. */
60         asm volatile (                                                                                                          \
61         "LDR            R0, =pxCurrentTCB                                                               \n\t"   \
62         "LDR            R0, [R0]                                                                                \n\t"   \
63         "LDR            LR, [R0]                                                                                \n\t"   \
64                                                                                                                                                 \
65         /* The critical nesting depth is the first item on the stack. */        \
66         /* Load it into the ulCriticalNesting variable. */                                      \
67         "LDR            R0, =ulCriticalNesting                                                  \n\t"   \
68         "LDMFD  LR!, {R1}                                                                                       \n\t"   \
69         "STR            R1, [R0]                                                                                \n\t"   \
70                                                                                                                                                 \
71         /* Get the SPSR from the stack. */                                                                      \
72         "LDMFD  LR!, {R0}                                                                                       \n\t"   \
73         "MSR            SPSR, R0                                                                                \n\t"   \
74                                                                                                                                                 \
75         /* Restore all system mode registers for the task. */                           \
76         "LDMFD  LR, {R0-R14}^                                                                           \n\t"   \
77         "NOP                                                                                                            \n\t"   \
78                                                                                                                                                 \
79         /* Restore the return address. */                                                                       \
80         "LDR            LR, [LR, #+60]                                                                  \n\t"   \
81                                                                                                                                                 \
82         /* And return - correcting the offset in the LR to obtain the */        \
83         /* correct address. */                                                                                          \
84         "SUBS PC, LR, #4                                                                                        \n\t"   \
85         );                                                                                                                                      
86 }
87 /*-----------------------------------------------------------*/
88
89 void vPortTickISR( void )
90 {
91         /* Increment the RTOS tick count, then look for the highest priority 
92         task that is ready to run. */
93         if( xTaskIncrementTick() != pdFALSE )
94         {       
95                 vTaskSwitchContext();
96         }
97                         
98         /* Ready for the next interrupt. */
99         TB_ClearITPendingBit( TB_IT_Update );   
100 }
101
102 /*-----------------------------------------------------------*/
103
104 /*
105  * The interrupt management utilities can only be called from ARM mode.  When
106  * THUMB_INTERWORK is defined the utilities are defined as functions here to
107  * ensure a switch to ARM mode.  When THUMB_INTERWORK is not defined then
108  * the utilities are defined as macros in portmacro.h - as per other ports.
109  */
110 #ifdef THUMB_INTERWORK
111
112         void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
113         void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
114
115         void vPortDisableInterruptsFromThumb( void )
116         {
117                 asm volatile ( 
118                         "STMDB  SP!, {R0}               \n\t"   /* Push R0.                                                                     */
119                         "MRS    R0, CPSR                \n\t"   /* Get CPSR.                                                            */
120                         "ORR    R0, R0, #0xC0   \n\t"   /* Disable IRQ, FIQ.                                            */
121                         "MSR    CPSR, R0                \n\t"   /* Write back modified value.                           */
122                         "LDMIA  SP!, {R0}               \n\t"   /* Pop R0.                                                                      */
123                         "BX             R14" );                                 /* Return back to thumb.                                        */
124         }
125                         
126         void vPortEnableInterruptsFromThumb( void )
127         {
128                 asm volatile ( 
129                         "STMDB  SP!, {R0}               \n\t"   /* Push R0.                                                                     */      
130                         "MRS    R0, CPSR                \n\t"   /* Get CPSR.                                                            */      
131                         "BIC    R0, R0, #0xC0   \n\t"   /* Enable IRQ, FIQ.                                                     */      
132                         "MSR    CPSR, R0                \n\t"   /* Write back modified value.                           */      
133                         "LDMIA  SP!, {R0}               \n\t"   /* Pop R0.                                                                      */
134                         "BX             R14" );                                 /* Return back to thumb.                                        */
135         }
136
137 #endif /* THUMB_INTERWORK */
138 /*-----------------------------------------------------------*/
139
140 void vPortEnterCritical( void )
141 {
142         /* Disable interrupts as per portDISABLE_INTERRUPTS();                                                  */
143         asm volatile ( 
144                 "STMDB  SP!, {R0}                       \n\t"   /* Push R0.                                                             */
145                 "MRS    R0, CPSR                        \n\t"   /* Get CPSR.                                                    */
146                 "ORR    R0, R0, #0xC0           \n\t"   /* Disable IRQ, FIQ.                                    */
147                 "MSR    CPSR, R0                        \n\t"   /* Write back modified value.                   */
148                 "LDMIA  SP!, {R0}" );                           /* Pop R0.                                                              */
149
150         /* Now interrupts are disabled ulCriticalNesting can be accessed 
151         directly.  Increment ulCriticalNesting to keep a count of how many times
152         portENTER_CRITICAL() has been called. */
153         ulCriticalNesting++;
154 }
155 /*-----------------------------------------------------------*/
156
157 void vPortExitCritical( void )
158 {
159         if( ulCriticalNesting > portNO_CRITICAL_NESTING )
160         {
161                 /* Decrement the nesting count as we are leaving a critical section. */
162                 ulCriticalNesting--;
163
164                 /* If the nesting level has reached zero then interrupts should be
165                 re-enabled. */
166                 if( ulCriticalNesting == portNO_CRITICAL_NESTING )
167                 {
168                         /* Enable interrupts as per portEXIT_CRITICAL().                                        */
169                         asm volatile ( 
170                                 "STMDB  SP!, {R0}               \n\t"   /* Push R0.                                             */      
171                                 "MRS    R0, CPSR                \n\t"   /* Get CPSR.                                    */      
172                                 "BIC    R0, R0, #0xC0   \n\t"   /* Enable IRQ, FIQ.                             */      
173                                 "MSR    CPSR, R0                \n\t"   /* Write back modified value.   */      
174                                 "LDMIA  SP!, {R0}" );                   /* Pop R0.                                              */
175                 }
176         }
177 }
178
179
180
181
182