diff --git a/.editorconfig b/.editorconfig index b0e01b7..268f607 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,6 +12,7 @@ indent_style = space indent_size = 4 trim_trailing_whitespace = false +# for VS Code [*.json] indent_style = space indent_size = 4 diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 742a9d0..b680ab1 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -50,7 +50,7 @@ "ARCH_AT91SAM3X8E" ], "compilerPath": "/usr/bin/arm-none-eabi-gcc", - "cStandard": "c11", + "cStandard": "gnu11", "cppStandard": "gnu++14", "intelliSenseMode": "gcc-arm", "includePath": [ @@ -58,9 +58,9 @@ ], "compilerArgs": [ "-mcpu=at91sam3x8e", - "-marm", - "-nostdlib", + "-mthumb", "-nodefaultlibs", + "-nostartfiles", "-fno-builtin", "-fpack-struct", "-Wall", @@ -88,4 +88,4 @@ } ], "version": 4 -} \ No newline at end of file +} diff --git a/arch/at91sam3x8e/startup.c b/arch/at91sam3x8e/startup.c index c20f637..ea2d436 100644 --- a/arch/at91sam3x8e/startup.c +++ b/arch/at91sam3x8e/startup.c @@ -27,8 +27,8 @@ #include #include -#include #include +#include /* from flash.ld */ extern uint32_t _sfixed; /* fixed area start */ @@ -44,16 +44,21 @@ extern uint32_t _estack; /* stack end */ /* implementation in init/main.c */ void do_bootstrap(void); -void __isr_reset(void) +void isr_reset(void) { + uint32_t *src; + uint32_t *dest; + /* copy .data to sram */ - memmove( - &_etext, - &_srelocate, - (size_t)&_erelocate - (size_t)&_srelocate - ); - /* clear .bss */ - memset(&_szero, 0, (size_t)&_ezero - (size_t)&_szero); + dest = &_etext; + src = &_srelocate; + while (src < &_erelocate) + *dest++ = *src++; + + /** clear .bss */ + dest = &_szero; + while (dest <= &_ezero) + *dest++ = 0; /* start the Kernel */ do_bootstrap(); @@ -66,128 +71,127 @@ void __isr_reset(void) * Default ISR for unimplemented interrupts. * This will halt the system. */ -void __isr_stub(void) +void isr_stub(void) { while (1); } -__attribute__((weak, alias("__isr_stub"))) void __isr_nmi(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_hard_fault(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_mem_fault(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_bus_fault(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_usage_fault(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_svc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_debug_mon(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_pend_sv(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_sys_tick(void); +__weak __alias(isr_stub) void isr_nmi(void); +__weak __alias(isr_stub) void isr_hard_fault(void); +__weak __alias(isr_stub) void isr_mem_fault(void); +__weak __alias(isr_stub) void isr_bus_fault(void); +__weak __alias(isr_stub) void isr_usage_fault(void); +__weak __alias(isr_stub) void isr_svc(void); +__weak __alias(isr_stub) void isr_debug_mon(void); +__weak __alias(isr_stub) void isr_pend_sv(void); +__weak __alias(isr_stub) void isr_sys_tick(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_supc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_rstc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_rtc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_rtt(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_wdt(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_pmc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_efc0(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_efc1(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_uart(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_smc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_pioa(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_piob(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_pioc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_piod(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_usart0(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_usart1(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_usart2(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_usart3(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_hsmci(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_twi0(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_twi1(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_spi0(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_ssc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc0(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc1(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc2(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc3(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc4(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc5(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc6(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc7(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_tc8(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_pwm(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_adc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_dacc(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_dmac(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_uotghs(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_trng(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_emac(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_can0(void); -__attribute__((weak, alias("__isr_stub"))) void __isr_can1(void); +__weak __alias(isr_stub) void isr_supc(void); +__weak __alias(isr_stub) void isr_rstc(void); +__weak __alias(isr_stub) void isr_rtc(void); +__weak __alias(isr_stub) void isr_rtt(void); +__weak __alias(isr_stub) void isr_wdt(void); +__weak __alias(isr_stub) void isr_pmc(void); +__weak __alias(isr_stub) void isr_efc0(void); +__weak __alias(isr_stub) void isr_efc1(void); +__weak __alias(isr_stub) void isr_uart(void); +__weak __alias(isr_stub) void isr_smc(void); +__weak __alias(isr_stub) void isr_pioa(void); +__weak __alias(isr_stub) void isr_piob(void); +__weak __alias(isr_stub) void isr_pioc(void); +__weak __alias(isr_stub) void isr_piod(void); +__weak __alias(isr_stub) void isr_usart0(void); +__weak __alias(isr_stub) void isr_usart1(void); +__weak __alias(isr_stub) void isr_usart2(void); +__weak __alias(isr_stub) void isr_usart3(void); +__weak __alias(isr_stub) void isr_hsmci(void); +__weak __alias(isr_stub) void isr_twi0(void); +__weak __alias(isr_stub) void isr_twi1(void); +__weak __alias(isr_stub) void isr_spi0(void); +__weak __alias(isr_stub) void isr_ssc(void); +__weak __alias(isr_stub) void isr_tc0(void); +__weak __alias(isr_stub) void isr_tc1(void); +__weak __alias(isr_stub) void isr_tc2(void); +__weak __alias(isr_stub) void isr_tc3(void); +__weak __alias(isr_stub) void isr_tc4(void); +__weak __alias(isr_stub) void isr_tc5(void); +__weak __alias(isr_stub) void isr_tc6(void); +__weak __alias(isr_stub) void isr_tc7(void); +__weak __alias(isr_stub) void isr_tc8(void); +__weak __alias(isr_stub) void isr_pwm(void); +__weak __alias(isr_stub) void isr_adc(void); +__weak __alias(isr_stub) void isr_dacc(void); +__weak __alias(isr_stub) void isr_dmac(void); +__weak __alias(isr_stub) void isr_uotghs(void); +__weak __alias(isr_stub) void isr_trng(void); +__weak __alias(isr_stub) void isr_emac(void); +__weak __alias(isr_stub) void isr_can0(void); +__weak __alias(isr_stub) void isr_can1(void); -__attribute__((section(".vectors"))) -const void *exception_table[] = { +__section(.vectors) const void *exception_table[] = { &_estack, /* initial SP value (stack grows down) */ - &__isr_reset, /* reset vector */ + &isr_reset, /* reset vector */ NULL, /* reserved */ - &__isr_hard_fault, /* hard fault */ - &__isr_mem_fault, /* hemory management fault */ - &__isr_bus_fault, /* bus fault */ - &__isr_usage_fault, /* usage fault */ + &isr_hard_fault, /* hard fault */ + &isr_mem_fault, /* hemory management fault */ + &isr_bus_fault, /* bus fault */ + &isr_usage_fault, /* usage fault */ NULL, /* reserved */ NULL, /* reserved */ NULL, /* reserved */ NULL, /* reserved */ - &__isr_svc, /* SVC call (used for syscalls) */ - &__isr_debug_mon, /* reserved for debug */ + &isr_svc, /* SVC call (used for syscalls) */ + &isr_debug_mon, /* reserved for debug */ NULL, /* reserved */ - &__isr_pend_sv, /* PendSV */ - &__isr_sys_tick, /* SysTick (used by the scheduler) */ + &isr_pend_sv, /* PendSV */ + &isr_sys_tick, /* SysTick (used by the scheduler) */ /* * Ok I am REALLY tired of writing out mnemonics. * Just have a look at include/arch/at91sam3x8e.h for details. */ - &__isr_rstc, - &__isr_rtc, - &__isr_rtt, - &__isr_wdt, - &__isr_pmc, - &__isr_efc0, - &__isr_efc1, - &__isr_uart, - &__isr_smc, + &isr_rstc, + &isr_rtc, + &isr_rtt, + &isr_wdt, + &isr_pmc, + &isr_efc0, + &isr_efc1, + &isr_uart, + &isr_smc, NULL, /* reserved */ - &__isr_pioa, - &__isr_piob, - &__isr_pioc, - &__isr_piod, + &isr_pioa, + &isr_piob, + &isr_pioc, + &isr_piod, NULL, /* reserved */ NULL, /* reserved */ - &__isr_usart0, - &__isr_usart1, - &__isr_usart2, - &__isr_usart3, - &__isr_hsmci, - &__isr_twi0, - &__isr_twi1, - &__isr_spi0, + &isr_usart0, + &isr_usart1, + &isr_usart2, + &isr_usart3, + &isr_hsmci, + &isr_twi0, + &isr_twi1, + &isr_spi0, NULL, /* reserved */ - &__isr_ssc, - &__isr_tc0, - &__isr_tc1, - &__isr_tc2, - &__isr_tc3, - &__isr_tc4, - &__isr_tc5, - &__isr_tc6, - &__isr_tc7, - &__isr_tc8, - &__isr_pwm, - &__isr_adc, - &__isr_dacc, - &__isr_dmac, - &__isr_uotghs, - &__isr_trng, - &__isr_emac, - &__isr_can0, - &__isr_can1, + &isr_ssc, + &isr_tc0, + &isr_tc1, + &isr_tc2, + &isr_tc3, + &isr_tc4, + &isr_tc5, + &isr_tc6, + &isr_tc7, + &isr_tc8, + &isr_pwm, + &isr_adc, + &isr_dacc, + &isr_dmac, + &isr_uotghs, + &isr_trng, + &isr_emac, + &isr_can0, + &isr_can1, }; diff --git a/include/arch/at91sam3x8e/interrupt.h b/include/arch/at91sam3x8e/interrupt.h index 0cb58d8..27b291a 100644 --- a/include/arch/at91sam3x8e/interrupt.h +++ b/include/arch/at91sam3x8e/interrupt.h @@ -28,108 +28,108 @@ #pragma once /** Reset interrupt handler */ -void __isr_reset(void); +void isr_reset(void); /** Non-maskable interrupt handler */ -void __isr_nmi(void); +void isr_nmi(void); /** Hard fault inerrupt handler */ -void __isr_hard_fault(void); +void isr_hard_fault(void); /** Memory management fault interrupt handler */ -void __isr_mem_fault(void); +void isr_mem_fault(void); /** Bus fault interrupt handler */ -void __isr_bus_fault(void); +void isr_bus_fault(void); /** Usage fault (illegal instruction) interrupt handler */ -void __isr_usage_fault(void); +void isr_usage_fault(void); /** SVC interrupt handler */ -void __isr_svc(void); +void isr_svc(void); /** Debug handler (reserved) */ -void __isr_debug_mon(void); +void isr_debug_mon(void); /** Pending SV interrupt handler */ -void __isr_pend_sv(void); +void isr_pend_sv(void); /** SysTick interrupt handler */ -void __isr_sys_tick(void); +void isr_sys_tick(void); /** Supply Controller (0) interrupt handler */ -void __isr_supc(void); +void isr_supc(void); /** Reset Controller (1) interrupt handler */ -void __isr_rstc(void); +void isr_rstc(void); /** Real-time Clock (2) interrupt handler */ -void __isr_rtc(void); +void isr_rtc(void); /** Real-time Timer (3) interrupt handler */ -void __isr_rtt(void); +void isr_rtt(void); /** Watchdog Timer (4) interrupt handler */ -void __isr_wdt(void); +void isr_wdt(void); /** Power Management Controller (5) interrupt handdler */ -void __isr_pmc(void); +void isr_pmc(void); /** Embedded Flash Controller 0 (6) interrupt handler */ -void __isr_efc0(void); +void isr_efc0(void); /** Embedded Flash Controller 1 (7) interrupt handler */ -void __isr_efc1(void); +void isr_efc1(void); /** Universal Asynchronous Receiver Transmitter (8) interrupt handler */ -void __isr_uart(void); +void isr_uart(void); /** Static Memory Controller (9) interrupt handler */ -void __isr_smc(void); +void isr_smc(void); /** Parallel I/O Controller A (11) interrupt handler */ -void __isr_pioa(void); +void isr_pioa(void); /** Parallel I/O Controller B (12) interrupt handler */ -void __isr_piob(void); +void isr_piob(void); /** Parallel I/O Controller C (13) interrupt handler */ -void __isr_pioc(void); +void isr_pioc(void); /** Parallel I/O Controller D (14) interrupt handler */ -void __isr_piod(void); +void isr_piod(void); /** Universal Synchronous/Asynchronous Receiver Transmitter 0 (17) interrupt handler */ -void __isr_usart0(void); +void isr_usart0(void); /** Universal Synchronous/Asynchronous Receiver Transmitter 1 (18) interrupt handler */ -void __isr_usart1(void); +void isr_usart1(void); /** Universal Synchronous/Asynchronous Receiver Transmitter 2 (19) interrupt handler */ -void __isr_usart2(void); +void isr_usart2(void); /** Universal Synchronous/Asynchronous Receiver Transmitter 3 (20) interrupt handler */ -void __isr_usart3(void); +void isr_usart3(void); /** Multimedia Card Interface (21) interrupt handler */ -void __isr_hsmci(void); +void isr_hsmci(void); /** Two-Wire Interface 0 (22) interrupt handler */ -void __isr_twi0(void); +void isr_twi0(void); /** Two-Wire Interface 1 (23) interrupt handler */ -void __isr_twi1(void); +void isr_twi1(void); /** Serial Peripheral Interface 0 (24) interrupt handler */ -void __isr_spi0(void); +void isr_spi0(void); /** Synchronous Serial Controller (26) interrupt handler */ -void __isr_ssc(void); +void isr_ssc(void); /** Timer/Counter 0 (27) interrupt handler */ -void __isr_tc0(void); +void isr_tc0(void); /** Timer/Counter 1 (28) interrupt handler */ -void __isr_tc1(void); +void isr_tc1(void); /** Timer/Counter 2 (29) interrupt handler */ -void __isr_tc2(void); +void isr_tc2(void); /** Timer/Counter 3 (30) interrupt handler */ -void __isr_tc3(void); +void isr_tc3(void); /** Timer/Counter 4 (31) interrupt handler */ -void __isr_tc4(void); +void isr_tc4(void); /** Timer/Counter 5 (32) interrupt handler */ -void __isr_tc5(void); +void isr_tc5(void); /** Timer/Counter 6 (33) interrupt handler */ -void __isr_tc6(void); +void isr_tc6(void); /** Timer/Counter 7 (34) interrupt handler */ -void __isr_tc7(void); +void isr_tc7(void); /** Timer/Counter 8 (35) interrupt handler */ -void __isr_tc8(void); +void isr_tc8(void); /** Pulse Width Modulation Controller (36) interrupt handler */ -void __isr_pwm(void); +void isr_pwm(void); /** Analog to Digital Converter Controller (37) interrupt handler */ -void __isr_adc(void); +void isr_adc(void); /** Digital to Analog Converter Controller (38) interrupt handler */ -void __isr_dacc(void); +void isr_dacc(void); /** Direct Memory Access Controller (39) interrupt handler */ -void __isr_dmac(void); +void isr_dmac(void); /** USB OTG High Speed (40) interrupt handler */ -void __isr_uotghs(void); +void isr_uotghs(void); /** True Random Number Generator (41) interrupt handler */ -void __isr_trng(void); +void isr_trng(void); /** Ethernet MAC (42) interrupt handler */ -void __isr_emac(void); +void isr_emac(void); /** Controller Area Network 0 (43) interrupt handler */ -void __isr_can0(void); +void isr_can0(void); /** Controller Area Network 1 (44) interrupt handler */ -void __isr_can1(void); +void isr_can1(void); /** * Interrupt numbers for sam3x8e diff --git a/include/stddef.h b/include/stddef.h index c8d0b89..3dd02fd 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -46,11 +46,3 @@ #endif /* NULL */ #include - -#ifndef __always_inline -/** - * Force a method to always be inlined by the compiler. - * Do not use this for functions exceeding one or two lines. - */ -#define __always_inline inline __attribute__((always_inline)) -#endif /* __always_inline */ diff --git a/include/toolchain.h b/include/toolchain.h new file mode 100644 index 0000000..110921e --- /dev/null +++ b/include/toolchain.h @@ -0,0 +1,66 @@ +/* + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2020 Felix Kopp + * + * Redistribution and use in source and binary forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#ifndef __GNUC__ +#error "Only GCC is supported" +#endif /* __GNUC__ */ + +#ifndef __always_inline +/** + * Force a method to always be inlined by the compiler. + * Do not use this for functions exceeding one or two lines. + */ +#define __always_inline inline __attribute__((always_inline)) +#endif /* __always_inline */ + +#ifndef __weak +/** + * Add the `weak` attribute to a symbol. + * This allows that identifier to be re-declared without any warnings. + */ +#define __weak __attribute__((__weak__)) +#endif /* __weak */ + +#ifndef __alias +/** + * Declare an identifier as an alias for some other identifier. + * + * @param name: The identifier (w/out quotes) this should be an alias for. + */ +#define __alias(name) __attribute__((alias(#name))) +#endif /* __alias */ + +#ifndef __section +/** + * Define the program section this symbol should live in. + * + * @param name: The section name w/out quotes. + */ +#define __section(name) __attribute((section(#name))) +#endif /* __section */