diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-08-13 09:42:40 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-08-13 09:42:40 -0600 |
commit | 10d49e897e562c376fd053b7aaa44912bc32b771 (patch) | |
tree | 8054ee03b7b66806d1d741877ab602ac98adc01c | |
parent | b10f9ac74ef20d0ff7f56f11e84e8f5d0fcecc2d (diff) | |
download | px4-nuttx-10d49e897e562c376fd053b7aaa44912bc32b771.tar.gz px4-nuttx-10d49e897e562c376fd053b7aaa44912bc32b771.tar.bz2 px4-nuttx-10d49e897e562c376fd053b7aaa44912bc32b771.zip |
Fix re-entry problem in SAMA5 up_putc
-rw-r--r-- | nuttx/ChangeLog | 5 | ||||
-rw-r--r-- | nuttx/arch/arm/src/sama5/sam_serial.c | 31 |
2 files changed, 35 insertions, 1 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 2471c4c7f..fa6401252 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -5387,3 +5387,8 @@ is being disconnected (2013-8-12). * nuttx/arch/arm/src/stm32/Kconfig, Make.defs, and /stm32f30xxx_i2c.c: STM32 F3 I2C fixes from John Wharington (2013-8-13). + * nuttx/arch/arm/src/sama5/sam_serial.c: Fix a re-entrancy problem + in up_putc(). I think all architectures have this re-entrancy + than can result in serial interrupt being disabled, but I have only + seen the symptom on SAMA5 (2013-8-13). + diff --git a/nuttx/arch/arm/src/sama5/sam_serial.c b/nuttx/arch/arm/src/sama5/sam_serial.c index ebf1e4166..19b2dcd1b 100644 --- a/nuttx/arch/arm/src/sama5/sam_serial.c +++ b/nuttx/arch/arm/src/sama5/sam_serial.c @@ -1194,7 +1194,10 @@ void up_serialinit(void) * Name: up_putc * * Description: - * Provide priority, low-level access to support OS debug writes + * Provide priority, low-level access to support OS debug writes. This + * function is intended only to support early boot-up logic and serial + * debug output from interrupt handlers. It is invasive and will effect + * your realtime performance! * ****************************************************************************/ @@ -1202,9 +1205,26 @@ int up_putc(int ch) { #ifdef HAVE_CONSOLE struct up_dev_s *priv = (struct up_dev_s*)CONSOLE_DEV.priv; + + /* This logic does not work. Apparently re-entrancy problems cause the + * loss of serial interrupts (a bad, zero IMR gets set). My attempts to + * make this function fully re-entrant have not been successful but the + * following brute force approach works just fine. + */ + +#if 0 uint32_t imr; + /* Disable serial interrupts */ + up_disableallints(priv, &imr); +#else + irqstate_t flags; + + /* Disable all interrupts */ + + flags = irqsave(); +#endif /* Check for LF */ @@ -1216,7 +1236,16 @@ int up_putc(int ch) } up_lowputc(ch); + +#if 0 /* See comments above */ + /* Restore serial interrupts */ + up_restoreusartint(priv, imr); +#else + /* Restore all interrupts */ + + irqrestore(flags); +#endif #endif return ch; } |