aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2017-01-13 12:10:00 -0500
committerKevin O'Connor <kevin@koconnor.net>2017-01-13 12:10:00 -0500
commit9a44a20a9d25f7e5d38ff943fbbd51d0f305ce3f (patch)
tree0772b124becf45b6561db108bcec0e93953209a8
parentf335045273401d89977b663eab9b96d62e5e2bbb (diff)
downloadkutter-9a44a20a9d25f7e5d38ff943fbbd51d0f305ce3f.tar.gz
kutter-9a44a20a9d25f7e5d38ff943fbbd51d0f305ce3f.tar.xz
kutter-9a44a20a9d25f7e5d38ff943fbbd51d0f305ce3f.zip
command: Check for reentrant calls to sendf()
Allow sendf() to be called from irq and timer context - check for the case where sendf() is called while already in sendf() and simply discard those messages. This makes it safe to use output() debugging calls even in irq and timer context. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--docs/Protocol.md4
-rw-r--r--src/command.c15
2 files changed, 15 insertions, 4 deletions
diff --git a/docs/Protocol.md b/docs/Protocol.md
index 5c375e30..39b81a8a 100644
--- a/docs/Protocol.md
+++ b/docs/Protocol.md
@@ -105,9 +105,7 @@ output("The value of %u is %s with size %u.", x, buf, buf_len);
```
The output() function is similar in usage to printf() - it is intended
-to generate and format arbitrary messages for human consumption. It is
-a wrapper around sendf() and as with sendf() it should not be called
-from interrupts or timers.
+to generate and format arbitrary messages for human consumption.
Declaring constants
-------------------
diff --git a/src/command.c b/src/command.c
index f11bfcc8..069dfe57 100644
--- a/src/command.c
+++ b/src/command.c
@@ -114,11 +114,22 @@ error:
void
_sendf(uint8_t parserid, ...)
{
+ static uint8_t in_sendf;
+ irqstatus_t flag = irq_save();
+ if (in_sendf) {
+ // This sendf call was made from an irq handler while the main
+ // code was already in sendf - just drop this sendf request.
+ irq_restore(flag);
+ return;
+ }
+ in_sendf = 1;
+ irq_restore(flag);
+
const struct command_encoder *cp = &command_encoders[parserid];
uint8_t max_size = READP(cp->max_size);
char *buf = console_get_output(max_size + MESSAGE_MIN);
if (!buf)
- return;
+ goto done;
char *p = &buf[MESSAGE_HEADER_SIZE];
if (max_size) {
char *maxend = &p[max_size];
@@ -182,6 +193,8 @@ _sendf(uint8_t parserid, ...)
*p++ = crc;
*p++ = MESSAGE_SYNC;
console_push_output(msglen);
+done:
+ in_sendf = 0;
return;
error:
shutdown("Message encode error");