Skip to content

Commit 5fac4de

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 f72a828 commit 5fac4de

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
};
@@ -65,11 +70,16 @@ static int np_uart_poll_in(const struct device *dev, unsigned char *p_char);
6570
static int np_uart_init(const struct device *dev);
6671

6772
#ifdef CONFIG_UART_ASYNC_API
73+
void native_pty_uart_async_poll_function(void *arg1, void *arg2, void *arg3);
74+
6875
static void np_uart_tx_done_work(struct k_work *work);
6976
static int np_uart_callback_set(const struct device *dev, uart_callback_t callback,
7077
void *user_data);
7178
static int np_uart_tx(const struct device *dev, const uint8_t *buf, size_t len, int32_t timeout);
7279
static int np_uart_tx_abort(const struct device *dev);
80+
static int np_uart_rx_buf_rsp(const struct device *dev, uint8_t *buf, size_t len);
81+
static int np_uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout);
82+
static int np_uart_rx_disable(const struct device *dev);
7383
#endif /* CONFIG_UART_ASYNC_API */
7484

7585
static DEVICE_API(uart, np_uart_driver_api) = {
@@ -79,6 +89,9 @@ static DEVICE_API(uart, np_uart_driver_api) = {
7989
.callback_set = np_uart_callback_set,
8090
.tx = np_uart_tx,
8191
.tx_abort = np_uart_tx_abort,
92+
.rx_buf_rsp = np_uart_rx_buf_rsp,
93+
.rx_enable = np_uart_rx_enable,
94+
.rx_disable = np_uart_rx_disable,
8295
#endif /* CONFIG_UART_ASYNC_API */
8396
};
8497

@@ -294,6 +307,82 @@ static int np_uart_tx_abort(const struct device *dev)
294307
return k_work_cancel_delayable_sync(&data->async.tx_done, &sync) ? 0 : -EFAULT;
295308
}
296309

310+
/*
311+
* Emulate async interrupts using a polling thread
312+
*/
313+
void native_pty_uart_async_poll_function(void *arg1, void *arg2, void *arg3)
314+
{
315+
const struct device *dev = arg1;
316+
struct native_pty_status *data = dev->data;
317+
struct uart_event evt;
318+
int rc;
319+
320+
ARG_UNUSED(arg2);
321+
ARG_UNUSED(arg3);
322+
323+
while (data->async.rx_len) {
324+
if (data->async.rx_len > 0) {
325+
rc = np_uart_stdin_poll_in_bottom(data->in_fd, data->async.rx_buf, data->async.rx_len);
326+
if (rc > 0) {
327+
/* Data received */
328+
evt.type = UART_RX_RDY;
329+
evt.data.rx.buf = data->async.rx_buf;
330+
evt.data.rx.offset = 0;
331+
evt.data.rx.len = rc;
332+
/* User callback */
333+
data->async.user_callback(data->async.dev, &evt, data->async.user_data);
334+
}
335+
}
336+
if ((data->async.rx_len == 0) || (rc < 0)) {
337+
/* Sleep if RX disabled or 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,
350+
int32_t timeout)
351+
{
352+
struct native_pty_status *data = dev->data;
353+
354+
ARG_UNUSED(timeout);
355+
356+
if (data->async.rx_buf != NULL) {
357+
return -EBUSY;
358+
}
359+
360+
data->async.rx_buf = buf;
361+
data->async.rx_len = len;
362+
363+
/* Create a thread which will wait for data - replacement for IRQ */
364+
k_thread_create(&data->async.rx_thread, data->async.rx_stack, 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)