Merge pull request #12790 from maribu/atmega_isr_thread

cpu/atmega_common
This commit is contained in:
Alexandre Abadie 2019-11-24 11:10:10 +01:00 committed by GitHub
commit 41e29e3fda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 46 additions and 63 deletions

View File

@ -173,8 +173,8 @@ ISR(BADISR_vect)
#if defined(CPU_ATMEGA128RFA1) || defined (CPU_ATMEGA256RFR2)
ISR(BAT_LOW_vect, ISR_BLOCK)
{
__enter_isr();
atmega_enter_isr();
DEBUG("BAT_LOW\n");
__exit_isr();
atmega_exit_isr();
}
#endif

View File

@ -61,35 +61,20 @@ extern "C"
/**
* @brief global in-ISR state variable
*/
extern volatile uint8_t __in_isr;
extern volatile uint8_t atmega_in_isr;
/**
* @brief Run this code on entering interrupt routines
*/
static inline void __enter_isr(void)
static inline void atmega_enter_isr(void)
{
__in_isr = 1;
atmega_in_isr = 1;
}
/**
* @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;
}
void atmega_exit_isr(void);
/**
* @brief Initialization of the CPU

View File

@ -29,12 +29,12 @@
/**
* @brief Macro returns state of the global interrupt register
*/
static uint8_t __get_interrupt_state(void);
static void __set_interrupt_state(uint8_t state);
static uint8_t atmega_get_interrupt_state(void);
static void atmega_set_interrupt_state(uint8_t state);
volatile uint8_t __in_isr = 0;
volatile uint8_t atmega_in_isr = 0;
__attribute__((always_inline)) static inline uint8_t __get_interrupt_state(void)
__attribute__((always_inline)) static inline uint8_t atmega_get_interrupt_state(void)
{
uint8_t sreg;
__asm__ volatile( "in __tmp_reg__, __SREG__ \n\t"
@ -43,7 +43,7 @@ __attribute__((always_inline)) static inline uint8_t __get_interrupt_state(void
return sreg & (1 << 7);
}
__attribute__((always_inline)) inline void __set_interrupt_state(uint8_t state)
__attribute__((always_inline)) inline void atmega_set_interrupt_state(uint8_t state)
{
__asm__ volatile( "mov r15,%0 \n\t"
"in r16, __SREG__ \n\t"
@ -60,7 +60,7 @@ __attribute__((always_inline)) inline void __set_interrupt_state(uint8_t state)
*/
unsigned int irq_disable(void)
{
uint8_t mask = __get_interrupt_state();
uint8_t mask = atmega_get_interrupt_state();
cli(); /* <-- acts as memory barrier, see doc of avr-libc */
return (unsigned int) mask;
}
@ -70,7 +70,7 @@ unsigned int irq_disable(void)
*/
unsigned int irq_enable(void)
{
uint8_t mask = __get_interrupt_state();
uint8_t mask = atmega_get_interrupt_state();
sei(); /* <-- acts as memory barrier, see doc of avr-libc */
return mask;
}
@ -80,7 +80,7 @@ unsigned int irq_enable(void)
*/
void irq_restore(unsigned int state)
{
__set_interrupt_state(state);
atmega_set_interrupt_state(state);
}
/**
@ -88,7 +88,7 @@ void irq_restore(unsigned int state)
*/
int irq_is_in(void)
{
int result = __in_isr;
int result = atmega_in_isr;
__asm__ volatile("" ::: "memory");
return result;
}

View File

@ -374,16 +374,16 @@ void gpio_irq_disable(gpio_t pin)
static inline void irq_handler(uint8_t int_num)
{
__enter_isr();
atmega_enter_isr();
config[int_num].cb(config[int_num].arg);
__exit_isr();
atmega_exit_isr();
}
#ifdef PCINT_NUM_BANKS
/* inline function that is used by the PCINT ISR */
static inline void pcint_handler(uint8_t bank, uint8_t enabled_pcints)
{
__enter_isr();
atmega_enter_isr();
/* Find right item */
uint8_t idx = 0;
@ -413,7 +413,7 @@ static inline void pcint_handler(uint8_t bank, uint8_t enabled_pcints)
idx++;
}
__exit_isr();
atmega_exit_isr();
}
#if defined(PCINT0_IDX)
ISR(PCINT0_vect, ISR_BLOCK)

View File

@ -176,7 +176,7 @@ static inline void _isr(tim_t tim, int chan)
DEBUG_TIMER_PORT |= (1 << DEBUG_TIMER_PIN);
#endif
__enter_isr();
atmega_enter_isr();
*ctx[tim].mask &= ~(1 << (chan + OCIE1A));
ctx[tim].cb(ctx[tim].arg, chan);
@ -185,7 +185,7 @@ static inline void _isr(tim_t tim, int chan)
DEBUG_TIMER_PORT &= ~(1 << DEBUG_TIMER_PIN);
#endif
__exit_isr();
atmega_exit_isr();
}
#endif

View File

@ -186,11 +186,11 @@ void uart_poweroff(uart_t uart)
static inline void isr_handler(int num)
{
__enter_isr();
atmega_enter_isr();
isr_ctx[num].rx_cb(isr_ctx[num].arg, dev[num]->DR);
__exit_isr();
atmega_exit_isr();
}
#ifdef UART_0_ISR

View File

@ -30,16 +30,13 @@
#include "cpu.h"
#include "board.h"
/*
* local function declarations (prefixed with __)
*/
static void __context_save(void);
static void __context_restore(void);
static void __enter_thread_mode(void);
static void atmega_context_save(void);
static void atmega_context_restore(void);
static void atmega_enter_thread_mode(void);
/**
* @brief Since AVR doesn't support direct manipulation of the program counter we
* model a stack like it would be left by __context_save().
* model a stack like it would be left by atmega_context_save().
* The resulting layout in memory is the following:
* ---------------thread_t (not created by thread_stack_init) ----------
* local variables (a temporary value and the stackpointer)
@ -51,7 +48,7 @@ static void __enter_thread_mode(void);
* -----------------------------------------------------------------------
* a 16 Bit pointer to task_func
* this is placed exactly at the place where the program counter would be
* stored normally and thus can be returned to when __context_restore()
* stored normally and thus can be returned to when atmega_context_restore()
* has been run
* (Optional 17 bit (bit is set to zero) for devices with > 128kb FLASH)
* -----------------------------------------------------------------------
@ -64,7 +61,7 @@ static void __enter_thread_mode(void);
* r26 - r31
* -----------------------------------------------------------------------
*
* After the invocation of __context_restore() the pointer to task_func is
* After the invocation of atmega_context_restore() the pointer to task_func is
* on top of the stack and can be returned to. This way we can actually place
* it inside of the program counter of the MCU.
* if task_func returns sched_task_exit gets popped into the PC
@ -201,7 +198,7 @@ void thread_stack_print(void)
void cpu_switch_context_exit(void)
{
sched_run();
__enter_thread_mode();
atmega_enter_thread_mode();
}
#define STACK_POINTER ((char *)AVR_STACK_POINTER_REG)
@ -213,7 +210,7 @@ extern char *__brkval;
/**
* @brief Set the MCU into Thread-Mode and load the initial task from the stack and run it
*/
void NORETURN __enter_thread_mode(void)
void NORETURN atmega_enter_thread_mode(void)
{
irq_enable();
@ -229,7 +226,7 @@ void NORETURN __enter_thread_mode(void)
__brkval = __malloc_heap_start;
}
__context_restore();
atmega_context_restore();
__asm__ volatile ("ret");
UNREACHABLE();
@ -238,9 +235,9 @@ void NORETURN __enter_thread_mode(void)
void thread_yield_higher(void)
{
if (irq_is_in() == 0) {
__context_save();
atmega_context_save();
sched_run();
__context_restore();
atmega_context_restore();
__asm__ volatile ("ret");
}
else {
@ -248,16 +245,17 @@ void thread_yield_higher(void)
}
}
void thread_yield_isr(void)
void atmega_exit_isr(void)
{
__context_save();
atmega_in_isr = 0;
atmega_context_save();
sched_run();
__context_restore();
atmega_context_restore();
__asm__ volatile ("reti");
}
__attribute__((always_inline)) static inline void __context_save(void)
__attribute__((always_inline)) static inline void atmega_context_save(void)
{
__asm__ volatile (
"push __tmp_reg__ \n\t"
@ -312,7 +310,7 @@ __attribute__((always_inline)) static inline void __context_save(void)
"st x+, __tmp_reg__ \n\t");
}
__attribute__((always_inline)) static inline void __context_restore(void)
__attribute__((always_inline)) static inline void atmega_context_restore(void)
{
__asm__ volatile (
"lds r26, sched_active_thread \n\t"

View File

@ -732,7 +732,7 @@ static void _isr(netdev_t *netdev)
*/
ISR(TRX24_RX_END_vect, ISR_BLOCK)
{
__enter_isr();
atmega_enter_isr();
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
DEBUG("TRX24_RX_END 0x%x\n", status);
@ -741,7 +741,7 @@ ISR(TRX24_RX_END_vect, ISR_BLOCK)
/* Call upper layer to process received data */
at86rfmega_dev->event_callback(at86rfmega_dev, NETDEV_EVENT_ISR);
__exit_isr();
atmega_exit_isr();
}
/**
@ -754,12 +754,12 @@ ISR(TRX24_RX_END_vect, ISR_BLOCK)
*/
ISR(TRX24_XAH_AMI_vect, ISR_BLOCK)
{
__enter_isr();
atmega_enter_isr();
DEBUG("TRX24_XAH_AMI\n");
((at86rf2xx_t *)at86rfmega_dev)->irq_status |= AT86RF2XX_IRQ_STATUS_MASK__AMI;
__exit_isr();
atmega_exit_isr();
}
/**
@ -771,7 +771,7 @@ ISR(TRX24_XAH_AMI_vect, ISR_BLOCK)
*/
ISR(TRX24_TX_END_vect, ISR_BLOCK)
{
__enter_isr();
atmega_enter_isr();
at86rf2xx_t *dev = (at86rf2xx_t *) at86rfmega_dev;
uint8_t status = *AT86RF2XX_REG__TRX_STATE & AT86RF2XX_TRX_STATUS_MASK__TRX_STATUS;
@ -786,7 +786,7 @@ ISR(TRX24_TX_END_vect, ISR_BLOCK)
at86rfmega_dev->event_callback(at86rfmega_dev, NETDEV_EVENT_ISR);
}
__exit_isr();
atmega_exit_isr();
}
#endif /* MODULE_AT86RFA1 || MODULE_AT86RFR2 */