forked from test34/can_wizard
Working simultaneous output and console, redefined LOG function
This commit is contained in:
parent
a583c32ba3
commit
598669779f
13 changed files with 290 additions and 183 deletions
|
@ -139,6 +139,8 @@ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
|
|||
static int history_len = 0;
|
||||
static char **history = NULL;
|
||||
|
||||
SemaphoreHandle_t stdout_taken_sem;
|
||||
|
||||
|
||||
enum KEY_ACTION{
|
||||
KEY_NULL = 0, /* NULL */
|
||||
|
@ -198,7 +200,7 @@ bool linenoiseIsDumbMode(void) {
|
|||
return dumbmode;
|
||||
}
|
||||
|
||||
static void flushWrite(void) {
|
||||
void flushWrite(void) {
|
||||
if (__fbufsize(stdout) > 0) {
|
||||
fflush(stdout);
|
||||
}
|
||||
|
@ -858,13 +860,16 @@ static char *linenoiseDumb(struct linenoiseState *l) {
|
|||
/* dumb terminal, fall back to fgets */
|
||||
// Not needed anymore, prompt is now in linenoiseEditStart
|
||||
// fputs(l->prompt, stdout);
|
||||
flushWrite();
|
||||
// flushWrite();
|
||||
l->len = 0; //needed?
|
||||
while (l->len < l->buflen) {
|
||||
int c = fgetc(stdin);
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
if (c == '\n') {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
break;
|
||||
} else if (c >= 0x1c && c <= 0x1f){
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
continue; /* consume arrow keys */
|
||||
} else if (c == BACKSPACE || c == 0x8) {
|
||||
if (l->len > 0) {
|
||||
|
@ -879,9 +884,12 @@ static char *linenoiseDumb(struct linenoiseState *l) {
|
|||
}
|
||||
fputc(c, stdout); /* echo */
|
||||
flushWrite();
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
}
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
fputc('\n', stdout);
|
||||
flushWrite();
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
// if (l->len == 0) return linenoiseEditMore;
|
||||
return strdup(l->buf);
|
||||
}
|
||||
|
@ -936,19 +944,27 @@ int linenoiseEditStart(struct linenoiseState *l, char *buf, size_t buflen, const
|
|||
|
||||
/* The latest history entry is always our current buffer, that
|
||||
* initially is just an empty string. */
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
if (!dumbmode) {
|
||||
linenoiseHistoryAdd("");
|
||||
int pos1 = getCursorPosition();
|
||||
if (fwrite(prompt,l->plen,1,stdout) == -1) return -1;
|
||||
if (fwrite(prompt,l->plen,1,stdout) == -1) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return -1;
|
||||
}
|
||||
flushWrite();
|
||||
int pos2 = getCursorPosition();
|
||||
if (pos1 >= 0 && pos2 >= 0) {
|
||||
l->plen = pos2 - pos1;
|
||||
}
|
||||
} else {
|
||||
if (fwrite(prompt,l->plen,1,stdout) == -1) return -1;
|
||||
if (fwrite(prompt,l->plen,1,stdout) == -1) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return -1;
|
||||
}
|
||||
flushWrite();
|
||||
}
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -975,6 +991,7 @@ char *linenoiseEditMore = "If you see this, you are misusing the API: when linen
|
|||
char *linenoiseEditFeed(struct linenoiseState *l) {
|
||||
if (dumbmode) return linenoiseDumb(l);
|
||||
uint32_t t1 = 0;
|
||||
uint32_t t2;
|
||||
char c;
|
||||
int nread;
|
||||
char seq[3];
|
||||
|
@ -990,16 +1007,20 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
*/
|
||||
t1 = getMillis();
|
||||
nread = fread(&c, 1, 1, stdin);
|
||||
if (nread <= 0) return NULL;
|
||||
// FIXME: line printed twice after pasting something
|
||||
if ( (getMillis() - t1) < LINENOISE_PASTE_KEY_DELAY && c != ENTER) {
|
||||
if (nread <= 0) return linenoiseEditMore;
|
||||
t2 = getMillis();
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
// FIXME: line printed twice after pasting something that takes more than 1 line
|
||||
if ( (t2 - t1) < LINENOISE_PASTE_KEY_DELAY && c != ENTER) {
|
||||
/* Pasting data, insert characters without formatting.
|
||||
* This can only be performed when the cursor is at the end of the
|
||||
* line. */
|
||||
if (linenoiseInsertPastedChar(l,c)) {
|
||||
errno = EIO;
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return NULL;
|
||||
}
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return linenoiseEditMore;
|
||||
}
|
||||
|
||||
|
@ -1012,7 +1033,10 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
// TODO: how was it supposed to work? c can't be less than 0
|
||||
// if (c < 0) return NULL;
|
||||
/* Read next character when 0 */
|
||||
if (c == 0) return linenoiseEditMore;
|
||||
if (c == 0) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return linenoiseEditMore;
|
||||
}
|
||||
}
|
||||
|
||||
switch(c) {
|
||||
|
@ -1028,9 +1052,11 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
refreshLine(l);
|
||||
hintsCallback = hc;
|
||||
}
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return strdup(l->buf);
|
||||
case CTRL_C: /* ctrl-c */
|
||||
errno = EAGAIN;
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return NULL;
|
||||
case BACKSPACE: /* backspace */
|
||||
case 8: /* ctrl-h */
|
||||
|
@ -1044,6 +1070,7 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
history_len--;
|
||||
free(history[history_len]);
|
||||
errno = ENOENT;
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
@ -1124,7 +1151,10 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
if (linenoiseEditInsert(l,c)) return NULL;
|
||||
if (linenoiseEditInsert(l,c)) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case CTRL_U: /* Ctrl+u, delete the whole line. */
|
||||
l->buf[0] = '\0';
|
||||
|
@ -1151,6 +1181,7 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
break;
|
||||
}
|
||||
flushWrite();
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return linenoiseEditMore;
|
||||
}
|
||||
|
||||
|
@ -1160,8 +1191,10 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
|
|||
* returns something different than NULL. At this point the user input
|
||||
* is in the buffer, and we can restore the terminal in normal mode. */
|
||||
void linenoiseEditStop(struct linenoiseState *l) {
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
fputc('\n', stdout);
|
||||
flushWrite();
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
}
|
||||
|
||||
/* This just implements a blocking loop for the multiplexed API.
|
||||
|
@ -1184,12 +1217,14 @@ static char *linenoiseBlockingEdit(char *buf, size_t buflen, const char *prompt)
|
|||
}
|
||||
|
||||
int linenoiseProbe() {
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
/* Switch to non-blocking mode */
|
||||
int stdin_fileno = fileno(stdin);
|
||||
int flags = fcntl(stdin_fileno, F_GETFL);
|
||||
flags |= O_NONBLOCK;
|
||||
int res = fcntl(stdin_fileno, F_SETFL, flags);
|
||||
if (res != 0) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return -1;
|
||||
}
|
||||
/* Device status request */
|
||||
|
@ -1218,11 +1253,14 @@ int linenoiseProbe() {
|
|||
flags &= ~O_NONBLOCK;
|
||||
res = fcntl(stdin_fileno, F_SETFL, flags);
|
||||
if (res != 0) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return -1;
|
||||
}
|
||||
if (read_bytes < 4) {
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return -2;
|
||||
}
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,12 @@ extern "C" {
|
|||
|
||||
#include <stddef.h> /* For size_t. */
|
||||
#include <stdbool.h>
|
||||
// for semaphore
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
extern char *linenoiseEditMore;
|
||||
extern SemaphoreHandle_t stdout_taken_sem;
|
||||
|
||||
/* The linenoiseState structure represents the state during line editing.
|
||||
* We pass this state to functions implementing specific editing
|
||||
|
@ -112,6 +116,7 @@ int linenoiseProbe();
|
|||
void linenoiseMaskModeEnable(void);
|
||||
void linenoiseMaskModeDisable(void);
|
||||
int linenoiseSetMaxLineLen(size_t len);
|
||||
void flushWrite(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -2,8 +2,9 @@ set(COMPONENT_SRCS
|
|||
"main.c"
|
||||
"cmd_system.c"
|
||||
"can.c"
|
||||
"console_task.c"
|
||||
"console.c"
|
||||
"fs.c"
|
||||
"xvprintf.c"
|
||||
)
|
||||
|
||||
set(COMPONENT_ADD_INCLUDEDIRS
|
||||
|
|
|
@ -25,12 +25,19 @@ menu "Can_wizard Configuration"
|
|||
help
|
||||
A priority of FreeRTOS task can_task. See more about tasks priorities in FreeRTOS documentation.
|
||||
|
||||
config CONSOLE_TASK_PRIORITY
|
||||
int "Console task priority"
|
||||
config CONSOLE_TX_PRIORITY
|
||||
int "Console task TX priority"
|
||||
range 0 22
|
||||
default 2
|
||||
help
|
||||
A priority of FreeRTOS task can_task. See more about tasks priorities in FreeRTOS documentation.
|
||||
A priority of FreeRTOS task can_task_tx. See more about tasks priorities in FreeRTOS documentation.
|
||||
|
||||
config CONSOLE_INT_PRIORITY
|
||||
int "Console task interactive priority"
|
||||
range 0 22
|
||||
default 1
|
||||
help
|
||||
A priority of FreeRTOS task can_task_interactive. See more about tasks priorities in FreeRTOS documentation.
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -4,9 +4,14 @@
|
|||
|
||||
#include "can.h"
|
||||
#include "esp_log.h"
|
||||
#include "freertos/projdefs.h"
|
||||
#include "hal/twai_types.h"
|
||||
#include "sdkconfig.h"
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "freertos/ringbuf.h"
|
||||
#include "xvprintf.h"
|
||||
|
||||
|
||||
static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_125KBITS();
|
||||
static const twai_general_config_t g_config = {
|
||||
|
@ -74,8 +79,8 @@ void can_task(void* arg) {
|
|||
if (twai_receive(&rx_msg, pdMS_TO_TICKS(10)) != ESP_OK) continue;
|
||||
// TODO: add software filtering
|
||||
// if ((((rx_msg.identifier >> 8) & 0xFF) != CONFIG_DEVICE_ID) && (((rx_msg.identifier >> 8) & 0xFF) != 0xFF)) continue;
|
||||
ESP_LOGI(LOG_TAG, "received can package with ID: %" PRIu32, rx_msg.identifier);
|
||||
// printf("received can package with ID: %" PRIu32, rx_msg.identifier);
|
||||
// ESP_LOGI(LOG_TAG, "received can frame: %" PRIu32, rx_msg.identifier);
|
||||
xprintf("received can frame: %" PRIu32 "\n", rx_msg.identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
155
main/console.c
Normal file
155
main/console.c
Normal file
|
@ -0,0 +1,155 @@
|
|||
#include "console.h"
|
||||
#include <fcntl.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_console.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_system.h"
|
||||
#include "freertos/projdefs.h"
|
||||
#include "linenoise/linenoise.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_vfs_usb_serial_jtag.h"
|
||||
#include "driver/usb_serial_jtag.h"
|
||||
#include "cmd_system.h"
|
||||
#include "fs.h"
|
||||
#include "xvprintf.h"
|
||||
|
||||
#if CONFIG_LOG_COLORS
|
||||
static const bool use_colors = true;
|
||||
#else
|
||||
static const bool use_colors = true;
|
||||
#endif
|
||||
|
||||
static const char* TAG = "console task";
|
||||
esp_console_config_t console_config;
|
||||
struct linenoiseState ls;
|
||||
|
||||
char prompt[50];
|
||||
|
||||
static void get_prompt(char* prompt_buf) {
|
||||
static const char* text = "can_wizard > ";
|
||||
static const char* prompt_color = LOG_COLOR_E;
|
||||
memset(prompt_buf,0,strlen(prompt_buf));
|
||||
if (use_colors) {
|
||||
strcat(prompt_buf, prompt_color);
|
||||
strcat(prompt_buf, text);
|
||||
strcat(prompt_buf, LOG_RESET_COLOR);
|
||||
} else {
|
||||
strcat(prompt_buf, text);
|
||||
}
|
||||
}
|
||||
|
||||
void console_task_tx(void* arg) {
|
||||
const int fd = fileno(stdout);
|
||||
char *msg_to_print;
|
||||
size_t msg_to_print_size;
|
||||
vTaskDelay(pdMS_TO_TICKS(200));
|
||||
while(1) {
|
||||
msg_to_print = (char *)xRingbufferReceive(can_messages, &msg_to_print_size, portMAX_DELAY);
|
||||
if (msg_to_print != NULL) {
|
||||
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
|
||||
linenoiseHide(&ls);
|
||||
write(fd, msg_to_print, msg_to_print_size);
|
||||
flushWrite();
|
||||
linenoiseShow(&ls);
|
||||
xSemaphoreGive(stdout_taken_sem);
|
||||
vRingbufferReturnItem(can_messages, (void *) msg_to_print);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void console_task_interactive(void* arg) {
|
||||
stdout_taken_sem = xSemaphoreCreateMutex();
|
||||
char *buf = calloc(1, console_config.max_cmdline_length);
|
||||
char *line;
|
||||
vTaskDelay(pdMS_TO_TICKS(15)); //give some time for app_main to finish
|
||||
/* Figure out if the terminal supports escape sequences */
|
||||
printf("Testing your console...");
|
||||
int probe_status = linenoiseProbe();
|
||||
// int probe_status = 1;
|
||||
if (probe_status) { /* zero indicates success */
|
||||
printf("\n"
|
||||
"Your terminal application does not support escape sequences.\n"
|
||||
"Line editing and history features are disabled.\n"
|
||||
"On Windows, try using Putty instead.\n"
|
||||
"Your terminal is in Dumb Mode from now! \n");
|
||||
linenoiseSetDumbMode(1);
|
||||
}
|
||||
printf("\n"
|
||||
"Type 'help' to get the list of commands.\n"
|
||||
"Use UP/DOWN arrows to navigate through command history.\n"
|
||||
"Press TAB when typing command name to auto-complete.\n"
|
||||
"Ctrl+C will terminate the console environment.\n");
|
||||
get_prompt(prompt);
|
||||
linenoiseEditStart(&ls, buf, console_config.max_cmdline_length, prompt);
|
||||
while (true) {
|
||||
line = linenoiseEditFeed(&ls);
|
||||
if (line == linenoiseEditMore) continue;
|
||||
linenoiseEditStop(&ls);
|
||||
if (line == NULL) { /* Break on EOF or error */
|
||||
ESP_LOGE(TAG, "Ctrl+C???");
|
||||
break;
|
||||
}
|
||||
/* Add the command to the history if not empty*/
|
||||
if (strlen(line) > 0) {
|
||||
linenoiseHistoryAdd(line);
|
||||
/* Save command history to filesystem */
|
||||
linenoiseHistorySave(HISTORY_PATH);
|
||||
}
|
||||
|
||||
int ret;
|
||||
esp_err_t err = esp_console_run(line, &ret);
|
||||
if (err == ESP_ERR_NOT_FOUND) {
|
||||
printf("Unrecognized command\n");
|
||||
} else if (err == ESP_ERR_INVALID_ARG) {
|
||||
// command was empty
|
||||
} else if (err == ESP_OK && ret != ESP_OK) {
|
||||
printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
|
||||
} else if (err != ESP_OK) {
|
||||
printf("Internal error: %s\n", esp_err_to_name(err));
|
||||
}
|
||||
/* linenoise allocates line buffer on the heap, so need to free it */
|
||||
linenoiseFree(line);
|
||||
linenoiseEditStart(&ls, buf, console_config.max_cmdline_length, prompt);
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG, "Terminating console");
|
||||
esp_console_deinit();
|
||||
while (1) {
|
||||
vTaskDelay(100);
|
||||
}
|
||||
}
|
||||
|
||||
void initialize_console(void) {
|
||||
/* Disable buffering on stdin */
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
||||
esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
||||
/* Move the caret to the beginning of the next line on '\n' */
|
||||
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
|
||||
/* Enable non-blocking mode on stdin and stdout */
|
||||
fcntl(fileno(stdout), F_SETFL, 0);
|
||||
fcntl(fileno(stdin), F_SETFL, 0);
|
||||
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
|
||||
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
|
||||
ESP_ERROR_CHECK(usb_serial_jtag_driver_install(&usb_serial_jtag_config));
|
||||
/* Tell vfs to use usb-serial-jtag driver */
|
||||
esp_vfs_usb_serial_jtag_use_driver();
|
||||
console_config.max_cmdline_args = 8;
|
||||
console_config.max_cmdline_length = 256;
|
||||
if (use_colors) console_config.hint_color = atoi(LOG_COLOR_CYAN);
|
||||
ESP_ERROR_CHECK(esp_console_init(&console_config));
|
||||
linenoiseSetMultiLine(1);
|
||||
linenoiseSetCompletionCallback(&esp_console_get_completion);
|
||||
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
|
||||
linenoiseHistorySetMaxLen(100);
|
||||
linenoiseSetMaxLineLen(console_config.max_cmdline_length);
|
||||
linenoiseHistoryLoad(HISTORY_PATH);
|
||||
/* Register commands */
|
||||
esp_console_register_help_command();
|
||||
register_system();
|
||||
}
|
10
main/console.h
Normal file
10
main/console.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#ifndef MAIN_CONSOLE_TASK_H
|
||||
#define MAIN_CONSOLE_TASK_H
|
||||
|
||||
// functions
|
||||
|
||||
void console_task_tx(void* arg);
|
||||
void console_task_interactive(void* arg);
|
||||
void initialize_console(void);
|
||||
|
||||
#endif // MAIN_CONSOLE_TASK_H
|
|
@ -1,88 +0,0 @@
|
|||
#include "console_task.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_system.h"
|
||||
#include "linenoise/linenoise.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_console.h"
|
||||
#include "fs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#define PROMPT_STR "[root@can_wiz ~]$ "
|
||||
|
||||
static const char* TAG = "console task";
|
||||
|
||||
|
||||
void console_task(void* arg) {
|
||||
|
||||
/* Prompt to be printed before each line.
|
||||
* This can be customized, made dynamic, etc.
|
||||
*/
|
||||
const char* prompt = LOG_COLOR_E PROMPT_STR LOG_RESET_COLOR;
|
||||
// const char* prompt = "dumb_console >";
|
||||
|
||||
printf("\n"
|
||||
"Type 'help' to get the list of commands.\n"
|
||||
"Use UP/DOWN arrows to navigate through command history.\n"
|
||||
"Press TAB when typing command name to auto-complete.\n"
|
||||
"Ctrl+C will terminate the console environment.\n");
|
||||
|
||||
/* Figure out if the terminal supports escape sequences */
|
||||
int probe_status = linenoiseProbe();
|
||||
// int probe_status = 1;
|
||||
if (probe_status) { /* zero indicates success */
|
||||
printf("\n"
|
||||
"Your terminal application does not support escape sequences.\n"
|
||||
"Line editing and history features are disabled.\n"
|
||||
"On Windows, try using Putty instead.\n");
|
||||
linenoiseSetDumbMode(1);
|
||||
|
||||
#if CONFIG_LOG_COLORS
|
||||
/* Since the terminal doesn't support escape sequences,
|
||||
* don't use color codes in the prompt.
|
||||
*/
|
||||
// prompt = "> ";
|
||||
#endif //CONFIG_LOG_COLORS
|
||||
}
|
||||
|
||||
/* Main loop */
|
||||
while (true) {
|
||||
/* Get a line using linenoise.
|
||||
* The line is returned when ENTER is pressed.
|
||||
*/
|
||||
char* line = linenoise(prompt);
|
||||
if (line == NULL) { /* Break on EOF or error */
|
||||
ESP_LOGE(TAG, "Ctrl+C???");
|
||||
break;
|
||||
}
|
||||
/* Add the command to the history if not empty*/
|
||||
if (strlen(line) > 0) {
|
||||
linenoiseHistoryAdd(line);
|
||||
/* Save command history to filesystem */
|
||||
linenoiseHistorySave(HISTORY_PATH);
|
||||
}
|
||||
|
||||
/* Try to run the command */
|
||||
int ret;
|
||||
esp_err_t err = esp_console_run(line, &ret);
|
||||
if (err == ESP_ERR_NOT_FOUND) {
|
||||
printf("Unrecognized command\n");
|
||||
} else if (err == ESP_ERR_INVALID_ARG) {
|
||||
// command was empty
|
||||
} else if (err == ESP_OK && ret != ESP_OK) {
|
||||
printf("Command returned non-zero error code: 0x%x (%s)\n", ret, esp_err_to_name(ret));
|
||||
} else if (err != ESP_OK) {
|
||||
printf("Internal error: %s\n", esp_err_to_name(err));
|
||||
}
|
||||
/* linenoise allocates line buffer on the heap, so need to free it */
|
||||
linenoiseFree(line);
|
||||
}
|
||||
|
||||
ESP_LOGE(TAG, "Error or end-of-input, terminating console");
|
||||
esp_console_deinit();
|
||||
while (true) {
|
||||
vTaskDelay(100);
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef MAIN_CONSOLE_TASK_H
|
||||
#define MAIN_CONSOLE_TASK_H
|
||||
|
||||
// functions
|
||||
|
||||
void console_task(void* arg);
|
||||
|
||||
#endif // MAIN_CONSOLE_TASK_H
|
77
main/main.c
77
main/main.c
|
@ -1,80 +1,17 @@
|
|||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_console.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "linenoise/linenoise.h"
|
||||
#include "esp_vfs_usb_serial_jtag.h"
|
||||
#include "driver/usb_serial_jtag.h"
|
||||
#include "cmd_system.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "can.h"
|
||||
#include "fs.h"
|
||||
#include "console_task.h"
|
||||
|
||||
|
||||
static void initialize_console(void) {
|
||||
/* Disable buffering on stdin */
|
||||
setvbuf(stdin, NULL, _IONBF, 0);
|
||||
|
||||
/* Minicom, screen, idf_monitor send CR when ENTER key is pressed */
|
||||
esp_vfs_dev_usb_serial_jtag_set_rx_line_endings(ESP_LINE_ENDINGS_CR);
|
||||
/* Move the caret to the beginning of the next line on '\n' */
|
||||
esp_vfs_dev_usb_serial_jtag_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF);
|
||||
|
||||
/* Enable non-blocking mode on stdin and stdout */
|
||||
fcntl(fileno(stdout), F_SETFL, 0);
|
||||
fcntl(fileno(stdin), F_SETFL, 0);
|
||||
|
||||
usb_serial_jtag_driver_config_t usb_serial_jtag_config = USB_SERIAL_JTAG_DRIVER_CONFIG_DEFAULT();
|
||||
|
||||
/* Install USB-SERIAL-JTAG driver for interrupt-driven reads and writes */
|
||||
ESP_ERROR_CHECK(usb_serial_jtag_driver_install(&usb_serial_jtag_config));
|
||||
|
||||
/* Tell vfs to use usb-serial-jtag driver */
|
||||
esp_vfs_usb_serial_jtag_use_driver();
|
||||
|
||||
/* Initialize the console */
|
||||
esp_console_config_t console_config = {
|
||||
.max_cmdline_args = 8,
|
||||
.max_cmdline_length = 256,
|
||||
#if CONFIG_LOG_COLORS
|
||||
.hint_color = atoi(LOG_COLOR_CYAN)
|
||||
#endif
|
||||
};
|
||||
ESP_ERROR_CHECK(esp_console_init(&console_config));
|
||||
|
||||
/* Configure linenoise line completion library */
|
||||
/* Enable multiline editing. If not set, long commands will scroll within
|
||||
* single line.
|
||||
*/
|
||||
linenoiseSetMultiLine(1);
|
||||
|
||||
/* Tell linenoise where to get command completions and hints */
|
||||
linenoiseSetCompletionCallback(&esp_console_get_completion);
|
||||
linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
|
||||
|
||||
/* Set command history size */
|
||||
linenoiseHistorySetMaxLen(100);
|
||||
|
||||
/* Set command maximum length */
|
||||
linenoiseSetMaxLineLen(console_config.max_cmdline_length);
|
||||
|
||||
/* Load command history from filesystem */
|
||||
linenoiseHistoryLoad(HISTORY_PATH);
|
||||
}
|
||||
#include "console.h"
|
||||
#include "xvprintf.h"
|
||||
|
||||
void app_main(void) {
|
||||
can_init();
|
||||
init_tx_ringbuf();
|
||||
xTaskCreate(can_task, "can task", 4096, NULL, CONFIG_CAN_TASK_PRIORITY, NULL);
|
||||
initialize_filesystem();
|
||||
initialize_console();
|
||||
|
||||
/* Register commands */
|
||||
esp_console_register_help_command();
|
||||
register_system();
|
||||
|
||||
xTaskCreate(console_task, "console task", 4096, NULL, CONFIG_CONSOLE_TASK_PRIORITY, NULL);
|
||||
|
||||
xTaskCreate(console_task_tx, "console tsk tx", 4096, NULL, CONFIG_CONSOLE_TX_PRIORITY, NULL);
|
||||
xTaskCreate(console_task_interactive, "console tsk int", 4096, NULL, CONFIG_CONSOLE_INT_PRIORITY, NULL);
|
||||
}
|
||||
|
|
30
main/xvprintf.c
Normal file
30
main/xvprintf.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
#include "xvprintf.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include "stdbool.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
RingbufHandle_t can_messages;
|
||||
|
||||
|
||||
void init_tx_ringbuf() {
|
||||
can_messages = xRingbufferCreate(1028, RINGBUF_TYPE_NOSPLIT);
|
||||
esp_log_set_vprintf(&xvprintf);
|
||||
}
|
||||
|
||||
// This function will be called by the ESP log library every time ESP_LOG needs to be performed.
|
||||
// @important Do NOT use the ESP_LOG* macro's in this function ELSE recursive loop and stack overflow! So use printf() instead for debug messages.
|
||||
int xvprintf(const char *fmt, va_list args) {
|
||||
char msg_to_send[500];
|
||||
size_t str_len;
|
||||
str_len = snprintf(msg_to_send, 499, fmt, va_arg(args, int), va_arg(args, char *));
|
||||
va_end(args);
|
||||
xRingbufferSend(can_messages, msg_to_send, str_len + 1, pdMS_TO_TICKS(100));
|
||||
return str_len;
|
||||
}
|
||||
|
||||
int xprintf(const char *fmt, ...) {
|
||||
va_list(args);
|
||||
va_start(args, fmt);
|
||||
return xvprintf(fmt, args);
|
||||
}
|
14
main/xvprintf.h
Normal file
14
main/xvprintf.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef MAIN_XVPRINTF_H
|
||||
#define MAIN_XVPRINTF_H
|
||||
|
||||
#include "freertos/ringbuf.h"
|
||||
|
||||
extern RingbufHandle_t can_messages;
|
||||
|
||||
void init_tx_ringbuf();
|
||||
int xvprintf(const char *fmt, va_list args);
|
||||
int xprintf(const char *fmt, ...);
|
||||
|
||||
// functions
|
||||
|
||||
#endif // MAIN_XVPRINTF_H
|
|
@ -399,7 +399,8 @@ CONFIG_ENV_GPIO_OUT_RANGE_MAX=21
|
|||
CONFIG_CAN_RX_GPIO=9
|
||||
CONFIG_CAN_TX_GPIO=8
|
||||
CONFIG_CAN_TASK_PRIORITY=5
|
||||
CONFIG_CONSOLE_TASK_PRIORITY=2
|
||||
CONFIG_CONSOLE_TX_PRIORITY=2
|
||||
CONFIG_CONSOLE_INT_PRIORITY=1
|
||||
# end of Can_wizard Configuration
|
||||
|
||||
#
|
||||
|
@ -987,7 +988,7 @@ CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0
|
|||
#
|
||||
# CONFIG_FREERTOS_SMP is not set
|
||||
CONFIG_FREERTOS_UNICORE=y
|
||||
CONFIG_FREERTOS_HZ=100
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y
|
||||
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
|
||||
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
|
||||
|
|
Loading…
Reference in a new issue