]> begriffs open source - cmsis-freertos/blob - Source/portable/GCC/STR75x/portISR.c
Updated pack to FreeRTOS 10.4.4
[cmsis-freertos] / Source / portable / GCC / STR75x / portISR.c
1 /*
2  * FreeRTOS Kernel V10.4.4
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
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:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
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.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  *
27  */
28
29
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  *----------------------------------------------------------*/
35
36 /*
37 */
38
39 /* Scheduler includes. */
40 #include "FreeRTOS.h"
41 #include "task.h"
42
43 /* Constants required to handle critical sections. */
44 #define portNO_CRITICAL_NESTING         ( ( uint32_t ) 0 )
45
46 volatile uint32_t ulCriticalNesting = 9999UL;
47
48 /*-----------------------------------------------------------*/
49
50 /* 
51  * The scheduler can only be started from ARM mode, hence the inclusion of this
52  * function here.
53  */
54 void vPortISRStartFirstTask( void );
55 /*-----------------------------------------------------------*/
56
57 void vPortISRStartFirstTask( void )
58 {
59         /* Simply start the scheduler.  This is included here as it can only be
60         called from ARM mode. */
61         asm volatile (                                                                                                          \
62         "LDR            R0, =pxCurrentTCB                                                               \n\t"   \
63         "LDR            R0, [R0]                                                                                \n\t"   \
64         "LDR            LR, [R0]                                                                                \n\t"   \
65                                                                                                                                                 \
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"   \
70         "STR            R1, [R0]                                                                                \n\t"   \
71                                                                                                                                                 \
72         /* Get the SPSR from the stack. */                                                                      \
73         "LDMFD  LR!, {R0}                                                                                       \n\t"   \
74         "MSR            SPSR, R0                                                                                \n\t"   \
75                                                                                                                                                 \
76         /* Restore all system mode registers for the task. */                           \
77         "LDMFD  LR, {R0-R14}^                                                                           \n\t"   \
78         "NOP                                                                                                            \n\t"   \
79                                                                                                                                                 \
80         /* Restore the return address. */                                                                       \
81         "LDR            LR, [LR, #+60]                                                                  \n\t"   \
82                                                                                                                                                 \
83         /* And return - correcting the offset in the LR to obtain the */        \
84         /* correct address. */                                                                                          \
85         "SUBS PC, LR, #4                                                                                        \n\t"   \
86         );                                                                                                                                      
87 }
88 /*-----------------------------------------------------------*/
89
90 void vPortTickISR( void )
91 {
92         /* Increment the RTOS tick count, then look for the highest priority 
93         task that is ready to run. */
94         if( xTaskIncrementTick() != pdFALSE )
95         {       
96                 vTaskSwitchContext();
97         }
98                         
99         /* Ready for the next interrupt. */
100         TB_ClearITPendingBit( TB_IT_Update );   
101 }
102
103 /*-----------------------------------------------------------*/
104
105 /*
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.
110  */
111 #ifdef THUMB_INTERWORK
112
113         void vPortDisableInterruptsFromThumb( void ) __attribute__ ((naked));
114         void vPortEnableInterruptsFromThumb( void ) __attribute__ ((naked));
115
116         void vPortDisableInterruptsFromThumb( void )
117         {
118                 asm volatile ( 
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.                                        */
125         }
126                         
127         void vPortEnableInterruptsFromThumb( void )
128         {
129                 asm volatile ( 
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.                                        */
136         }
137
138 #endif /* THUMB_INTERWORK */
139 /*-----------------------------------------------------------*/
140
141 void vPortEnterCritical( void )
142 {
143         /* Disable interrupts as per portDISABLE_INTERRUPTS();                                                  */
144         asm volatile ( 
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.                                                              */
150
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. */
154         ulCriticalNesting++;
155 }
156 /*-----------------------------------------------------------*/
157
158 void vPortExitCritical( void )
159 {
160         if( ulCriticalNesting > portNO_CRITICAL_NESTING )
161         {
162                 /* Decrement the nesting count as we are leaving a critical section. */
163                 ulCriticalNesting--;
164
165                 /* If the nesting level has reached zero then interrupts should be
166                 re-enabled. */
167                 if( ulCriticalNesting == portNO_CRITICAL_NESTING )
168                 {
169                         /* Enable interrupts as per portEXIT_CRITICAL().                                        */
170                         asm volatile ( 
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.                                              */
176                 }
177         }
178 }
179
180
181
182
183