Contiki-NG
startup_cc13xx_cc26xx_gcc.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28 * OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/**
31 * \addtogroup cc13xx-cc26xx-cpu
32 * @{
33 *
34 * \file
35 * Startup file for GCC for CC13xx/CC26xx.
36 */
37/*---------------------------------------------------------------------------*/
38/* Check if compiler is GNU Compiler. */
39#if !(defined(__GNUC__))
40#error "startup_cc13xx_cc26xx_gcc.c: Unsupported compiler!"
41#endif
42/*---------------------------------------------------------------------------*/
43#include <string.h>
44
45#include <ti/devices/DeviceFamily.h>
46#include DeviceFamily_constructPath(inc/hw_types.h)
47#include DeviceFamily_constructPath(driverlib/interrupt.h)
48#include DeviceFamily_constructPath(driverlib/setup.h)
49/*---------------------------------------------------------------------------*/
50/* Forward declaration of the default fault handlers. */
51void resetISR(void);
52static void nmiISR(void);
53static void faultISR(void);
54static void defaultHandler(void);
55static void busFaultHandler(void);
56/*---------------------------------------------------------------------------*/
57/*
58 * External declaration for the reset handler that is to be called when the
59 * processor is started.
60 */
61extern void _c_int00(void);
62
63/* The entry point for the application. */
64extern int main(void);
65/*---------------------------------------------------------------------------*/
66/* Linker variable that marks the top of stack. */
67extern unsigned long _stack_end;
68
69/*
70 * The vector table. Note that the proper constructs must be placed on this to
71 * ensure that it ends up at physical address 0x0000.0000.
72 */
73__attribute__((section(".resetVecs"))) __attribute__((used))
74static void(*const resetVectors[16])(void) =
75{
76 (void(*)(void))((uint32_t)&_stack_end),
77 /* The initial stack pointer */
78 resetISR, /* The reset handler */
79 nmiISR, /* The NMI handler */
80 faultISR, /* The hard fault handler */
81 defaultHandler, /* The MPU fault handler */
82 busFaultHandler, /* The bus fault handler */
83 defaultHandler, /* The usage fault handler */
84 0, /* Reserved */
85 0, /* Reserved */
86 0, /* Reserved */
87 0, /* Reserved */
88 defaultHandler, /* SVCall handler */
89 defaultHandler, /* Debug monitor handler */
90 0, /* Reserved */
91 defaultHandler, /* The PendSV handler */
92 defaultHandler /* The SysTick handler */
93};
94/*---------------------------------------------------------------------------*/
95/*
96 * The following are arrays of pointers to constructor functions that need to
97 * be called during startup to initialize global objects.
98 */
99extern void (*__init_array_start[])(void);
100extern void (*__init_array_end[])(void);
101
102/* The following global variable is required for C++ support. */
103void *__dso_handle = (void *)&__dso_handle;
104/*---------------------------------------------------------------------------*/
105/*
106 * The following are constructs created by the linker, indicating where the
107 * the "data" and "bss" segments reside in memory. The initializers for the
108 * for the "data" segment resides immediately following the "text" segment.
109 */
110extern uint32_t __bss_start__;
111extern uint32_t __bss_end__;
112extern uint32_t __data_load__;
113extern uint32_t __data_start__;
114extern uint32_t __data_end__;
115/*---------------------------------------------------------------------------*/
116/*
117 * \brief Entry point of the startup code.
118 *
119 * Initialize the .data and .bss sections, and call main.
120 */
121void
122localProgramStart(void)
123{
124 uint32_t *bs;
125 uint32_t *be;
126 uint32_t *dl;
127 uint32_t *ds;
128 uint32_t *de;
129 uint32_t count;
130 uint32_t i;
131
132 IntMasterDisable();
133
134 /* Final trim of device */
135 SetupTrimDevice();
136
137 /* initiailize .bss to zero */
138 bs = &__bss_start__;
139 be = &__bss_end__;
140 while(bs < be) {
141 *bs = 0;
142 bs++;
143 }
144
145 /* relocate the .data section */
146 dl = &__data_load__;
147 ds = &__data_start__;
148 de = &__data_end__;
149 if(dl != ds) {
150 while(ds < de) {
151 *ds = *dl;
152 dl++;
153 ds++;
154 }
155 }
156
157 /* Run any constructors */
158 count = (uint32_t)(__init_array_end - __init_array_start);
159 for(i = 0; i < count; i++) {
160 __init_array_start[i]();
161 }
162
163 /* Call the application's entry point. */
164 main();
165
166 /* If we ever return signal Error */
167 faultISR();
168}
169/*---------------------------------------------------------------------------*/
170/*
171 * \brief Reset ISR.
172 *
173 * This is the code that gets called when the processor first starts execution
174 * following a reset event. Only the absolutely necessary set is performed,
175 * after which the application supplied entry() routine is called. Any fancy
176 * actions (such as making decisions based on the reset cause register, and
177 * resetting the bits in that register) are left solely in the hands of the
178 * application.
179 */
180void __attribute__((naked))
181resetISR(void)
182{
183 __asm__ __volatile__
184 (
185 "movw r0, #:lower16:resetVectors \n"
186 "movt r0, #:upper16:resetVectors \n"
187 "ldr r0, [r0] \n"
188 "mov sp, r0 \n"
189 "bx %0 \n"
190 : /* output */
191 : /* input */
192 "r"(localProgramStart)
193 );
194}
195/*---------------------------------------------------------------------------*/
196/*
197 * \brief Non-Maskable Interrupt (NMI) ISR.
198 *
199 * This is the code that gets called when the processor receives a NMI. This
200 * simply enters an infinite loop, preserving the system state for examination
201 * by a debugger.
202 */
203static void
204nmiISR(void)
205{
206 /* Enter an infinite loop. */
207 for(;;) { /* hang */ }
208}
209/*---------------------------------------------------------------------------*/
210/*
211 * \brief Debug stack pointer.
212 * \param sp Stack pointer.
213 *
214 * Provide a view into the CPU state from the provided stack pointer.
215 */
216static void
217debugHardfault(uint32_t *sp)
218{
219 volatile uint32_t r0; /**< R0 register */
220 volatile uint32_t r1; /**< R1 register */
221 volatile uint32_t r2; /**< R2 register */
222 volatile uint32_t r3; /**< R3 register */
223 volatile uint32_t r12; /**< R12 register */
224 volatile uint32_t lr; /**< LR register */
225 volatile uint32_t pc; /**< PC register */
226 volatile uint32_t psr; /**< PSR register */
227
228 (void)(r0 = sp[0]);
229 (void)(r1 = sp[1]);
230 (void)(r2 = sp[2]);
231 (void)(r3 = sp[3]);
232 (void)(r12 = sp[4]);
233 (void)(lr = sp[5]);
234 (void)(pc = sp[6]);
235 (void)(psr = sp[7]);
236
237 /* Enter an infinite loop. */
238 for(;;) { /* hang */ }
239}
240/*---------------------------------------------------------------------------*/
241/*
242 * \brief CPU Fault ISR.
243 *
244 * This is the code that gets called when the processor receives a fault
245 * interrupt. Setup a call to debugStackPointer with the current stack pointer.
246 * The stack pointer in this case would be the CPU state which caused the CPU
247 * fault.
248 */
249static void
250faultISR(void)
251{
252 __asm__ __volatile__
253 (
254 "tst lr, #4 \n"
255 "ite eq \n"
256 "mrseq r0, msp \n"
257 "mrsne r0, psp \n"
258 "bx %0 \n"
259 : /* output */
260 : /* input */
261 "r"(debugHardfault)
262 );
263}
264/*---------------------------------------------------------------------------*/
265/* Dummy variable */
266volatile int x__;
267
268/*
269 * \brief Bus Fault Handler.
270 *
271 * This is the code that gets called when the processor receives an unexpected
272 * interrupt. This simply enters an infinite loop, preserving the system state
273 * for examination by a debugger.
274 */
275static void
276busFaultHandler(void)
277{
278 x__ = 0;
279
280 /* Enter an infinite loop. */
281 for(;;) { /* hang */ }
282}
283/*---------------------------------------------------------------------------*/
284/*
285 * \brief Default Handler.
286 *
287 * This is the code that gets called when the processor receives an unexpected
288 * interrupt. This simply enters an infinite loop, preserving the system state
289 * for examination by a debugger.
290 */
291static void
292defaultHandler(void)
293{
294 /* Enter an infinite loop. */
295 for(;;) { /* hang */ }
296}
297/*---------------------------------------------------------------------------*/
298/*
299 * \brief Finalize object function.
300 *
301 * This function is called by __libc_fini_array which gets called when exit()
302 * is called. In order to support exit(), an empty _fini() stub function is
303 * required.
304 */
305void
306_fini(void)
307{
308 /* Function body left empty intentionally */
309}
310/*---------------------------------------------------------------------------*/
311/** @} */
static void debugHardfault(uint32_t *sp)
static volatile uint64_t count
Num.
Definition: clock.c:50