Skip to content

Commit 02ddd19

Browse files
committed
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 80d0d2c commit 02ddd19

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

drivers/serial/uart_native_pty.c

+89
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ 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+
K_KERNEL_STACK_MEMBER(rx_stack, CONFIG_ARCH_POSIX_RECOMMENDED_STACK_SIZE);
5964
} async;
6065
#endif /* CONFIG_UART_ASYNC_API */
6166
};
@@ -70,6 +75,9 @@ static int np_uart_callback_set(const struct device *dev, uart_callback_t callba
7075
void *user_data);
7176
static int np_uart_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout);
7277
static int np_uart_tx_abort(const struct device *dev);
78+
static int np_uart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len);
79+
static int np_uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout);
80+
static int np_uart_rx_disable(const struct device *dev);
7381
#endif /* CONFIG_UART_ASYNC_API */
7482

7583
static DEVICE_API(uart, np_uart_driver_api) = {
@@ -79,6 +87,9 @@ static DEVICE_API(uart, np_uart_driver_api) = {
7987
.callback_set = np_uart_callback_set,
8088
.tx = np_uart_tx,
8189
.tx_abort = np_uart_tx_abort,
90+
.rx_buf_rsp = np_uart_rx_buf_rsp,
91+
.rx_enable = np_uart_rx_enable,
92+
.rx_disable = np_uart_rx_disable,
8293
#endif /* CONFIG_UART_ASYNC_API */
8394
};
8495

@@ -294,6 +305,84 @@ static int np_uart_tx_abort(const struct device *dev)
294305
return k_work_cancel_delayable_sync(&data->async.tx_done, &sync) ? 0 : -EFAULT;
295306
}
296307

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

299388

0 commit comments

Comments
 (0)