From 7dfe7bd496d60f994f295fd8d2d02d539e636875 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Fri, 4 Aug 2017 21:01:10 +0200 Subject: [PATCH 1/4] guard avrInitSystemTickTimer with extern "C" --- ports/avr/atomport-private.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ports/avr/atomport-private.h b/ports/avr/atomport-private.h index 866f6b4..877535c 100644 --- a/ports/avr/atomport-private.h +++ b/ports/avr/atomport-private.h @@ -33,7 +33,15 @@ /* CPU Frequency */ #define AVR_CPU_HZ 1000000 +#ifdef __cplusplus +extern "C" { +#endif + /* Function prototypes */ void avrInitSystemTickTimer ( void ); +#ifdef __cplusplus +} +#endif + #endif /* __ATOM_PORT_PRIVATE_H */ From f9d5f0a10ccef59029a135779cbe3261224cbbb0 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Fri, 4 Aug 2017 21:02:44 +0200 Subject: [PATCH 2/4] use F_CPU for the AVR CPU frequency (if available) --- ports/avr/atomport-private.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ports/avr/atomport-private.h b/ports/avr/atomport-private.h index 877535c..70f91d1 100644 --- a/ports/avr/atomport-private.h +++ b/ports/avr/atomport-private.h @@ -31,7 +31,11 @@ #define __ATOM_PORT_PRIVATE_H /* CPU Frequency */ +#ifdef F_CPU +#define AVR_CPU_HZ F_CPU +#else #define AVR_CPU_HZ 1000000 +#endif #ifdef __cplusplus extern "C" { From 3f68de64b6b7d5fa7524b9b0eb5419e0b96d2d61 Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Fri, 4 Aug 2017 22:06:11 +0200 Subject: [PATCH 3/4] guard uart functions with extern "C" --- ports/avr/uart.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ports/avr/uart.h b/ports/avr/uart.h index 15c0370..69db35c 100644 --- a/ports/avr/uart.h +++ b/ports/avr/uart.h @@ -13,6 +13,9 @@ #include "atom.h" +#ifdef __cplusplus +extern "C" { +#endif /* * Perform UART startup initialization. @@ -23,3 +26,7 @@ int uart_init(uint32_t baudrate); * Send one character to the UART. */ int uart_putchar(char c, FILE *stream); + +#ifdef __cplusplus +} +#endif From 6eb64f441449feaa73d3ff3a829d808bbbdb28fa Mon Sep 17 00:00:00 2001 From: Jacques Germishuys Date: Sun, 20 Aug 2017 18:47:32 +0200 Subject: [PATCH 4/4] move AVR port's timers to a different translation unit this gives greater flexibility in terms of timer choices --- ports/avr/Makefile | 2 +- ports/avr/atomport-private.c | 90 ++++++++++++++++++++++++++++++++++++ ports/avr/atomport.c | 89 ----------------------------------- 3 files changed, 91 insertions(+), 90 deletions(-) create mode 100644 ports/avr/atomport-private.c diff --git a/ports/avr/Makefile b/ports/avr/Makefile index 6578ab1..2e1ac50 100644 --- a/ports/avr/Makefile +++ b/ports/avr/Makefile @@ -36,7 +36,7 @@ PART=atmega16 BUILD_DIR=build # Port/application object files -APP_OBJECTS = atomport.o uart.o tests-main.o +APP_OBJECTS = atomport.o atomport-private.o uart.o tests-main.o APP_ASM_OBJECTS = atomport-asm.o # Kernel object files diff --git a/ports/avr/atomport-private.c b/ports/avr/atomport-private.c new file mode 100644 index 0000000..d3a0c18 --- /dev/null +++ b/ports/avr/atomport-private.c @@ -0,0 +1,90 @@ +#include + +#include "atom.h" +#include "atomport-private.h" + +/** + * \b avrInitSystemTickTimer + * + * Initialise the system tick timer. Uses the AVR's timer1 facility. + * + * @return None + */ +void avrInitSystemTickTimer ( void ) +{ + /* Set timer 1 compare match value for configured system tick, + * with a prescaler of 256. We will get a compare match 1A + * interrupt on every system tick, in which we must call the + * OS's system tick handler. */ + OCR1A = (AVR_CPU_HZ / 256 / SYSTEM_TICKS_PER_SEC); + + /* Enable compare match 1A interrupt */ +#ifdef TIMSK + TIMSK = _BV(OCIE1A); +#else + TIMSK1 = _BV(OCIE1A); +#endif + + /* Set prescaler 256 */ + TCCR1B = _BV(CS12) | _BV(WGM12); +} + + +/** + * + * System tick ISR. + * + * This is responsible for regularly calling the OS system tick handler. + * The system tick handler checks if any timer callbacks are necessary, + * and runs the scheduler. + * + * The compiler automatically saves all registers necessary before calling + * out to a C routine. This will be (at least) R0, R1, SREG, R18-R27 and + * R30/R31. + * + * The system may decide to schedule in a new thread during the call to + * atomTimerTick(), in which case around half of the thread's context will + * already have been saved here, ready for when we return here when the + * interrupted thread is scheduled back in. The remaining context will be + * saved by the context switch routine. + * + * As with all interrupts, the ISR should call atomIntEnter() and + * atomIntExit() on entry and exit. This serves two purposes: + * + * a) To notify the OS that it is running in interrupt context + * b) To defer the scheduler until after the ISR is completed + * + * We defer all scheduling decisions until after the ISR has completed + * in case the interrupt handler makes more than one thread ready. + * + * @return None + */ +ISR (TIMER1_COMPA_vect) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the OS system tick handler */ + atomTimerTick(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + + +/** + * + * Default (no handler installed) ISR. + * + * Installs a default handler to be called if any interrupts occur for + * which we have not registered an ISR. This is empty and has only been + * included to handle user-created code which may enable interrupts. The + * core OS does not enable any interrupts other than the system timer + * tick interrupt. + * + * @return None + */ +ISR (BADISR_vect) +{ + /* Empty */ +} diff --git a/ports/avr/atomport.c b/ports/avr/atomport.c index 362e66d..a10f31d 100644 --- a/ports/avr/atomport.c +++ b/ports/avr/atomport.c @@ -28,10 +28,7 @@ */ -#include - #include "atom.h" -#include "atomport-private.h" /** Forward declarations */ @@ -268,89 +265,3 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_poi } - -/** - * \b avrInitSystemTickTimer - * - * Initialise the system tick timer. Uses the AVR's timer1 facility. - * - * @return None - */ -void avrInitSystemTickTimer ( void ) -{ - /* Set timer 1 compare match value for configured system tick, - * with a prescaler of 256. We will get a compare match 1A - * interrupt on every system tick, in which we must call the - * OS's system tick handler. */ - OCR1A = (AVR_CPU_HZ / 256 / SYSTEM_TICKS_PER_SEC); - - /* Enable compare match 1A interrupt */ -#ifdef TIMSK - TIMSK = _BV(OCIE1A); -#else - TIMSK1 = _BV(OCIE1A); -#endif - - /* Set prescaler 256 */ - TCCR1B = _BV(CS12) | _BV(WGM12); -} - - -/** - * - * System tick ISR. - * - * This is responsible for regularly calling the OS system tick handler. - * The system tick handler checks if any timer callbacks are necessary, - * and runs the scheduler. - * - * The compiler automatically saves all registers necessary before calling - * out to a C routine. This will be (at least) R0, R1, SREG, R18-R27 and - * R30/R31. - * - * The system may decide to schedule in a new thread during the call to - * atomTimerTick(), in which case around half of the thread's context will - * already have been saved here, ready for when we return here when the - * interrupted thread is scheduled back in. The remaining context will be - * saved by the context switch routine. - * - * As with all interrupts, the ISR should call atomIntEnter() and - * atomIntExit() on entry and exit. This serves two purposes: - * - * a) To notify the OS that it is running in interrupt context - * b) To defer the scheduler until after the ISR is completed - * - * We defer all scheduling decisions until after the ISR has completed - * in case the interrupt handler makes more than one thread ready. - * - * @return None - */ -ISR (TIMER1_COMPA_vect) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the OS system tick handler */ - atomTimerTick(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - - -/** - * - * Default (no handler installed) ISR. - * - * Installs a default handler to be called if any interrupts occur for - * which we have not registered an ISR. This is empty and has only been - * included to handle user-created code which may enable interrupts. The - * core OS does not enable any interrupts other than the system timer - * tick interrupt. - * - * @return None - */ -ISR (BADISR_vect) -{ - /* Empty */ -}