From 80b02e52682a5d37dd45d3ffc0db8e90774e88a0 Mon Sep 17 00:00:00 2001 From: Josarn Date: Wed, 25 Apr 2018 17:53:26 +0200 Subject: [PATCH 1/6] cpu/atmega_common: exit_isr thread_yield --- cpu/atmega_common/include/cpu.h | 26 ++++++++++++++++---------- cpu/atmega_common/periph/timer.c | 5 ----- cpu/atmega_common/periph/uart.c | 15 +++------------ cpu/atmega_common/thread_arch.c | 2 -- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/cpu/atmega_common/include/cpu.h b/cpu/atmega_common/include/cpu.h index 8cb114772afe..208b85b29224 100644 --- a/cpu/atmega_common/include/cpu.h +++ b/cpu/atmega_common/include/cpu.h @@ -35,7 +35,8 @@ #include #include "cpu_conf.h" - +#include "sched.h" +#include "thread.h" /** * For downwards compatibility with old RIOT code. * TODO: remove once core was adjusted @@ -52,7 +53,7 @@ extern "C" { extern volatile uint8_t __in_isr; /** - * @brief Flag entering of an ISR + * @brief Run this code on entering interrupt routines */ static inline void __enter_isr(void) { @@ -60,10 +61,22 @@ static inline void __enter_isr(void) } /** - * @brief Flag exiting of an ISR + * @brief Exit ISR mode and yield with a return from interrupt. Use at the + * end of ISRs in place of thread_yield_higher. If thread_yield is needed, use + * thread_yield followed by thread_yield_isr instead of thread_yield alone. + */ +void thread_yield_isr(void); + +/** + * @brief Run this code on exiting interrupt routines */ static inline void __exit_isr(void) { + if (sched_context_switch_request) { + thread_yield(); + __in_isr = 0; + thread_yield_isr(); + } __in_isr = 0; } @@ -128,13 +141,6 @@ static inline void atmega_set_prescaler(uint8_t clk_scale) */ void atmega_stdio_init(void); -/** - * @brief Exit ISR mode and yield with a return from interrupt. Use at the - * end of ISRs in place of thread_yield_higher. If thread_yield is needed, use - * thread_yield followed by thread_yield_isr instead of thread_yield alone. - */ -void thread_yield_isr(void); - #ifdef __cplusplus } #endif diff --git a/cpu/atmega_common/periph/timer.c b/cpu/atmega_common/periph/timer.c index 8572e83df5fb..b74daf691622 100644 --- a/cpu/atmega_common/periph/timer.c +++ b/cpu/atmega_common/periph/timer.c @@ -167,11 +167,6 @@ static inline void _isr(tim_t tim, int chan) *ctx[tim].mask &= ~(1 << (chan + OCIE1A)); ctx[tim].cb(ctx[tim].arg, chan); - if (sched_context_switch_request) { - thread_yield(); - thread_yield_isr(); - } - __exit_isr(); } #endif diff --git a/cpu/atmega_common/periph/uart.c b/cpu/atmega_common/periph/uart.c index 9f6b4ba7675e..c15c7dcd8b3e 100644 --- a/cpu/atmega_common/periph/uart.c +++ b/cpu/atmega_common/periph/uart.c @@ -160,46 +160,37 @@ void uart_poweroff(uart_t uart) static inline void isr_handler(int num) { + __enter_isr(); + isr_ctx[num].rx_cb(isr_ctx[num].arg, dev[num]->DR); - if (sched_context_switch_request) { - thread_yield(); - thread_yield_isr(); - } + __exit_isr(); } #ifdef UART_0_ISR ISR(UART_0_ISR, ISR_BLOCK) { - __enter_isr(); isr_handler(0); - __exit_isr(); } #endif /* UART_0_ISR */ #ifdef UART_1_ISR ISR(UART_1_ISR, ISR_BLOCK) { - __enter_isr(); isr_handler(1); - __exit_isr(); } #endif /* UART_1_ISR */ #ifdef UART_2_ISR ISR(UART_2_ISR, ISR_BLOCK) { - __enter_isr(); isr_handler(2); - __exit_isr(); } #endif /* UART_2_ISR */ #ifdef UART_3_ISR ISR(UART_3_ISR, ISR_BLOCK) { - __enter_isr(); isr_handler(3); - __exit_isr(); } #endif /* UART_3_ISR */ diff --git a/cpu/atmega_common/thread_arch.c b/cpu/atmega_common/thread_arch.c index d76995e4e1c6..180d32470046 100644 --- a/cpu/atmega_common/thread_arch.c +++ b/cpu/atmega_common/thread_arch.c @@ -236,8 +236,6 @@ void thread_yield_isr(void) { sched_run(); __context_restore(); - __exit_isr(); - __asm__ volatile("reti"); } From 9b631170cbfcc041451284330ad1e3c508e89f4e Mon Sep 17 00:00:00 2001 From: Josarn Date: Wed, 25 Apr 2018 17:54:00 +0200 Subject: [PATCH 2/6] cpu/atmega_common: uncrustified --- cpu/atmega_common/include/cpu.h | 12 ++++++------ cpu/atmega_common/thread_arch.c | 24 ++++++++++-------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/cpu/atmega_common/include/cpu.h b/cpu/atmega_common/include/cpu.h index 208b85b29224..d2a0d55bd5f6 100644 --- a/cpu/atmega_common/include/cpu.h +++ b/cpu/atmega_common/include/cpu.h @@ -88,20 +88,20 @@ void cpu_init(void); /** * @brief Print the last instruction's address */ -__attribute__((always_inline)) static inline void cpu_print_last_instruction(void) + static inline void __attribute__((always_inline)) cpu_print_last_instruction(void) { uint8_t hi; uint8_t lo; uint16_t ptr; - __asm__ volatile( "in __tmp_reg__, __SP_H__ \n\t" + __asm__ volatile ("in __tmp_reg__, __SP_H__ \n\t" "mov %0, __tmp_reg__ \n\t" - : "=g"(hi) ); + : "=g" (hi)); - __asm__ volatile( "in __tmp_reg__, __SP_L__ \n\t" + __asm__ volatile ("in __tmp_reg__, __SP_L__ \n\t" "mov %0, __tmp_reg__ \n\t" - : "=g"(lo) ); - ptr = hi<<8 | lo; + : "=g" (lo)); + ptr = hi << 8 | lo; printf("Stack Pointer: 0x%04x\n", ptr); } diff --git a/cpu/atmega_common/thread_arch.c b/cpu/atmega_common/thread_arch.c index 180d32470046..46cad12f9ccf 100644 --- a/cpu/atmega_common/thread_arch.c +++ b/cpu/atmega_common/thread_arch.c @@ -28,7 +28,6 @@ #include "cpu.h" #include "board.h" - /* * local function declarations (prefixed with __) */ @@ -69,7 +68,7 @@ static void __enter_thread_mode(void); * if task_func returns sched_task_exit gets popped into the PC */ char *thread_stack_init(thread_task_func_t task_func, void *arg, - void *stack_start, int stack_size) + void *stack_start, int stack_size) { uint16_t tmp_adress; uint8_t *stk; @@ -111,7 +110,6 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, *stk = (uint8_t) 0x00; #endif - /* r0 */ stk--; *stk = (uint8_t) 0x00; @@ -140,7 +138,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, int i; - for (i = 2; i <= 23 ; i++) { + for (i = 2; i <= 23; i++) { stk--; *stk = (uint8_t) 0; } @@ -178,7 +176,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, */ void thread_stack_print(void) { - uint8_t found_marker = 1; + uint8_t found_marker = 1; uint8_t *sp = (uint8_t *)sched_active_thread->sp; uint16_t size = 0; @@ -193,8 +191,7 @@ void thread_stack_print(void) if ((*sp == 0xFE) && (*(sp + 1) == 0xAF)) { found_marker = 0; } - } - while (found_marker == 1); + } while (found_marker == 1); printf("stack size: %u bytes\n", size); } @@ -209,13 +206,12 @@ void cpu_switch_context_exit(void) /** * @brief Set the MCU into Thread-Mode and load the initial task from the stack and run it */ - void NORETURN __enter_thread_mode(void) __attribute__((naked)); void NORETURN __enter_thread_mode(void) { irq_enable(); __context_restore(); - __asm__ volatile("ret"); + __asm__ volatile ("ret"); UNREACHABLE(); } @@ -236,12 +232,12 @@ void thread_yield_isr(void) { sched_run(); __context_restore(); - __asm__ volatile("reti"); + __asm__ volatile ("reti"); } __attribute__((always_inline)) static inline void __context_save(void) { - __asm__ volatile( + __asm__ volatile ( "push __tmp_reg__ \n\t" "in __tmp_reg__, __SREG__ \n\t" "cli \n\t" @@ -292,13 +288,13 @@ __attribute__((always_inline)) static inline void __context_save(void) "st x+, __tmp_reg__ \n\t" "in __tmp_reg__, __SP_H__ \n\t" "st x+, __tmp_reg__ \n\t" - ); + ); } __attribute__((always_inline)) static inline void __context_restore(void) { - __asm__ volatile( + __asm__ volatile ( "lds r26, sched_active_thread \n\t" "lds r27, sched_active_thread + 1 \n\t" "ld r28, x+ \n\t" @@ -347,5 +343,5 @@ __attribute__((always_inline)) static inline void __context_restore(void) "pop __tmp_reg__ \n\t" "out __SREG__, __tmp_reg__ \n\t" "pop __tmp_reg__ \n\t" - ); + ); } From fe9277137292edc87bbd96d3ee7e6dc32280964c Mon Sep 17 00:00:00 2001 From: Josarn Date: Fri, 8 Jun 2018 17:52:44 +0200 Subject: [PATCH 3/6] cpu/atmega_common/include/cpu.h: uncrustified --- cpu/atmega_common/include/cpu.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cpu/atmega_common/include/cpu.h b/cpu/atmega_common/include/cpu.h index d2a0d55bd5f6..cfb476b2532c 100644 --- a/cpu/atmega_common/include/cpu.h +++ b/cpu/atmega_common/include/cpu.h @@ -44,7 +44,8 @@ #include "irq.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif /** @@ -88,7 +89,7 @@ void cpu_init(void); /** * @brief Print the last instruction's address */ - static inline void __attribute__((always_inline)) cpu_print_last_instruction(void) +static inline void __attribute__((always_inline)) cpu_print_last_instruction(void) { uint8_t hi; uint8_t lo; @@ -111,13 +112,13 @@ void cpu_init(void); * Some CPUs may not support the highest prescaler settings */ enum { - CPU_ATMEGA_CLK_SCALE_DIV1 = 0, - CPU_ATMEGA_CLK_SCALE_DIV2 = 1, - CPU_ATMEGA_CLK_SCALE_DIV4 = 2, - CPU_ATMEGA_CLK_SCALE_DIV8 = 3, - CPU_ATMEGA_CLK_SCALE_DIV16 = 4, - CPU_ATMEGA_CLK_SCALE_DIV32 = 5, - CPU_ATMEGA_CLK_SCALE_DIV64 = 6, + CPU_ATMEGA_CLK_SCALE_DIV1 = 0, + CPU_ATMEGA_CLK_SCALE_DIV2 = 1, + CPU_ATMEGA_CLK_SCALE_DIV4 = 2, + CPU_ATMEGA_CLK_SCALE_DIV8 = 3, + CPU_ATMEGA_CLK_SCALE_DIV16 = 4, + CPU_ATMEGA_CLK_SCALE_DIV32 = 5, + CPU_ATMEGA_CLK_SCALE_DIV64 = 6, CPU_ATMEGA_CLK_SCALE_DIV128 = 7, CPU_ATMEGA_CLK_SCALE_DIV256 = 8, CPU_ATMEGA_CLK_SCALE_DIV512 = 9, From 0e491861af0ebdaf993d126f970a5b6f11b6e086 Mon Sep 17 00:00:00 2001 From: Josarn Date: Fri, 8 Jun 2018 17:53:13 +0200 Subject: [PATCH 4/6] cpu/atmega_common/periph/timer.c: uncrustified --- cpu/atmega_common/periph/timer.c | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cpu/atmega_common/periph/timer.c b/cpu/atmega_common/periph/timer.c index b74daf691622..4a0065fde3b5 100644 --- a/cpu/atmega_common/periph/timer.c +++ b/cpu/atmega_common/periph/timer.c @@ -29,18 +29,18 @@ #include "periph/timer.h" #include "periph_conf.h" -#define ENABLE_DEBUG (0) +#define ENABLE_DEBUG (0) #include "debug.h" /** * @brief All timers have three channels */ -#define CHANNELS (3) +#define CHANNELS (3) /** * @brief We have 5 possible prescaler values */ -#define PRESCALE_NUMOF (5U) +#define PRESCALE_NUMOF (5U) /** * @brief Possible prescaler values, encoded as 2 ^ val @@ -51,13 +51,13 @@ static const uint8_t prescalers[] = { 0, 3, 6, 8, 10 }; * @brief Timer state context */ typedef struct { - mega_timer_t *dev; /**< timer device */ - volatile uint8_t *mask; /**< address of interrupt mask register */ - volatile uint8_t *flag; /**< address of interrupt flag register */ - timer_cb_t cb; /**< interrupt callback */ - void *arg; /**< interrupt callback argument */ - uint8_t mode; /**< remember the configured mode */ - uint8_t isrs; /**< remember the interrupt state */ + mega_timer_t *dev; /**< timer device */ + volatile uint8_t *mask; /**< address of interrupt mask register */ + volatile uint8_t *flag; /**< address of interrupt flag register */ + timer_cb_t cb; /**< interrupt callback */ + void *arg; /**< interrupt callback argument */ + uint8_t mode; /**< remember the configured mode */ + uint8_t isrs; /**< remember the interrupt state */ } ctx_t; /** @@ -109,8 +109,8 @@ int timer_init(tim_t tim, unsigned long freq, timer_cb_t cb, void *arg) ctx[tim].dev->CNT = 0; /* save interrupt context and timer mode */ - ctx[tim].cb = cb; - ctx[tim].arg = arg; + ctx[tim].cb = cb; + ctx[tim].arg = arg; ctx[tim].mode = (pre + 1); /* enable timer with calculated prescaler */ @@ -128,7 +128,7 @@ int timer_set_absolute(tim_t tim, int channel, unsigned int value) ctx[tim].dev->OCR[channel] = (uint16_t)value; *ctx[tim].flag &= ~(1 << (channel + OCF1A)); - *ctx[tim].mask |= (1 << (channel + OCIE1A)); + *ctx[tim].mask |= (1 << (channel + OCIE1A)); return 1; } @@ -187,8 +187,8 @@ ISR(TIMER_0_ISRC, ISR_BLOCK) { _isr(0, 2); } -#endif /* TIMER_0_ISRC */ -#endif /* TIMER_0 */ +#endif /* TIMER_0_ISRC */ +#endif /* TIMER_0 */ #ifdef TIMER_1 ISR(TIMER_1_ISRA, ISR_BLOCK) @@ -206,8 +206,8 @@ ISR(TIMER_1_ISRC, ISR_BLOCK) { _isr(1, 2); } -#endif /* TIMER_1_ISRC */ -#endif /* TIMER_1 */ +#endif /* TIMER_1_ISRC */ +#endif /* TIMER_1 */ #ifdef TIMER_2 ISR(TIMER_2_ISRA, ISR_BLOCK) From 40c1839a8c6b8af6e1409225021c31696210aa82 Mon Sep 17 00:00:00 2001 From: Josarn Date: Fri, 8 Jun 2018 17:53:43 +0200 Subject: [PATCH 5/6] cpu/atmega_common/periph/uart.c: uncrustified --- cpu/atmega_common/periph/uart.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpu/atmega_common/periph/uart.c b/cpu/atmega_common/periph/uart.c index c15c7dcd8b3e..8925f7a2bcb9 100644 --- a/cpu/atmega_common/periph/uart.c +++ b/cpu/atmega_common/periph/uart.c @@ -35,7 +35,6 @@ #include "periph/uart.h" - /** * @brief Maximum percentage error in calculated baud before switching to * double speed transmission (U2X) @@ -90,6 +89,7 @@ static void _update_brr(uart_t uart, uint16_t brr, bool double_speed) static void _set_brr(uart_t uart, uint32_t baudrate) { uint16_t brr; + #if defined(UART_STDIO_BAUDRATE) /* UBRR_VALUE and USE_2X are statically computed from */ if (baudrate == UART_STDIO_BAUDRATE) { @@ -115,7 +115,7 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) /* register interrupt context */ isr_ctx[uart].rx_cb = rx_cb; - isr_ctx[uart].arg = arg; + isr_ctx[uart].arg = arg; /* disable and reset UART */ dev[uart]->CSRB = 0; @@ -134,14 +134,13 @@ int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg) dev[uart]->CSRB = (1 << TXEN0); } - return UART_OK; } void uart_write(uart_t uart, const uint8_t *data, size_t len) { for (size_t i = 0; i < len; i++) { - while (!(dev[uart]->CSRA & (1 << UDRE0))) {}; + while (!(dev[uart]->CSRA & (1 << UDRE0))) {} dev[uart]->DR = data[i]; } } From 91359631d5fe22c86cda8eadaf98082bd5c8351c Mon Sep 17 00:00:00 2001 From: Josarn Date: Fri, 8 Jun 2018 17:54:06 +0200 Subject: [PATCH 6/6] cpu/atmega_common/thread_arch.c: uncrustified --- cpu/atmega_common/thread_arch.c | 60 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/cpu/atmega_common/thread_arch.c b/cpu/atmega_common/thread_arch.c index 46cad12f9ccf..f33a442ad17a 100644 --- a/cpu/atmega_common/thread_arch.c +++ b/cpu/atmega_common/thread_arch.c @@ -78,58 +78,58 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, /* put marker on stack */ stk--; - *stk = (uint8_t) 0xAF; + *stk = (uint8_t)0xAF; stk--; - *stk = (uint8_t) 0xFE; + *stk = (uint8_t)0xFE; /* save sched_task_exit */ stk--; - tmp_adress = (uint16_t) sched_task_exit; - *stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff); + tmp_adress = (uint16_t)sched_task_exit; + *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); stk--; tmp_adress >>= 8; - *stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff); + *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); #if FLASHEND > 0x1ffff /* Devices with more than 128kb FLASH use a 17 bit PC, we set whole the top byte forcibly to 0 */ stk--; - *stk = (uint8_t) 0x00; + *stk = (uint8_t)0x00; #endif /* save address to task_func in place of the program counter */ stk--; - tmp_adress = (uint16_t) task_func; - *stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff); + tmp_adress = (uint16_t)task_func; + *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); stk--; tmp_adress >>= 8; - *stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff); + *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); #if FLASHEND > 0x1ffff /* Devices with more than 128kb FLASH use a 17 bit PC, we set whole the top byte forcibly to 0 */ stk--; - *stk = (uint8_t) 0x00; + *stk = (uint8_t)0x00; #endif /* r0 */ stk--; - *stk = (uint8_t) 0x00; + *stk = (uint8_t)0x00; /* status register (with interrupts enabled) */ stk--; - *stk = (uint8_t) 0x80; + *stk = (uint8_t)0x80; #if defined(EIND) stk--; - *stk = (uint8_t) 0x00; + *stk = (uint8_t)0x00; #endif #if defined(RAMPZ) stk--; - *stk = (uint8_t) 0x00; + *stk = (uint8_t)0x00; #endif /* r1 - has always to be 0 */ stk--; - *stk = (uint8_t) 0x00; + *stk = (uint8_t)0x00; /* * Space for registers r2 -r23 * @@ -140,7 +140,7 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, for (i = 2; i <= 23; i++) { stk--; - *stk = (uint8_t) 0; + *stk = (uint8_t)0; } /* @@ -148,22 +148,22 @@ char *thread_stack_init(thread_task_func_t task_func, void *arg, * r24 and r25 * */ stk--; - tmp_adress = (uint16_t) arg; - *stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff); + tmp_adress = (uint16_t)arg; + *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); stk--; tmp_adress >>= 8; - *stk = (uint8_t)(tmp_adress & (uint16_t) 0x00ff); + *stk = (uint8_t)(tmp_adress & (uint16_t)0x00ff); /* * Space for registers r26-r31 */ for (i = 26; i <= 31; i++) { stk--; - *stk = (uint8_t) i; + *stk = (uint8_t)i; } stk--; - return (char *) stk; + return (char *)stk; } /** @@ -216,18 +216,21 @@ void NORETURN __enter_thread_mode(void) UNREACHABLE(); } -void thread_yield_higher(void) { +void thread_yield_higher(void) +{ if (irq_is_in() == 0) { __context_save(); sched_run(); __context_restore(); - __asm__ volatile("ret"); - } else { + __asm__ volatile ("ret"); + } + else { sched_context_switch_request = 1; } } -void thread_yield_isr(void) { +void thread_yield_isr(void) +{ __context_save(); sched_run(); __context_restore(); @@ -287,9 +290,7 @@ __attribute__((always_inline)) static inline void __context_save(void) "in __tmp_reg__, __SP_L__ \n\t" "st x+, __tmp_reg__ \n\t" "in __tmp_reg__, __SP_H__ \n\t" - "st x+, __tmp_reg__ \n\t" - ); - + "st x+, __tmp_reg__ \n\t"); } __attribute__((always_inline)) static inline void __context_restore(void) @@ -342,6 +343,5 @@ __attribute__((always_inline)) static inline void __context_restore(void) #endif "pop __tmp_reg__ \n\t" "out __SREG__, __tmp_reg__ \n\t" - "pop __tmp_reg__ \n\t" - ); + "pop __tmp_reg__ \n\t"); }