Skip to content

Commit 082eaee

Browse files
committed
Add read with timeout to uart driver
Adds a new uart:read/2 that takes a timeout parameter for reads. If no data is received during the timeout period `timeout` is returned, and the listener is removed allowing for another read without getting the `{error, ealready}` error tuple. Closes atomvm#1446 Signed-off-by: Winford <[email protected]>
1 parent 06d5e26 commit 082eaee

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

src/platforms/esp32/components/avm_builtins/uart_driver.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static const AtomStringIntPair cmd_table[] = {
103103
{ ATOM_STR("\x4", "read"), UARTReadCmd },
104104
{ ATOM_STR("\x5", "write"), UARTWriteCmd },
105105
{ ATOM_STR("\x5", "close"), UARTCloseCmd },
106+
{ ATOM_STR("\xB", "cancel_read"), UARTCancelCmd },
106107
SELECT_INT_DEFAULT(UARTInvalidCmd)
107108
};
108109

@@ -394,6 +395,23 @@ static void uart_driver_do_read(Context *ctx, GenMessage gen_message)
394395
}
395396
}
396397

398+
static void uart_driver_do_cancel_read(Context *ctx, GenMessage gen_message)
399+
{
400+
struct UARTData *uart_data = ctx->platform_data;
401+
402+
safe_update_reader_data(uart_data, NO_READER, NO_REF);
403+
404+
term pid = gen_message.pid;
405+
term ref = gen_message.ref;
406+
407+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
408+
ESP_LOGE(TAG, "[uart_driver_do_read] Failed to allocate space for return value");
409+
globalcontext_send_message(ctx->global, term_to_local_process_id(pid), OUT_OF_MEMORY_ATOM);
410+
}
411+
412+
port_send_reply(ctx, pid, ref, OK_ATOM);
413+
}
414+
397415
static void uart_driver_do_write(Context *ctx, GenMessage gen_message)
398416
{
399417
GlobalContext *glb = ctx->global;
@@ -533,6 +551,11 @@ static NativeHandlerResult uart_driver_consume_mailbox(Context *ctx)
533551
is_closed = true;
534552
break;
535553

554+
case UARTCancelCmd:
555+
TRACE("cancel_read\n");
556+
uart_driver_do_cancel_read(ctx, gen_message);
557+
break;
558+
536559
default:
537560
TRACE("uart: error: unrecognized command.\n");
538561
}

0 commit comments

Comments
 (0)