Skip to content

Commit

Permalink
Add read with timeout to uart driver
Browse files Browse the repository at this point in the history
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 #1446

Signed-off-by: Winford <[email protected]>
  • Loading branch information
UncleGrumpy committed Feb 7, 2025
1 parent 2f9a4bc commit 38b751a
Showing 1 changed file with 23 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/platforms/esp32/components/avm_builtins/uart_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ static const AtomStringIntPair cmd_table[] = {
{ ATOM_STR("\x4", "read"), UARTReadCmd },
{ ATOM_STR("\x5", "write"), UARTWriteCmd },
{ ATOM_STR("\x5", "close"), UARTCloseCmd },
{ ATOM_STR("\xB", "cancel_read"), UARTCancelCmd },
SELECT_INT_DEFAULT(UARTInvalidCmd)
};

Expand Down Expand Up @@ -384,6 +385,23 @@ static void uart_driver_do_read(Context *ctx, GenMessage gen_message)
}
}

static void uart_driver_do_cancel_read(Context *ctx, GenMessage gen_message)
{
struct UARTData *uart_data = ctx->platform_data;

safe_update_reader_data(uart_data, NO_READER, NO_REF);

term pid = gen_message.pid;
term ref = gen_message.ref;

if (UNLIKELY(memory_ensure_free_with_roots(ctx, TUPLE_SIZE(2), 1, &ref, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) {
ESP_LOGE(TAG, "[uart_driver_do_read] Failed to allocate space for return value");
globalcontext_send_message(ctx->global, term_to_local_process_id(pid), OUT_OF_MEMORY_ATOM);
}

port_send_reply(ctx, pid, ref, OK_ATOM);
}

static void uart_driver_do_write(Context *ctx, GenMessage gen_message)
{
GlobalContext *glb = ctx->global;
Expand Down Expand Up @@ -523,6 +541,11 @@ static NativeHandlerResult uart_driver_consume_mailbox(Context *ctx)
is_closed = true;
break;

case UARTCancelCmd:
TRACE("cancel_read\n");
uart_driver_do_cancel_read(ctx, gen_message);
break;

default:
TRACE("uart: error: unrecognized command.\n");
}
Expand Down

0 comments on commit 38b751a

Please sign in to comment.