mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #5763 from jthacker/avr_thread_arch_isr_stack_usage
atmega: use software interrupt for context swap
This commit is contained in:
commit
6d30ced410
@ -52,6 +52,22 @@ extern "C" {
|
||||
#define LED0_TOGGLE (PORTB ^= LED0_MASK)
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* Context swap defines
|
||||
* Setup to use PJ6 which is pin change interrupt 15 (PCINT15)
|
||||
* This emulates a software triggered interrupt
|
||||
**/
|
||||
#define AVR_CONTEXT_SWAP_INIT do { \
|
||||
DDRJ |= (1 << PJ6); \
|
||||
PCICR |= (1 << PCIE1); \
|
||||
PCMSK1 |= (1 << PCINT15); \
|
||||
} while (0)
|
||||
#define AVR_CONTEXT_SWAP_INTERRUPT_VECT PCINT1_vect
|
||||
#define AVR_CONTEXT_SWAP_TRIGGER PORTJ ^= (1 << PJ6)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief xtimer configuration values
|
||||
* @{
|
||||
|
@ -150,6 +150,19 @@ extern "C" {
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Context swap defines
|
||||
* Setup to use PB5 which is pin change interrupt 5
|
||||
* This emulates a software triggered interrupt
|
||||
**/
|
||||
#define AVR_CONTEXT_SWAP_INIT do { \
|
||||
DDRB |= (1 << PB5); \
|
||||
PCICR |= (1 << PCIE0); \
|
||||
PCMSK0 |= (1 << PCINT5); \
|
||||
} while (0)
|
||||
#define AVR_CONTEXT_SWAP_INTERRUPT_VECT PCINT0_vect
|
||||
#define AVR_CONTEXT_SWAP_TRIGGER PORTB ^= (1 << PB5)
|
||||
|
||||
/**
|
||||
* @brief xtimer configuration values
|
||||
* @{
|
||||
|
@ -25,11 +25,37 @@
|
||||
#include "sched.h"
|
||||
#include "irq.h"
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief AVR_CONTEXT_SWAP_INIT intialize 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 __)
|
||||
*/
|
||||
|
||||
static void __context_save(void);
|
||||
static void __context_restore(void);
|
||||
static void __enter_thread_mode(void);
|
||||
@ -122,7 +148,6 @@ char *thread_arch_stack_init(thread_task_func_t task_func, void *arg,
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
#endif
|
||||
|
||||
#if defined(RAMPZ)
|
||||
stk--;
|
||||
*stk = (uint8_t) 0x00;
|
||||
@ -221,6 +246,7 @@ void thread_arch_start_threading(void) __attribute__((naked));
|
||||
void thread_arch_start_threading(void)
|
||||
{
|
||||
sched_run();
|
||||
AVR_CONTEXT_SWAP_INIT;
|
||||
__enter_thread_mode();
|
||||
}
|
||||
|
||||
@ -238,17 +264,17 @@ void NORETURN __enter_thread_mode(void)
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void thread_arch_yield(void) __attribute__((naked));
|
||||
void thread_arch_yield(void)
|
||||
{
|
||||
void thread_arch_yield(void) {
|
||||
AVR_CONTEXT_SWAP_TRIGGER;
|
||||
}
|
||||
|
||||
|
||||
// Use this interrupt to perform all context switches
|
||||
ISR(AVR_CONTEXT_SWAP_INTERRUPT_VECT, ISR_NAKED) {
|
||||
__context_save();
|
||||
|
||||
/* irq_disable(); */ /* gets already disabled during __context_save() */
|
||||
sched_run();
|
||||
irq_enable();
|
||||
|
||||
__context_restore();
|
||||
__asm__ volatile("ret");
|
||||
__asm__ volatile("reti");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user