Skip to content

Commit 9bbc6d1

Browse files
JordanYateskartben
authored andcommitted
serial: uart_native_pty: ASYNC RX support
Add support for transmitting using the asynchronous API. The asynchronous portion is simulated through a dedicated polling thread. Signed-off-by: Jordan Yates <[email protected]>
1 parent 5536e5b commit 9bbc6d1

File tree

1 file changed

+90
-0
lines changed

1 file changed

+90
-0
lines changed

drivers/serial/uart_native_pty.c

+90
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ struct native_pty_status {
5656
void *user_data;
5757
const uint8_t *tx_buf;
5858
size_t tx_len;
59+
uint8_t *rx_buf;
60+
size_t rx_len;
61+
/* Instance-specific RX thread. */
62+
struct k_thread rx_thread;
63+
/* Stack for RX thread */
64+
K_KERNEL_STACK_MEMBER(rx_stack, CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE);
5965
} async;
6066
#endif /* CONFIG_UART_ASYNC_API */
6167
};
@@ -70,6 +76,9 @@ static int np_uart_callback_set(const struct device *dev, uart_callback_t callba
7076
void *user_data);
7177
static int np_uart_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout);
7278
static int np_uart_tx_abort(const struct device *dev);
79+
static int np_uart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len);
80+
static int np_uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout);
81+
static int np_uart_rx_disable(const struct device *dev);
7382
#endif /* CONFIG_UART_ASYNC_API */
7483

7584
static DEVICE_API(uart, np_uart_driver_api) = {
@@ -79,6 +88,9 @@ static DEVICE_API(uart, np_uart_driver_api) = {
7988
.callback_set = np_uart_callback_set,
8089
.tx = np_uart_tx,
8190
.tx_abort = np_uart_tx_abort,
91+
.rx_buf_rsp = np_uart_rx_buf_rsp,
92+
.rx_enable = np_uart_rx_enable,
93+
.rx_disable = np_uart_rx_disable,
8294
#endif /* CONFIG_UART_ASYNC_API */
8395
};
8496

@@ -311,6 +323,84 @@ static int np_uart_tx_abort(const struct device *dev)
311323
return 0;
312324
}
313325

326+
/*
327+
* Emulate async interrupts using a polling thread
328+
*/
329+
static void native_pty_uart_async_poll_function(void *arg1, void *arg2, void *arg3)
330+
{
331+
const struct device *dev = arg1;
332+
struct native_pty_status *data = dev->data;
333+
struct uart_event evt;
334+
int rc;
335+
336+
ARG_UNUSED(arg2);
337+
ARG_UNUSED(arg3);
338+
339+
while (data->async.rx_len) {
340+
rc = np_uart_stdin_poll_in_bottom(data->in_fd, data->async.rx_buf,
341+
data->async.rx_len);
342+
if (rc > 0) {
343+
/* Data received */
344+
evt.type = UART_RX_RDY;
345+
evt.data.rx.buf = data->async.rx_buf;
346+
evt.data.rx.offset = 0;
347+
evt.data.rx.len = rc;
348+
/* User callback */
349+
if (data->async.user_callback) {
350+
data->async.user_callback(data->async.dev, &evt,
351+
data->async.user_data);
352+
}
353+
}
354+
if ((data->async.rx_len != 0) && (rc < 0)) {
355+
/* Sleep if RX not disabled and last read didn't result in any data */
356+
k_sleep(K_MSEC(10));
357+
}
358+
}
359+
}
360+
361+
static int np_uart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len)
362+
{
363+
/* Driver never requests additional buffers */
364+
return -ENOTSUP;
365+
}
366+
367+
static int np_uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout)
368+
{
369+
struct native_pty_status *data = dev->data;
370+
371+
ARG_UNUSED(timeout);
372+
373+
if (data->async.rx_buf != NULL) {
374+
return -EBUSY;
375+
}
376+
377+
data->async.rx_buf = buf;
378+
data->async.rx_len = len;
379+
380+
/* Create a thread which will wait for data - replacement for IRQ */
381+
k_thread_create(&data->async.rx_thread, data->async.rx_stack,
382+
K_KERNEL_STACK_SIZEOF(data->async.rx_stack),
383+
native_pty_uart_async_poll_function,
384+
(void *)dev, NULL, NULL,
385+
K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT);
386+
return 0;
387+
}
388+
389+
static int np_uart_rx_disable(const struct device *dev)
390+
{
391+
struct native_pty_status *data = dev->data;
392+
393+
if (data->async.rx_buf == NULL) {
394+
return -EFAULT;
395+
}
396+
397+
data->async.rx_len = 0;
398+
data->async.rx_buf = NULL;
399+
400+
/* Wait for RX thread to terminate */
401+
return k_thread_join(&data->async.rx_thread, K_FOREVER);
402+
}
403+
314404
#endif /* CONFIG_UART_ASYNC_API */
315405

316406

0 commit comments

Comments
 (0)