summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-03-24 15:00:20 -0700
committerKeith Packard <keithp@keithp.com>2013-03-24 15:00:20 -0700
commitf3dc025a764ca6a2c44fb514ccaf22e6210f769d (patch)
tree05c0be2a58f2bfc84d2916d90baaea0f1609d890 /src/core
parent0365df9ed5a638bfdefb29eec830e51301c13936 (diff)
altos: Do not release interrupts from any pollchar function
getchar relies on interrupts being blocked across the pollchar calls and into the sleep call or it may go to sleep with data pending. This prefixes all pollchar functions with _ to indicate that they are to be called with interrupts blocked and eliminates all interrupt manipulation calls from within the pollchar functions. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/ao.h2
-rw-r--r--src/core/ao_packet.h2
-rw-r--r--src/core/ao_serial.h8
-rw-r--r--src/core/ao_stdio.c31
4 files changed, 22 insertions, 21 deletions
diff --git a/src/core/ao.h b/src/core/ao.h
index ce0bf5d1..adda0b6f 100644
--- a/src/core/ao.h
+++ b/src/core/ao.h
@@ -607,7 +607,7 @@ ao_monitor_init(void) __reentrant;
#define AO_READ_AGAIN (-1)
struct ao_stdio {
- int (*pollchar)(void);
+ int (*_pollchar)(void); /* Called with interrupts blocked */
void (*putchar)(char c) __reentrant;
void (*flush)(void);
uint8_t echo;
diff --git a/src/core/ao_packet.h b/src/core/ao_packet.h
index 08b184d6..6d121bb9 100644
--- a/src/core/ao_packet.h
+++ b/src/core/ao_packet.h
@@ -63,7 +63,7 @@ void
ao_packet_putchar(char c) __reentrant;
int
-ao_packet_pollchar(void);
+_ao_packet_pollchar(void);
#if PACKET_HAS_MASTER
/* ao_packet_master.c */
diff --git a/src/core/ao_serial.h b/src/core/ao_serial.h
index a799bf2c..baf213c0 100644
--- a/src/core/ao_serial.h
+++ b/src/core/ao_serial.h
@@ -32,7 +32,7 @@ char
ao_serial0_getchar(void);
int
-ao_serial0_pollchar(void);
+_ao_serial0_pollchar(void);
void
ao_serial0_putchar(char c);
@@ -52,7 +52,7 @@ char
ao_serial1_getchar(void);
int
-ao_serial1_pollchar(void);
+_ao_serial1_pollchar(void);
void
ao_serial1_putchar(char c);
@@ -72,7 +72,7 @@ char
ao_serial2_getchar(void);
int
-ao_serial2_pollchar(void);
+_ao_serial2_pollchar(void);
void
ao_serial2_putchar(char c);
@@ -92,7 +92,7 @@ char
ao_serial3_getchar(void);
int
-ao_serial3_pollchar(void);
+_ao_serial3_pollchar(void);
void
ao_serial3_putchar(char c);
diff --git a/src/core/ao_stdio.c b/src/core/ao_stdio.c
index 1748dfe8..977d74b1 100644
--- a/src/core/ao_stdio.c
+++ b/src/core/ao_stdio.c
@@ -99,20 +99,21 @@ char
getchar(void) __reentrant
{
int c;
- ao_arch_critical(
- int8_t stdio = ao_cur_stdio;
+ int8_t stdio;
- for (;;) {
- c = ao_stdios[stdio].pollchar();
- if (c != AO_READ_AGAIN)
- break;
- if (++stdio == ao_num_stdios)
- stdio = 0;
- if (stdio == ao_cur_stdio)
- ao_sleep(&ao_stdin_ready);
- }
- ao_cur_stdio = stdio;
- );
+ ao_arch_block_interrupts();
+ stdio = ao_cur_stdio;
+ for (;;) {
+ c = ao_stdios[stdio]._pollchar();
+ if (c != AO_READ_AGAIN)
+ break;
+ if (++stdio == ao_num_stdios)
+ stdio = 0;
+ if (stdio == ao_cur_stdio)
+ ao_sleep(&ao_stdin_ready);
+ }
+ ao_cur_stdio = stdio;
+ ao_arch_release_interrupts();
return c;
}
@@ -123,13 +124,13 @@ ao_echo(void)
}
int8_t
-ao_add_stdio(int (*pollchar)(void),
+ao_add_stdio(int (*_pollchar)(void),
void (*putchar)(char),
void (*flush)(void)) __reentrant
{
if (ao_num_stdios == AO_NUM_STDIOS)
ao_panic(AO_PANIC_STDIO);
- ao_stdios[ao_num_stdios].pollchar = pollchar;
+ ao_stdios[ao_num_stdios]._pollchar = _pollchar;
ao_stdios[ao_num_stdios].putchar = putchar;
ao_stdios[ao_num_stdios].flush = flush;
ao_stdios[ao_num_stdios].echo = 1;