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