Hi Daniel,
Thanks for the bump; very interesting observation!
So, I had a theory, and here is what I tried:
#include "mbed.h"
Serial term(USBTX, USBRX);
volatile bool one_shot = false;
void HandleTimer(void){
if (!one_shot) {
one_shot = true;
term.printf("!");
}
}
int main() {
Ticker timer;
timer.attach(&HandleTimer, 0.1);
wait(1); // wait so we know handler triggers before we hang on getc()
while(true){
int key = term.getc();
term.printf(">");
if (key == 'r')
one_shot = false;
}
}
And the result:
!>>>>>>>>!a>>>>>>>>>!a>>>>
Interesting :) No 'a' the first time.
So here is my initial theory that led me to this test. When you start this code, it all goes fine and ends up hanging on getc() waiting for a character, in the depths of stdio. Then, when the interrupt fires, printf enters in to stdio to do things as well, and changes some state within the stdio libs. When getc() finally gets a character, something is a little confused and means the result is incorrect. i.e. it is a re-entrancy problem.
So, you don't really want to be in stdio when an interrupt happens (as you'd probably expect). As a simple "workaround" to prove the point, here is some code that doesn't hang on getc():
#include "mbed.h"
Serial term(USBTX, USBRX);
volatile bool one_shot = false;
void HandleTimer(void){
if (!one_shot) {
one_shot = true;
term.printf("!");
}
}
int main() {
Ticker timer;
timer.attach(&HandleTimer, 0.1);
while(true){
if(term.readable()) {
int key = term.getc();
term.printf(">");
if (key == 'r')
one_shot = false;
}
}
}
This works as I think you are expecting, but of course doesn't totally eliminate the potential for a race condition.
So whilst this probably gets you what you need, it also asks the question about if and how we should support re-entrancy/resouce sharing. This will need more investigation/specification, and I'd be interested in opinions at what level people would "expect" it to be solved (it just works vs RTOS/resouce sharing etc). It feels like a good candidate for "it just works", where works is it trying to do the most "expected" behaviour.
This problem can be reproduced with the mbed and PC connected via USB serial (no hardware needed).
The code below is a simplification of the program referenced in this thread. The problem appears to be related to the first key press after a printf from within a timer handler (local echo and the Terminal class are not relevant).
When running the code, one should see the "!" character as the one shot in the timer handler triggers. After that, a key press (eg. the letter "a") is displayed along with the ">" character. Further key presses just result in the ">" character (with no echo). When the one shot is reset with the "r" key, a "!" should be displayed and then the next key press results in an echo (and the ">"). Further key presses just result in ">".
An example display is as follows: