git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@595 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-01-09 11:05:26 +00:00
parent a07bd21d44
commit 52ab7591c7
4 changed files with 92 additions and 20 deletions

View File

@ -85,9 +85,13 @@ void hwinit(void) {
InitSerial(); InitSerial();
} }
interrupt(TIMERA0_VECTOR) tmr0irq(void) { SYS_IRQ_HANDLER(TIMERA0_VECTOR) tmr0irq(void) {
chSysIRQEnterI(); SYS_IRQ_PROLOGUE();
chSysLockI();
chSysTimerHandlerI(); chSysTimerHandlerI();
chSysIRQExitI(); chSysUnlockI();
SYS_IRQ_EPILOGUE();
} }

View File

@ -31,12 +31,55 @@
* because performance concerns. * because performance concerns.
*/ */
/**
* The default implementation of this function is void so no messages are
* actually printed.
* @note The function is declared as a weak symbol, it is possible to redefine
* it in your application code.
* @param msg pointer to the message string
*/
__attribute__((weak))
void sys_puts(char *msg) { void sys_puts(char *msg) {
} }
/**
* Performs a context switch between two threads.
* @param otp the thread to be switched out
* @param ntp the thread to be switched in
* @note The function is declared as a weak symbol, it is possible to redefine
* it in your application code.
*/
__attribute__((naked, weak))
void sys_switch(Thread *otp, Thread *ntp) { void sys_switch(Thread *otp, Thread *ntp) {
register struct intctx *sp asm("r1");
asm volatile ("push r11 \n\t" \
"push r10 \n\t" \
"push r9 \n\t" \
"push r8 \n\t" \
"push r7 \n\t" \
"push r6 \n\t" \
"push r6 \n\t" \
"push r4");
otp->p_ctx.sp = sp;
sp = ntp->p_ctx.sp;
asm volatile ("pop r4 \n\t" \
"pop r5 \n\t" \
"pop r6 \n\t" \
"pop r7 \n\t" \
"pop r8 \n\t" \
"pop r9 \n\t" \
"pop r10 \n\t" \
"pop r11 \n\t" \
"ret" : : "r" (sp));
} }
/**
* Disables the interrupts and halts the system.
* @note The function is declared as a weak symbol, it is possible to redefine
* it in your application code.
*/
__attribute__((weak))
void sys_halt(void) { void sys_halt(void) {
sys_disable(); sys_disable();
@ -44,4 +87,16 @@ void sys_halt(void) {
} }
} }
/**
* Start a thread by invoking its work function.
* If the work function returns @p chThdExit() is automatically invoked.
*/
void threadstart(void) {
asm volatile ("eint \n\t" \
"mov r11, r15 \n\t" \
"call r10 \n\t" \
"call #chThdExit");
}
/** @} */ /** @} */

View File

@ -150,6 +150,12 @@ if (chSchRescRequiredI()) \
chSchDoRescheduleI(); \ chSchDoRescheduleI(); \
} }
/**
* IRQ handler function modifier. Note it just aliases the WinMSP "interrupt"
* macro.
*/
#define SYS_IRQ_HANDLER interrupt
/** /**
* This port function is implemented as inlined code for performance reasons. * This port function is implemented as inlined code for performance reasons.
*/ */
@ -181,11 +187,6 @@ if (chSchRescRequiredI()) \
#define sys_wait_for_interrupt() #define sys_wait_for_interrupt()
#endif #endif
/**
* IRQ handler function modifier.
*/
#define SYS_IRQ_HANDLER
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif

View File

@ -34,7 +34,9 @@ static void SetError(uint8_t urctl, FullDuplexDriver *com) {
sts |= SD_FRAMING_ERROR; sts |= SD_FRAMING_ERROR;
if (urctl & BRK) if (urctl & BRK)
sts |= SD_BREAK_DETECTED; sts |= SD_BREAK_DETECTED;
chSysLockI();
chFDDAddFlagsI(com, sts); chFDDAddFlagsI(com, sts);
chSysUnlockI();
} }
#ifdef USE_MSP430_USART0 #ifdef USE_MSP430_USART0
@ -42,30 +44,34 @@ FullDuplexDriver COM1;
static uint8_t ib1[SERIAL_BUFFERS_SIZE]; static uint8_t ib1[SERIAL_BUFFERS_SIZE];
static uint8_t ob1[SERIAL_BUFFERS_SIZE]; static uint8_t ob1[SERIAL_BUFFERS_SIZE];
interrupt(USART0TX_VECTOR) u0txirq(void) { SYS_IRQ_HANDLER(USART0TX_VECTOR) u0txirq(void) {
msg_t b; msg_t b;
chSysIRQEnterI(); SYS_IRQ_PROLOGUE();
chSysLockI();
b = chFDDRequestDataI(&COM1); b = chFDDRequestDataI(&COM1);
chSysUnlockI();
if (b < Q_OK) if (b < Q_OK)
U0IE &= ~UTXIE0; U0IE &= ~UTXIE0;
else else
U0TXBUF = b; U0TXBUF = b;
chSysIRQExitI(); SYS_IRQ_EPILOGUE();
} }
interrupt(USART0RX_VECTOR) u0rxirq(void) { SYS_IRQ_HANDLER(USART0RX_VECTOR) u0rxirq(void) {
uint8_t urctl; uint8_t urctl;
chSysIRQEnterI(); SYS_IRQ_PROLOGUE();
if ((urctl = U0RCTL) & RXERR) if ((urctl = U0RCTL) & RXERR)
SetError(urctl, &COM1); SetError(urctl, &COM1);
chSysLockI();
chFDDIncomingDataI(&COM1, U0RXBUF); chFDDIncomingDataI(&COM1, U0RXBUF);
chSysUnlockI();
chSysIRQExitI(); SYS_IRQ_EPILOGUE();
} }
/* /*
@ -75,7 +81,9 @@ interrupt(USART0RX_VECTOR) u0rxirq(void) {
static void OutNotify1(void) { static void OutNotify1(void) {
if (!(U0IE & UTXIE0)) { if (!(U0IE & UTXIE0)) {
chSysLockI();
U0TXBUF = (uint8_t)chFDDRequestDataI(&COM1); U0TXBUF = (uint8_t)chFDDRequestDataI(&COM1);
chSysUnlockI();
U0IE |= UTXIE0; U0IE |= UTXIE0;
} }
} }
@ -108,30 +116,34 @@ FullDuplexDriver COM2;
static uint8_t ib2[SERIAL_BUFFERS_SIZE]; static uint8_t ib2[SERIAL_BUFFERS_SIZE];
static uint8_t ob2[SERIAL_BUFFERS_SIZE]; static uint8_t ob2[SERIAL_BUFFERS_SIZE];
interrupt(USART1TX_VECTOR) u1txirq(void) { SYS_IRQ_HANDLER(USART1TX_VECTOR) u1txirq(void) {
msg_t b; msg_t b;
chSysIRQEnterI(); SYS_IRQ_PROLOGUE();
chSysLockI();
b = chFDDRequestDataI(&COM2); b = chFDDRequestDataI(&COM2);
chSysUnlockI();
if (b < Q_OK) if (b < Q_OK)
U1IE &= ~UTXIE1; U1IE &= ~UTXIE1;
else else
U1TXBUF = b; U1TXBUF = b;
chSysIRQExitI(); SYS_IRQ_EPILOGUE();
} }
interrupt(USART1RX_VECTOR) u1rxirq(void) { SYS_IRQ_HANDLER(USART1RX_VECTOR) u1rxirq(void) {
uint8_t urctl; uint8_t urctl;
chSysIRQEnterI(); SYS_IRQ_PROLOGUE();
if ((urctl = U1RCTL) & RXERR) if ((urctl = U1RCTL) & RXERR)
SetError(urctl, &COM2); SetError(urctl, &COM2);
chSysLockI();
chFDDIncomingDataI(&COM2, U1RXBUF); chFDDIncomingDataI(&COM2, U1RXBUF);
chSysUnlockI();
chSysIRQExitI(); SYS_IRQ_EPILOGUE();
} }