Skip to content

Commit 7b21778

Browse files
authored
Refactor to clean up and fix console handling (#3666)
* Refactor into new 'console' module. A breaking change, but should finally see us move away from the chronic edge cases and inconsistent behaviour we have while trying to shoe-horn the usb-serial-jtag and cdc-acm consoles into uart behaviour and assumptions. * Fix and document console.write() Added example on using framed data transmission over the console. * fixup uart examples * Add workaround for silently dropped console output. * Add file upload helper script for console module. Plus, it can serve as a reference for any IDEs which may need/want updating. * Fixup really silly copy/paste error. * Make upload-file.py work better on CDC-ACM console. * Updated console module doc with CDC-ACM info. * Load file in binary mode in upload-file.py.
1 parent 7c5bb15 commit 7b21778

File tree

13 files changed

+1171
-394
lines changed

13 files changed

+1171
-394
lines changed

components/base_nodemcu/user_main.c

+1-153
Original file line numberDiff line numberDiff line change
@@ -11,47 +11,18 @@
1111
#include "lua.h"
1212
#include "linput.h"
1313
#include "platform.h"
14-
#include <string.h>
15-
#include <stdlib.h>
16-
#include <fcntl.h>
1714
#include "sdkconfig.h"
1815
#include "esp_system.h"
1916
#include "esp_event.h"
2017
#include "esp_spiffs.h"
2118
#include "esp_netif.h"
22-
#include "esp_vfs_dev.h"
23-
#include "esp_vfs_cdcacm.h"
24-
#include "esp_vfs_usb_serial_jtag.h"
25-
#include "driver/usb_serial_jtag.h"
2619
#include "nvs_flash.h"
2720

2821
#include "task/task.h"
29-
#include "sections.h"
3022
#include "nodemcu_esp_event.h"
3123

3224
#include "freertos/FreeRTOS.h"
33-
#include "freertos/task.h"
34-
#include "freertos/queue.h"
35-
36-
#define SIG_LUA 0
37-
#define SIG_UARTINPUT 1
38-
39-
// Line ending config from Kconfig
40-
#if CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF
41-
# define RX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CRLF
42-
#elif CONFIG_NEWLIB_STDIN_LINE_ENDING_CR
43-
# define RX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CR
44-
#else
45-
# define RX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF
46-
#endif
47-
48-
#if CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF
49-
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CRLF
50-
#elif CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR
51-
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_CR
52-
#else
53-
# define TX_LINE_ENDINGS_CFG ESP_LINE_ENDINGS_LF
54-
#endif
25+
#include "freertos/semphr.h"
5526

5627

5728
// We don't get argument size data from the esp_event dispatch, so it's
@@ -71,8 +42,6 @@ typedef struct {
7142
static task_handle_t relayed_event_task;
7243
static SemaphoreHandle_t relayed_event_handled;
7344

74-
static task_handle_t lua_feed_task;
75-
7645

7746
// This function runs in the context of the system default event loop RTOS task
7847
static void relay_default_loop_events(
@@ -166,129 +135,10 @@ static void nodemcu_init(void)
166135
}
167136

168137

169-
static bool have_console_on_data_cb(void)
170-
{
171-
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
172-
return uart_has_on_data_cb(CONFIG_ESP_CONSOLE_UART_NUM);
173-
#else
174-
return false;
175-
#endif
176-
}
177-
178-
179-
static void console_nodemcu_task(task_param_t param, task_prio_t prio)
180-
{
181-
(void)prio;
182-
char c = (char)param;
183-
184-
if (run_input)
185-
feed_lua_input(&c, 1);
186-
187-
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
188-
if (have_console_on_data_cb())
189-
uart_feed_data(CONFIG_ESP_CONSOLE_UART_NUM, &c, 1);
190-
#endif
191-
192-
// The IDF doesn't seem to honor setvbuf(stdout, NULL, _IONBF, 0) :(
193-
fsync(fileno(stdout));
194-
}
195-
196-
197-
static void console_task(void *)
198-
{
199-
for (;;)
200-
{
201-
/* We can't use a large read buffer here as some console choices
202-
* (e.g. usb-serial-jtag) don't support read timeouts/partial reads,
203-
* which breaks the echo support and makes for a bad user experience.
204-
*/
205-
char c;
206-
ssize_t n = read(fileno(stdin), &c, 1);
207-
if (n > 0 && (run_input || have_console_on_data_cb()))
208-
{
209-
if (!task_post_block_high(lua_feed_task, (task_param_t)c))
210-
{
211-
NODE_ERR("Lost console input data?!\n");
212-
}
213-
}
214-
}
215-
}
216-
217-
218-
static void console_init(void)
219-
{
220-
fflush(stdout);
221-
fsync(fileno(stdout));
222-
223-
/* Disable buffering */
224-
setvbuf(stdin, NULL, _IONBF, 0);
225-
setvbuf(stdout, NULL, _IONBF, 0);
226-
227-
/* Disable non-blocking mode */
228-
fcntl(fileno(stdin), F_SETFL, 0);
229-
fcntl(fileno(stdout), F_SETFL, 0);
230-
231-
#if CONFIG_ESP_CONSOLE_UART_DEFAULT || CONFIG_ESP_CONSOLE_UART_CUSTOM
232-
/* Based on console/advanced example */
233-
234-
esp_vfs_dev_uart_port_set_rx_line_endings(
235-
CONFIG_ESP_CONSOLE_UART_NUM, RX_LINE_ENDINGS_CFG);
236-
esp_vfs_dev_uart_port_set_tx_line_endings(
237-
CONFIG_ESP_CONSOLE_UART_NUM, TX_LINE_ENDINGS_CFG);
238-
239-
/* Configure UART. Note that REF_TICK is used so that the baud rate remains
240-
* correct while APB frequency is changing in light sleep mode.
241-
*/
242-
const uart_config_t uart_config = {
243-
.baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,
244-
.data_bits = UART_DATA_8_BITS,
245-
.parity = UART_PARITY_DISABLE,
246-
.stop_bits = UART_STOP_BITS_1,
247-
#if SOC_UART_SUPPORT_REF_TICK
248-
.source_clk = UART_SCLK_REF_TICK,
249-
#elif SOC_UART_SUPPORT_XTAL_CLK
250-
.source_clk = UART_SCLK_XTAL,
251-
#endif
252-
};
253-
/* Install UART driver for interrupt-driven reads and writes */
254-
uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, 256, 0, 0, NULL, 0);
255-
uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config);
256-
257-
/* Tell VFS to use UART driver */
258-
esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
259-
260-
#elif CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG
261-
/* Based on @pjsg's work */
262-
263-
esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(RX_LINE_ENDINGS_CFG);
264-
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(TX_LINE_ENDINGS_CFG);
265-
266-
usb_serial_jtag_driver_config_t usb_serial_jtag_config =
267-
USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
268-
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and write */
269-
usb_serial_jtag_driver_install(&usb_serial_jtag_config);
270-
271-
esp_vfs_usb_serial_jtag_use_driver();
272-
#elif CONFIG_ESP_CONSOLE_USB_CDC
273-
/* Based on console/advanced_usb_cdc */
274-
275-
esp_vfs_dev_cdcacm_set_rx_line_endings(RX_LINE_ENDINGS_CFG);
276-
esp_vfs_dev_cdcacm_set_tx_line_endings(TX_LINE_ENDINGS_CFG);
277-
#else
278-
# error "Unsupported console type"
279-
#endif
280-
281-
xTaskCreate(
282-
console_task, "console", 1024, NULL, ESP_TASK_MAIN_PRIO+1, NULL);
283-
}
284-
285-
286138
void __attribute__((noreturn)) app_main(void)
287139
{
288140
task_init();
289141

290-
lua_feed_task = task_get_id(console_nodemcu_task);
291-
292142
relayed_event_handled = xSemaphoreCreateBinary();
293143
relayed_event_task = task_get_id(handle_default_loop_event);
294144

@@ -304,8 +154,6 @@ void __attribute__((noreturn)) app_main(void)
304154
nvs_flash_init ();
305155
esp_netif_init ();
306156

307-
console_init();
308-
309157
start_lua ();
310158
task_pump_messages ();
311159
__builtin_unreachable ();

components/lua/Kconfig

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ menu "Lua configuration"
129129
bool
130130
default y
131131
select NODEMCU_CMODULE_PIPE
132-
select NODEMCU_CMODULE_UART
132+
select NODEMCU_CMODULE_CONSOLE
133133
select LUA_BUILTIN_DEBUG
134134

135135
choice LUA_INIT_STRING

components/modules/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ set(module_srcs
1111
"bit.c"
1212
"bthci.c"
1313
"common.c"
14+
"console.c"
1415
"crypto.c"
1516
"dht.c"
1617
"encoder.c"
@@ -35,6 +36,7 @@ set(module_srcs
3536
"rmt.c"
3637
"rtcmem.c"
3738
"qrcodegen.c"
39+
"serial_common.c"
3840
"sigma_delta.c"
3941
"sjson.c"
4042
"sodium.c"

components/modules/Kconfig

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ menu "NodeMCU modules"
2828
help
2929
Includes the can module.
3030

31+
config NODEMCU_CMODULE_CONSOLE
32+
bool "Console module"
33+
default y
34+
help
35+
Includes the console module (required by our Lua VM).
36+
3137
config NODEMCU_CMODULE_CRYPTO
3238
bool "Crypto module"
3339
default "n"
@@ -339,6 +345,6 @@ menu "NodeMCU modules"
339345
bool "UART module"
340346
default y
341347
help
342-
Includes the UART module (required by our Lua VM).
348+
Includes the UART module.
343349

344350
endmenu

0 commit comments

Comments
 (0)