I am writing an embedded application for MCU (STM32), and I encounter this problem of async programming.
I would like to show you 2 cases, the first case is to use a blocking call, to send data
//blocking function call, send data and wait for data receive in a loop
int uart_send_sync(char *data)
{
uart_send("ATDR\n");
while (uart_receive()) {
uart_get_data(buffer);
//parse
return status;
}
return -1;
}
int status_A = uart_send_sync("ATSA\n");
int status_B = uart_send_sync("ATSB\n");
The above example is a blocking call, I could easily write a neat and simple uart_send
code to get the parse respond (status_A
and status_B
).
But, this method, is not idle, as the MCU will be wasting resources idling in the loop to wait for respond.
The example below is to use async way (interupt) to send the data. But, doing so creates a big problem, I will not able to get my status_A
and status_B
in sequence.
//Send async data to uart using interupt
uart_send("ATSA\n");
//Send async data to uart using interupt
uart_send("ATSB\n");
//Interupt handler from MCU
uart_IRQ_handler(void)
{
//set flag so the main loop is notify
//store data in ring buffer, and retrieve the data from main loop
gi_uart_rcv = true;
}
//main loop
while(true) {
// notify when uart rcv data
if(gi_uart_rcv) {
//get data
uart_get_data(buffer);
//parse data
}
}
To solve this problem, I could use a state machine, to track for my status_A
and status_B
but this implementation is very messy.
May I know how can I achieve a better implementation of async in embedded system?
gi_uart_rcv
becomesfalse
is the gorilla in the living room. It is the race condition on that variable therein lies code's problems. In short: I do not see posted code as working and thus not re-viewable. – chux 2 days agogi_uart_rcv
to synchronize async and sync events. How it is set and tested is central to this code's synchronize scheme. – chux yesterday