1414 * - _isatty_r: Terminal check (stub - treats stdout/stderr as terminals,
1515 * stdin as not a terminal)
1616 *
17- * The UART bus used for I/O can be configured via the SYSCALLS_UART_BUS
18- * preprocessor macro:
19- * - Define SYSCALLS_UART_BUS to specify the UART bus number (0, 1, 2, etc.)
20- * - Define SYSCALLS_UART_BUS as -1 or leave undefined to disable UART I/O
21- * (functions will be no-ops returning error codes)
22- *
23- * Buffer size for TX can be configured via:
24- * - SYSCALLS_UART_TX_BUFFER_SIZE (default: 256)
17+ * Usage:
18+ * Call syscalls_init() with an initialized UART_Handle pointer to enable
19+ * stdout/stderr output. Until syscalls_init() is called, _write_r will
20+ * return EBADF.
2521 *
2622 * Note: RX functionality is not implemented as this is designed for
27- * write-only logging and debugging output. A minimal 1-byte RX buffer
28- * is allocated to satisfy the UART driver requirements, but reads will
29- * always return ENOSYS.
30- *
31- * Example configuration:
32- * #define SYSCALLS_UART_BUS 0
33- * #define SYSCALLS_UART_TX_BUFFER_SIZE 512
23+ * write-only logging and debugging output. Reads will always return ENOSYS.
3424 */
3525
3626#include <errno.h>
3929#include <sys/stat.h>
4030#include <unistd.h>
4131
32+ #include "util/error.h"
4233#include "util/util.h"
4334
44- #include "syscalls_config.h"
45-
46- // Only include UART headers if UART I/O is enabled
47- #if SYSCALLS_UART_BUS >= 0
35+ // Include UART headers for handle type
4836#include "system/bus/uart.h"
4937
50- // Minimal RX buffer (required by UART driver)
51- #define SYSCALLS_UART_RX_BUFFER_SIZE 1
52-
53- // Static buffers and handle for UART I/O
38+ // Static handle for UART I/O
5439static UART_Handle * g_uart_handle = nullptr ;
55- static CircularBuffer g_rx_buffer , g_tx_buffer ;
56- static uint8_t g_rx_data [SYSCALLS_UART_RX_BUFFER_SIZE ];
57- static uint8_t g_tx_data [SYSCALLS_UART_TX_BUFFER_SIZE ];
58- static bool g_uart_initialized = false;
59-
60- // Set to tell UART driver that syscalls is claiming the UART bus
61- bool g_SYSCALLS_uart_claim = false;
6240
6341static int check_args (struct _reent * r , void const * buf , size_t cnt )
6442{
@@ -76,43 +54,37 @@ static int check_args(struct _reent *r, void const *buf, size_t cnt)
7654}
7755
7856/**
79- * @brief Initialize UART for syscalls (called automatically on first use)
57+ * @brief Initialize syscalls with a UART handle
58+ *
59+ * @param handle Pointer to an initialized UART handle to use for stdout/stderr
60+ * @throws ERROR_RESOURCE_BUSY if syscalls is already initialized
8061 */
81- static void syscalls_uart_init ( void )
62+ void syscalls_init ( UART_Handle * handle )
8263{
83- if (g_uart_initialized ) {
84- return ;
64+ if (g_uart_handle != nullptr ) {
65+ THROW ( ERROR_RESOURCE_BUSY ) ;
8566 }
86-
87- circular_buffer_init (& g_rx_buffer , g_rx_data , SYSCALLS_UART_RX_BUFFER_SIZE );
88- circular_buffer_init (& g_tx_buffer , g_tx_data , SYSCALLS_UART_TX_BUFFER_SIZE );
89-
90- g_SYSCALLS_uart_claim = true; // Claim UART for syscalls
91- g_uart_handle = UART_init (SYSCALLS_UART_BUS , & g_rx_buffer , & g_tx_buffer );
92- g_SYSCALLS_uart_claim = false; // Prevent further claims
93- g_uart_initialized = true;
67+ g_uart_handle = handle ;
9468}
9569
9670/**
97- * @brief Deinitialize UART for syscalls
71+ * @brief Deinitialize syscalls
9872 *
99- * @note This function is needed by tests.
73+ * Clears the UART handle, disabling stdout/stderr output.
74+ *
75+ * @param handle Pointer to the UART handle that was used to initialize syscalls
76+ * @throws ERROR_INVALID_ARGUMENT if handle doesn't match the initialized handle
10077 */
101- void syscalls_uart_deinit ( void )
78+ void syscalls_deinit ( UART_Handle * handle )
10279{
103- if (g_uart_handle != nullptr ) {
104- UART_deinit (g_uart_handle );
105- g_uart_handle = nullptr ;
80+ if (g_uart_handle != handle ) {
81+ THROW (ERROR_INVALID_ARGUMENT );
10682 }
107- g_uart_initialized = false ;
83+ g_uart_handle = nullptr ;
10884}
10985
11086bool syscalls_uart_flush (uint32_t timeout )
11187{
112- if (!g_uart_initialized ) {
113- syscalls_uart_init ();
114- }
115-
11688 if (g_uart_handle == nullptr ) {
11789 return false;
11890 }
@@ -121,8 +93,6 @@ bool syscalls_uart_flush(uint32_t timeout)
12193 return UART_flush (g_uart_handle , timeout );
12294}
12395
124- #endif /* SYSCALLS_UART_BUS >= 0 */
125-
12696/**
12797 * @brief Read data from file descriptor (stub - reads not supported)
12898 *
@@ -163,12 +133,7 @@ _ssize_t _write_r(struct _reent *r, int fd, void const *buf, size_t cnt)
163133 return ret ;
164134 }
165135
166- #if SYSCALLS_UART_BUS >= 0
167136 if (fd == STDOUT_FILENO || fd == STDERR_FILENO ) {
168- if (!g_uart_initialized ) {
169- syscalls_uart_init ();
170- }
171-
172137 if (g_uart_handle == nullptr ) {
173138 r -> _errno = EIO ;
174139 return -1 ;
@@ -186,9 +151,6 @@ _ssize_t _write_r(struct _reent *r, int fd, void const *buf, size_t cnt)
186151
187152 return (_ssize_t )bytes_written ;
188153 }
189- #else
190- (void )fd ;
191- #endif
192154
193155 r -> _errno = EBADF ;
194156 return -1 ;
0 commit comments