Skip to content

Commit ebd168f

Browse files
authored
Make syscalls bus runtime setable (#149)
1 parent a60c944 commit ebd168f

File tree

9 files changed

+162
-212
lines changed

9 files changed

+162
-212
lines changed

src/platform/h563xx/platform.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,7 @@ void PLATFORM_init(void)
198198

199199
system_clock_config();
200200

201-
LOG_init();
202-
LOG_LL_INFO("Platform hardware initialized");
201+
LOG_INFO("Platform hardware initialized");
203202
}
204203

205204
/**

src/system/README.md

Lines changed: 0 additions & 65 deletions
This file was deleted.

src/system/bus/uart.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,8 @@
3232
#include "util/error.h"
3333
#include "util/util.h"
3434

35-
#include "syscalls_config.h"
3635
#include "uart.h"
3736

38-
/* syscalls module sets this when claiming its bus */
39-
extern bool g_SYSCALLS_uart_claim;
40-
4137
/**
4238
* @brief UART bus handle structure
4339
*/
@@ -247,14 +243,6 @@ UART_Handle *UART_init(
247243
THROW(ERROR_INVALID_ARGUMENT);
248244
}
249245

250-
/* Check if syscalls is claiming the UART */
251-
#if defined(SYSCALLS_UART_BUS) && SYSCALLS_UART_BUS >= 0
252-
if (bus == SYSCALLS_UART_BUS && !g_SYSCALLS_uart_claim) {
253-
/* Only syscalls can claim this bus */
254-
THROW(ERROR_RESOURCE_UNAVAILABLE);
255-
}
256-
#endif
257-
258246
UART_Bus bus_id = (UART_Bus)bus;
259247

260248
/* Check if bus is already initialized */

src/system/syscalls.c

Lines changed: 25 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,13 @@
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>
@@ -39,26 +29,14 @@
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
5439
static 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

6341
static 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

11086
bool 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;

src/system/syscalls_config.h

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/system/system.c

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,43 @@
77
* other hardware access.
88
*/
99

10+
#include <stddef.h>
11+
#include <stdint.h>
12+
1013
#include "platform/platform.h"
1114
#include "platform/uart_ll.h"
1215
#include "util/error.h"
1316
#include "util/logging.h"
1417
#include "util/si_prefix.h"
18+
#include "util/util.h"
1519

20+
#include "bus/uart.h"
1621
#include "led.h"
17-
#include "syscalls_config.h"
1822
#include "system.h"
1923

24+
// Global variables for logging
25+
static UART_Handle *g_logging_uart_handle = nullptr;
26+
static uint8_t g_log_buf[1024];
27+
static uint8_t g_log_rx_buf[1];
28+
static CircularBuffer g_log_cb;
29+
static CircularBuffer g_log_rx_cb;
30+
2031
void SYSTEM_init(void)
2132
{
33+
// Initialize logging early to capture any log messages during startup
34+
LOG_init();
2235
PLATFORM_init();
23-
// Read any logs that were generated during platform initialization
24-
unsigned const max_log_entries = 32;
25-
LOG_task(max_log_entries);
36+
37+
// Set up log output
38+
circular_buffer_init(&g_log_cb, g_log_buf, sizeof(g_log_buf));
39+
circular_buffer_init(&g_log_rx_cb, g_log_rx_buf, sizeof(g_log_rx_buf));
40+
uint8_t log_bus = 2;
41+
g_logging_uart_handle = UART_init(log_bus, &g_log_rx_cb, &g_log_cb);
42+
extern void syscalls_init(UART_Handle * handle);
43+
syscalls_init(g_logging_uart_handle);
44+
// Buffered log messages can now be output with LOG_task
45+
LOG_task(0xFF);
46+
2647
LED_init();
2748
}
2849

@@ -35,8 +56,7 @@ __attribute__((noreturn)) void SYSTEM_reset(void)
3556
// Flush any pending log messages
3657
LOG_task(UINT32_MAX);
3758
unsigned const bits_per_uart_byte = 10;
38-
uint64_t const buffer_size_bits =
39-
(uint64_t)SYSCALLS_UART_TX_BUFFER_SIZE * bits_per_uart_byte;
59+
size_t const buffer_size_bits = sizeof(g_log_buf) * bits_per_uart_byte;
4060
// Timeout to wait for TX buffer to empty (2x time for safety)
4161
uint32_t timeout =
4262
((buffer_size_bits * SI_MILLI_DIV * 2) / UART_DEFAULT_BAUDRATE);

tests/test_headers/errno.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,26 @@
44
/**
55
* @file errno.h
66
* @brief Test replacement for system errno.h
7-
*
7+
*
88
* This file provides minimal error code definitions for testing.
99
*/
1010

1111
// Error codes
12-
#define EBADF 9 // Bad file descriptor
13-
#define EIO 5 // I/O error
14-
#define ENOSYS 38 // Function not implemented
15-
#define EAGAIN 11 // Resource temporarily unavailable
16-
#define EFAULT 14 // Bad address
17-
#define ENOTTY 25 // Not a terminal
12+
#define EBADF 9 // Bad file descriptor
13+
#define EIO 5 // I/O error
14+
#define ENOSYS 38 // Function not implemented
15+
#define EAGAIN 11 // Resource temporarily unavailable
16+
#define EFAULT 14 // Bad address
17+
#define ENOTTY 25 // Not a terminal
18+
#define EINVAL 22 // Invalid argument
19+
#define ENOMEM 12 // Out of memory
20+
#define ETIMEDOUT 110 // Connection timed out
21+
#define EBUSY 16 // Device or resource busy
22+
#define EDOM 33 // Math argument out of domain
23+
#define ERANGE 34 // Math result not representable
24+
#define ENODEV 19 // No such device
25+
#define ENXIO 6 // No such device or address
26+
#define EWOULDBLOCK EAGAIN // Operation would block
1827

1928
// Forward errno to our fake reent
2029
#define errno (__impure_ptr->_errno)

0 commit comments

Comments
 (0)