mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-25 14:33:52 +01:00
Merge pull request #1618 from rousselk/msp430-fix-thread-yield
Fix thread_yield() on MSP430 platforms
This commit is contained in:
commit
fa8c70bbb8
@ -1,12 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2013, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
* Copyright (C) 2014, Freie Universitaet Berlin (FUB) & INRIA.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "irq.h"
|
||||
#include "kernel.h"
|
||||
#include "kernel_internal.h"
|
||||
#include "sched.h"
|
||||
@ -16,16 +18,27 @@ volatile int __inISR = 0;
|
||||
|
||||
char __isr_stack[MSP430_ISR_STACK_SIZE];
|
||||
|
||||
void thread_yield(void)
|
||||
/*
|
||||
* we must prevent the compiler to generate a prologue or an epilogue
|
||||
* for thread_yield(), since we rely on the RETI instruction at the end
|
||||
* of its execution, in the inlined __restore_context() sub-function
|
||||
*/
|
||||
__attribute__((naked)) void thread_yield(void)
|
||||
{
|
||||
/*
|
||||
* disable IRQ, remembering if they are
|
||||
* to be reactivated after context switch
|
||||
*/
|
||||
unsigned int irqen = disableIRQ();
|
||||
|
||||
__save_context();
|
||||
|
||||
dINT();
|
||||
/* have sched_active_thread point to the next thread */
|
||||
sched_run();
|
||||
eINT();
|
||||
|
||||
__restore_context();
|
||||
__restore_context(irqen);
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
NORETURN void cpu_switch_context_exit(void)
|
||||
@ -33,7 +46,7 @@ NORETURN void cpu_switch_context_exit(void)
|
||||
sched_active_thread = sched_threads[0];
|
||||
sched_run();
|
||||
|
||||
__restore_context();
|
||||
__restore_context(GIE);
|
||||
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2013, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
* Copyright (C) 2014, Freie Universitaet Berlin (FUB) & INRIA.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
@ -99,9 +100,22 @@ inline void __save_context(void)
|
||||
__save_context_isr();
|
||||
}
|
||||
|
||||
inline void __restore_context(void)
|
||||
inline void __restore_context(unsigned int irqen)
|
||||
{
|
||||
__restore_context_isr();
|
||||
|
||||
/*
|
||||
* we want to enable appropriate IRQs *just after*
|
||||
* quitting the interrupt handler; to that end,
|
||||
* we change the GIE bit in the value to be restored
|
||||
* in R2 (a.k.a. SR) by the next RETI instruction
|
||||
*/
|
||||
if (irqen) {
|
||||
__asm__("bis.w #8, 0(r1)");
|
||||
} else {
|
||||
__asm__("bic.w #8, 0(r1)");
|
||||
}
|
||||
|
||||
__asm__("reti");
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user