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-31 12:24:24 -0700
commit4f1f3e836393304434130d362771a39f6f8f859a (patch)
tree5655f7ae7aa252a96aa585e3aee47b1b57a8fc9a /src/core
parent7afcec1a1dce140dfa569469df4ef42ed407a742 (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 e3161b4c..6c790f69 100644
--- a/src/core/ao.h
+++ b/src/core/ao.h
@@ -638,7 +638,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;