14
14
#endif
15
15
16
16
#include <stdbool.h>
17
+ #include <signal.h>
17
18
#include <zephyr/drivers/uart.h>
18
19
#include <zephyr/kernel.h>
19
20
#include <cmdline.h> /* native_sim command line options header */
@@ -56,6 +57,8 @@ struct native_pty_status {
56
57
void * user_data ;
57
58
const uint8_t * tx_buf ;
58
59
size_t tx_len ;
60
+ uint8_t * rx_buf ;
61
+ size_t rx_len ;
59
62
} async ;
60
63
#endif /* CONFIG_UART_ASYNC_API */
61
64
};
@@ -70,6 +73,10 @@ static int np_uart_callback_set(const struct device *dev, uart_callback_t callba
70
73
void * user_data );
71
74
static int np_uart_tx (const struct device * dev , const uint8_t * buf , size_t len , int32_t timeout );
72
75
static int np_uart_tx_abort (const struct device * dev );
76
+ static int np_uart_rx_buf_rsp (const struct device * dev , uint8_t * buf , size_t len );
77
+ static int np_uart_rx_enable (const struct device * dev , uint8_t * buf , size_t len , int32_t timeout );
78
+ static int np_uart_rx_disable (const struct device * dev );
79
+ static void sigio_handler (int status );
73
80
#endif /* CONFIG_UART_ASYNC_API */
74
81
75
82
static DEVICE_API (uart , np_uart_driver_api ) = {
@@ -79,6 +86,9 @@ static DEVICE_API(uart, np_uart_driver_api) = {
79
86
.callback_set = np_uart_callback_set ,
80
87
.tx = np_uart_tx ,
81
88
.tx_abort = np_uart_tx_abort ,
89
+ .rx_buf_rsp = np_uart_rx_buf_rsp ,
90
+ .rx_enable = np_uart_rx_enable ,
91
+ .rx_disable = np_uart_rx_disable ,
82
92
#endif /* CONFIG_UART_ASYNC_API */
83
93
};
84
94
@@ -143,7 +153,16 @@ static int np_uart_init(const struct device *dev)
143
153
}
144
154
145
155
#ifdef CONFIG_UART_ASYNC_API
156
+ static bool handler_installed ;
157
+
158
+ if (!handler_installed ) {
159
+ /* Install global SIGIO handler */
160
+ nsi_signal_handler_install (SIGIO , sigio_handler );
161
+ handler_installed = true;
162
+ }
146
163
k_work_init_delayable (& d -> async .tx_done , np_uart_tx_done_work );
164
+ /* Mark the file descriptor as async */
165
+ nsi_fd_async (d -> in_fd );
147
166
#endif
148
167
149
168
return 0 ;
@@ -296,6 +315,88 @@ static int np_uart_tx_abort(const struct device *dev)
296
315
return k_work_cancel_delayable_sync (& data -> async .tx_done , & sync ) ? 0 : - EFAULT ;
297
316
}
298
317
318
+ static void sigio_handler_dev (const struct device * dev )
319
+ {
320
+ struct native_pty_status * data = dev -> data ;
321
+ unsigned char fallback [8 ];
322
+ struct uart_event event ;
323
+ unsigned char * buf ;
324
+ long read ;
325
+ int len ;
326
+
327
+ /* Read data from the file even if it is disabled.
328
+ * This prevents data that was received while disabled from
329
+ * appearing at the output if it is enabled later.
330
+ */
331
+ if (data -> async .rx_len == 0 ) {
332
+ buf = fallback ;
333
+ len = sizeof (fallback );
334
+ } else {
335
+ buf = data -> async .rx_buf ;
336
+ len = data -> async .rx_len ;
337
+ }
338
+
339
+ /* Loop until there is no more data to be read */
340
+ while (1 ) {
341
+ read = np_uart_stdin_poll_in_bottom (data -> in_fd , buf , len );
342
+ if (read <= 0 ) {
343
+ break ;
344
+ }
345
+ if (data -> async .rx_len == 0 ) {
346
+ /* RX disabled, drop data */
347
+ continue ;
348
+ }
349
+
350
+ event .type = UART_RX_RDY ;
351
+ event .data .rx .buf = buf ;
352
+ event .data .rx .len = len ;
353
+ event .data .rx .offset = 0 ;
354
+
355
+ data -> async .user_callback (data -> async .dev , & event , data -> async .user_data );
356
+ }
357
+ }
358
+
359
+ #define NATIVE_PTY_SIGIO_HANDLER (inst ) \
360
+ sigio_handler_dev(DEVICE_DT_GET(DT_DRV_INST(inst)));
361
+
362
+ static void sigio_handler (int status )
363
+ {
364
+ DT_INST_FOREACH_STATUS_OKAY (NATIVE_PTY_SIGIO_HANDLER )
365
+ }
366
+
367
+ static int np_uart_rx_buf_rsp (const struct device * dev , uint8_t * buf , size_t len )
368
+ {
369
+ /* Driver never requests additional buffers */
370
+ return - ENOTSUP ;
371
+ }
372
+
373
+ static int np_uart_rx_enable (const struct device * dev , uint8_t * buf , size_t len ,
374
+ int32_t timeout )
375
+ {
376
+ struct native_pty_status * data = dev -> data ;
377
+
378
+ ARG_UNUSED (timeout );
379
+
380
+ data -> async .rx_buf = buf ;
381
+ data -> async .rx_len = len ;
382
+
383
+ return 0 ;
384
+ }
385
+
386
+ static int np_uart_rx_disable (const struct device * dev )
387
+ {
388
+ struct native_pty_status * data = dev -> data ;
389
+
390
+ if (data -> async .rx_buf == NULL ) {
391
+ return - EFAULT ;
392
+ }
393
+
394
+ data -> async .rx_buf = NULL ;
395
+ data -> async .rx_len = 0 ;
396
+
397
+ return 0 ;
398
+ }
399
+
299
400
#endif /* CONFIG_UART_ASYNC_API */
300
401
301
402
0 commit comments