Skip to content

Commit 92a6bb0

Browse files
committed
pbio/platform/sim_hub: Set and reset terminal settings from main.
This makes more sense as the entry and exit point.
1 parent 7360359 commit 92a6bb0

File tree

2 files changed

+57
-57
lines changed

2 files changed

+57
-57
lines changed

lib/pbio/drv/bluetooth/bluetooth_simulation.c

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
#if PBDRV_CONFIG_BLUETOOTH_SIMULATION
77

88
#include <errno.h>
9-
#include <fcntl.h>
109
#include <signal.h>
1110
#include <stdio.h>
1211
#include <stdlib.h>
13-
#include <termios.h>
1412
#include <unistd.h>
1513

1614
#include "bluetooth.h"
@@ -132,6 +130,8 @@ pbio_error_t pbdrv_bluetooth_controller_initialize(pbio_os_state_t *state, pbio_
132130

133131
static void pbdrv_bluetooth_simulation_tick_handler() {
134132
uint8_t buf[256 + STDIN_HEADER_SIZE];
133+
134+
// This has been made non-blocking in platform.c.
135135
ssize_t r = read(STDIN_FILENO, buf + STDIN_HEADER_SIZE, sizeof(buf) - STDIN_HEADER_SIZE);
136136

137137
if (r > 0) {
@@ -170,59 +170,7 @@ static pbio_error_t pbdrv_bluetooth_simulation_process_thread(pbio_os_state_t *s
170170
return bluetooth_thread_err;
171171
}
172172

173-
static struct termios oldt;
174-
175-
static void restore_terminal_settings(void) {
176-
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
177-
}
178-
179-
static void handle_signal(int sig) {
180-
restore_terminal_settings();
181-
signal(sig, SIG_DFL);
182-
raise(sig);
183-
}
184-
185173
void pbdrv_bluetooth_init_hci(void) {
186-
struct termios newt;
187-
188-
// Save the original terminal settings
189-
if (tcgetattr(STDIN_FILENO, &oldt) != 0) {
190-
printf("DEBUG: Failed to get terminal attributes\n");
191-
return;
192-
}
193-
194-
// Register the cleanup function to restore terminal settings on exit
195-
atexit(restore_terminal_settings);
196-
signal(SIGINT, handle_signal);
197-
signal(SIGTERM, handle_signal);
198-
199-
newt = oldt;
200-
201-
// Get one char at a time instead of newline and disable CTRL+C for exit.
202-
newt.c_lflag &= ~(ICANON | ECHO | ISIG);
203-
204-
// MicroPython REPL expects \r for newline.
205-
newt.c_iflag |= INLCR;
206-
newt.c_iflag &= ~ICRNL;
207-
208-
if (tcsetattr(STDIN_FILENO, TCSANOW, &newt) != 0) {
209-
printf("Failed to set terminal attributes\n");
210-
return;
211-
}
212-
213-
// Set stdin non-blocking so we can service it in the runloop like on
214-
// embedded hubs.
215-
int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
216-
if (flags == -1) {
217-
printf("Failed to get fcntl flags\n");
218-
return;
219-
}
220-
221-
if (fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK) == -1) {
222-
printf("Failed to set non-blocking\n");
223-
return;
224-
}
225-
226174
bluetooth_thread_err = PBIO_ERROR_AGAIN;
227175
bluetooth_thread_state = 0;
228176
pbio_os_process_start(&pbdrv_bluetooth_simulation_process, pbdrv_bluetooth_simulation_process_thread, NULL);

lib/pbio/platform/sim_hub/platform.c

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
// SPDX-License-Identifier: MIT
22
// Copyright (c) 2025 The Pybricks Authors
33

4+
#include <errno.h>
5+
#include <fcntl.h>
6+
#include <signal.h>
47
#include <stdio.h>
8+
#include <stdlib.h>
9+
#include <termios.h>
10+
#include <unistd.h>
511

612
#include "../../drv/motor_driver/motor_driver_virtual_simulation.h"
713

@@ -133,11 +139,9 @@ const pbdrv_motor_driver_virtual_simulation_platform_data_t
133139
},
134140
};
135141

136-
extern uint8_t pbsys_hmi_native_program_buf[PBDRV_CONFIG_BLOCK_DEVICE_RAM_SIZE];
137-
extern uint32_t pbsys_hmi_native_program_size;
138-
139142
int main(int argc, char **argv) {
140143

144+
// Parse given program, else otherwise default to REPL.
141145
if (argc > 1) {
142146

143147
// Pybricksdev helper script, pipes multi-mpy to us.
@@ -150,6 +154,8 @@ int main(int argc, char **argv) {
150154
}
151155

152156
// Read the multi-mpy file from pipe.
157+
extern uint8_t pbsys_hmi_native_program_buf[PBDRV_CONFIG_BLOCK_DEVICE_RAM_SIZE];
158+
extern uint32_t pbsys_hmi_native_program_size;
153159
pbsys_hmi_native_program_size = fread(pbsys_hmi_native_program_buf, 1, sizeof(pbsys_hmi_native_program_buf), pipe);
154160
pclose(pipe);
155161

@@ -159,6 +165,52 @@ int main(int argc, char **argv) {
159165
}
160166
}
161167

168+
// Save the original terminal settings
169+
struct termios term_old, term_new;
170+
if (tcgetattr(STDIN_FILENO, &term_old) != 0) {
171+
printf("DEBUG: Failed to get terminal attributes\n");
172+
return 0;
173+
}
174+
term_new = term_old;
175+
176+
// Get one char at a time instead of newline and disable CTRL+C for exit.
177+
term_new.c_lflag &= ~(ICANON | ECHO | ISIG);
178+
179+
// MicroPython REPL expects \r for newline.
180+
term_new.c_iflag |= INLCR;
181+
term_new.c_iflag &= ~ICRNL;
182+
183+
if (tcsetattr(STDIN_FILENO, TCSANOW, &term_new) != 0) {
184+
printf("Failed to set terminal attributes\n");
185+
return 0;
186+
}
187+
188+
// Set stdin non-blocking so we can service it in the runloop like on
189+
// embedded hubs.
190+
int stdin_flags = fcntl(STDIN_FILENO, F_GETFL, 0);
191+
if (stdin_flags == -1) {
192+
printf("Failed to get fcntl flags\n");
193+
return 0;
194+
}
195+
if (fcntl(STDIN_FILENO, F_SETFL, stdin_flags | O_NONBLOCK) == -1) {
196+
printf("Failed to set non-blocking\n");
197+
return 0;
198+
}
199+
200+
// Runs the 'embedded' main.
162201
extern void _main(void);
163202
_main();
203+
204+
// Restore stdin flags.
205+
if (fcntl(STDIN_FILENO, F_SETFL, stdin_flags) == -1) {
206+
printf("Failed to restore stdin flags\n");
207+
}
208+
209+
// Restore terminal settings.
210+
if (tcsetattr(STDIN_FILENO, TCSANOW, &term_old) != 0) {
211+
printf("Failed to restore terminal attributes\n");
212+
return 0;
213+
}
214+
215+
return 0;
164216
}

0 commit comments

Comments
 (0)