]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/ThirdParty/GCC/nrf52840-dk/port.c
Remove the FreeRTOS-IoT-Libraries from FreeRTOS-Plus as it was an old copy with a...
[freertos] / FreeRTOS / Source / portable / ThirdParty / GCC / nrf52840-dk / port.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  * Implementation of functions defined in portable.h for the ARM CM4F port.\r
31  *----------------------------------------------------------*/\r
32 \r
33 /* Scheduler includes. */\r
34 #include "FreeRTOS.h"\r
35 #include "task.h"\r
36 \r
37 /*\r
38  * Start first task is a separate function so it can be tested in isolation.\r
39  */\r
40 void vPortStartFirstTask( void ) __attribute__ (( naked ));\r
41 \r
42 /*\r
43  * Exception handlers.\r
44  */\r
45 void vPortSVCHandler( void ) __attribute__ (( naked ));\r
46 void xPortPendSVHandler( void ) __attribute__ (( naked ));\r
47 \r
48 \r
49 /*-----------------------------------------------------------*/\r
50 \r
51 void vPortStartFirstTask( void )\r
52 {\r
53     __asm volatile(\r
54 #if defined(__SES_ARM)\r
55                     " ldr r0, =_vectors \n"     /* Locate the stack using _vectors table. */\r
56 #else\r
57                     " ldr r0, =__isr_vector \n" /* Locate the stack using __isr_vector table. */\r
58 #endif\r
59                     " ldr r0, [r0]          \n"\r
60                     " msr msp, r0           \n" /* Set the msp back to the start of the stack. */\r
61                     " cpsie i               \n" /* Globally enable interrupts. */\r
62                     " cpsie f               \n"\r
63                     " dsb                   \n"\r
64                     " isb                   \n"\r
65 #ifdef SOFTDEVICE_PRESENT\r
66                     /* Block kernel interrupts only (PendSV) before calling SVC */\r
67                     " mov r0, %0            \n"\r
68                     " msr basepri, r0       \n"\r
69 #endif\r
70                     " svc 0                 \n" /* System call to start first task. */\r
71                     "                       \n"\r
72                     " .align 2              \n"\r
73 #ifdef SOFTDEVICE_PRESENT\r
74                     ::"i"(configKERNEL_INTERRUPT_PRIORITY  << (8 - configPRIO_BITS))\r
75 #endif\r
76                 );\r
77 }\r
78 \r
79 /*-----------------------------------------------------------*/\r
80 \r
81 void vPortSVCHandler( void )\r
82 {\r
83     __asm volatile (\r
84                     "   ldr r3, =pxCurrentTCB           \n" /* Restore the context. */\r
85                     "   ldr r1, [r3]                    \n" /* Use pxCurrentTCBConst to get the pxCurrentTCB address. */\r
86                     "   ldr r0, [r1]                    \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
87                     "   ldmia r0!, {r4-r11, r14}        \n" /* Pop the registers that are not automatically saved on exception entry and the critical nesting count. */\r
88                     "   msr psp, r0                     \n" /* Restore the task stack pointer. */\r
89                     "   isb                             \n"\r
90                     "   mov r0, #0                      \n"\r
91                     "   msr basepri, r0                 \n"\r
92                     "   bx r14                          \n"\r
93                     "                                   \n"\r
94                     "   .align 2                        \n"\r
95                 );\r
96 }\r
97 \r
98 /*-----------------------------------------------------------*/\r
99 \r
100 void xPortPendSVHandler( void )\r
101 {\r
102     /* This is a naked function. */\r
103 \r
104     __asm volatile\r
105     (\r
106     "   mrs r0, psp                         \n"\r
107     "   isb                                 \n"\r
108     "                                       \n"\r
109     "   ldr r3, =pxCurrentTCB               \n" /* Get the location of the current TCB. */\r
110     "   ldr r2, [r3]                        \n"\r
111     "                                       \n"\r
112     "   tst r14, #0x10                      \n" /* Is the task using the FPU context?  If so, push high vfp registers. */\r
113     "   it eq                               \n"\r
114     "   vstmdbeq r0!, {s16-s31}             \n"\r
115     "                                       \n"\r
116     "   stmdb r0!, {r4-r11, r14}            \n" /* Save the core registers. */\r
117     "                                       \n"\r
118     "   str r0, [r2]                        \n" /* Save the new top of stack into the first member of the TCB. */\r
119     "                                       \n"\r
120     "   stmdb sp!, {r3}                     \n"\r
121     "   mov r0, %0                          \n"\r
122     "   msr basepri, r0                     \n"\r
123     "   dsb                                 \n"\r
124     "   isb                                 \n"\r
125     "   bl vTaskSwitchContext               \n"\r
126     "   mov r0, #0                          \n"\r
127     "   msr basepri, r0                     \n"\r
128     "   ldmia sp!, {r3}                     \n"\r
129     "                                       \n"\r
130     "   ldr r1, [r3]                        \n" /* The first item in pxCurrentTCB is the task top of stack. */\r
131     "   ldr r0, [r1]                        \n"\r
132     "                                       \n"\r
133     "   ldmia r0!, {r4-r11, r14}            \n" /* Pop the core registers. */\r
134     "                                       \n"\r
135     "   tst r14, #0x10                      \n" /* Is the task using the FPU context?  If so, pop the high vfp registers too. */\r
136     "   it eq                               \n"\r
137     "   vldmiaeq r0!, {s16-s31}             \n"\r
138     "                                       \n"\r
139     "   msr psp, r0                         \n"\r
140     "   isb                                 \n"\r
141     "                                       \n"\r
142     "                                       \n"\r
143     "   bx r14                              \n"\r
144     "                                       \n"\r
145     "   .align 2                            \n"\r
146     ::"i"(configMAX_SYSCALL_INTERRUPT_PRIORITY  << (8 - configPRIO_BITS))\r
147     );\r
148 }\r