1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-24 22:13:52 +01:00

cpu/atmega_common: return to non-interrupt context swaps

This commit is contained in:
Matthew Blue 2018-04-08 11:10:58 -04:00
parent b522d5e6ee
commit ac2b643308
4 changed files with 21 additions and 31 deletions

View File

@ -97,6 +97,13 @@ __attribute__((always_inline)) static inline void cpu_print_last_instruction(voi
*/
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

View File

@ -176,6 +176,7 @@ static inline void _isr(tim_t tim, int chan)
if (sched_context_switch_request) {
thread_yield();
thread_yield_isr();
}
__exit_isr();

View File

@ -170,6 +170,7 @@ static inline void isr_handler(int num)
if (sched_context_switch_request) {
thread_yield();
thread_yield_isr();
}
}

View File

@ -29,31 +29,6 @@
#include "board.h"
/**
* @brief AVR_CONTEXT_SWAP_INIT initialize the context swap trigger
* Called when threading is first started.
*/
#ifndef AVR_CONTEXT_SWAP_INIT
#error AVR_CONTEXT_SWAP_INIT must be defined in board.h
#endif
/**
* @brief AVR_CONTEXT_SWAP_INTERRUPT_VECT Name of the ISR to use for context swapping
*/
#ifndef AVR_CONTEXT_SWAP_INTERRUPT_VECT
#error AVR_CONTEXT_SWAP_INTERRUPT_VECT must be defined in board.h
#endif
/**
* @brief AVR_CONTEXT_SWAP_TRIGGER executed to start the context swap
* When executed, this should result in the interrupt named in
* AVR_CONTEXT_SWAP_INTERRUPT_VECT being called
*/
#ifndef AVR_CONTEXT_SWAP_TRIGGER
#error ARV_CONTEXT_SWAP_TRIGGER must be defined in board.h
#endif
/*
* local function declarations (prefixed with __)
*/
@ -228,7 +203,6 @@ void cpu_switch_context_exit(void) __attribute__((naked));
void cpu_switch_context_exit(void)
{
sched_run();
AVR_CONTEXT_SWAP_INIT;
__enter_thread_mode();
}
@ -247,19 +221,26 @@ void NORETURN __enter_thread_mode(void)
}
void thread_yield_higher(void) {
AVR_CONTEXT_SWAP_TRIGGER;
if (irq_is_in() == 0) {
__context_save();
sched_run();
__context_restore();
__asm__ volatile("ret");
} else {
sched_context_switch_request = 1;
}
}
/* Use this interrupt to perform all context switches */
ISR(AVR_CONTEXT_SWAP_INTERRUPT_VECT, ISR_NAKED) {
void thread_yield_isr(void) {
__context_save();
sched_run();
__context_restore();
__exit_isr();
__asm__ volatile("reti");
}
__attribute__((always_inline)) static inline void __context_save(void)
{
__asm__ volatile(