Skip to content

Commit 5ac66d6

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 0d4f3a5 commit 5ac66d6

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
@@ -102,6 +102,7 @@ static const AtomStringIntPair cmd_table[] = {
102102
{ ATOM_STR("\x4", "read"), UARTReadCmd },
103103
{ ATOM_STR("\x5", "write"), UARTWriteCmd },
104104
{ ATOM_STR("\x5", "close"), UARTCloseCmd },
105+
{ ATOM_STR("\xB", "cancel_read"), UARTCancelCmd },
105106
SELECT_INT_DEFAULT(UARTInvalidCmd)
106107
};
107108

@@ -388,6 +389,23 @@ static void uart_driver_do_read(Context *ctx, GenMessage gen_message)
388389
}
389390
}
390391

392+
static void uart_driver_do_cancel_read(Context *ctx, GenMessage gen_message)
393+
{
394+
struct UARTData *uart_data = ctx->platform_data;
395+
396+
safe_update_reader_data(uart_data, NO_READER, NO_REF);
397+
398+
term pid = gen_message.pid;
399+
term ref = gen_message.ref;
400+
401+
if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
402+
ESP_LOGE(TAG, "[uart_driver_do_read] Failed to allocate space for return value");
403+
globalcontext_send_message(ctx->global, term_to_local_process_id(pid), OUT_OF_MEMORY_ATOM);
404+
}
405+
406+
port_send_reply(ctx, pid, ref, OK_ATOM);
407+
}
408+
391409
static void uart_driver_do_write(Context *ctx, GenMessage gen_message)
392410
{
393411
GlobalContext *glb = ctx->global;
@@ -527,6 +545,11 @@ static NativeHandlerResult uart_driver_consume_mailbox(Context *ctx)
527545
is_closed = true;
528546
break;
529547

548+
case UARTCancelCmd:
549+
TRACE("cancel_read\n");
550+
uart_driver_do_cancel_read(ctx, gen_message);
551+
break;
552+
530553
default:
531554
TRACE("uart: error: unrecognized command.\n");
532555
}

0 commit comments

Comments
 (0)