Working simultaneous output and console, redefined LOG function

This commit is contained in:
Данила Горнушко 2023-11-24 06:49:17 +03:00
parent a583c32ba3
commit 598669779f
13 changed files with 290 additions and 183 deletions

View file

@ -139,6 +139,8 @@ static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN;
static int history_len = 0; static int history_len = 0;
static char **history = NULL; static char **history = NULL;
SemaphoreHandle_t stdout_taken_sem;
enum KEY_ACTION{ enum KEY_ACTION{
KEY_NULL = 0, /* NULL */ KEY_NULL = 0, /* NULL */
@ -198,7 +200,7 @@ bool linenoiseIsDumbMode(void) {
return dumbmode; return dumbmode;
} }
static void flushWrite(void) { void flushWrite(void) {
if (__fbufsize(stdout) > 0) { if (__fbufsize(stdout) > 0) {
fflush(stdout); fflush(stdout);
} }
@ -858,13 +860,16 @@ static char *linenoiseDumb(struct linenoiseState *l) {
/* dumb terminal, fall back to fgets */ /* dumb terminal, fall back to fgets */
// Not needed anymore, prompt is now in linenoiseEditStart // Not needed anymore, prompt is now in linenoiseEditStart
// fputs(l->prompt, stdout); // fputs(l->prompt, stdout);
flushWrite(); // flushWrite();
l->len = 0; //needed? l->len = 0; //needed?
while (l->len < l->buflen) { while (l->len < l->buflen) {
int c = fgetc(stdin); int c = fgetc(stdin);
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
if (c == '\n') { if (c == '\n') {
xSemaphoreGive(stdout_taken_sem);
break; break;
} else if (c >= 0x1c && c <= 0x1f){ } else if (c >= 0x1c && c <= 0x1f){
xSemaphoreGive(stdout_taken_sem);
continue; /* consume arrow keys */ continue; /* consume arrow keys */
} else if (c == BACKSPACE || c == 0x8) { } else if (c == BACKSPACE || c == 0x8) {
if (l->len > 0) { if (l->len > 0) {
@ -879,9 +884,12 @@ static char *linenoiseDumb(struct linenoiseState *l) {
} }
fputc(c, stdout); /* echo */ fputc(c, stdout); /* echo */
flushWrite(); flushWrite();
xSemaphoreGive(stdout_taken_sem);
} }
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
fputc('\n', stdout); fputc('\n', stdout);
flushWrite(); flushWrite();
xSemaphoreGive(stdout_taken_sem);
// if (l->len == 0) return linenoiseEditMore; // if (l->len == 0) return linenoiseEditMore;
return strdup(l->buf); 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 /* The latest history entry is always our current buffer, that
* initially is just an empty string. */ * initially is just an empty string. */
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
if (!dumbmode) { if (!dumbmode) {
linenoiseHistoryAdd(""); linenoiseHistoryAdd("");
int pos1 = getCursorPosition(); 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(); flushWrite();
int pos2 = getCursorPosition(); int pos2 = getCursorPosition();
if (pos1 >= 0 && pos2 >= 0) { if (pos1 >= 0 && pos2 >= 0) {
l->plen = pos2 - pos1; l->plen = pos2 - pos1;
} }
} else { } 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(); flushWrite();
} }
xSemaphoreGive(stdout_taken_sem);
return 0; return 0;
} }
@ -975,6 +991,7 @@ char *linenoiseEditMore = "If you see this, you are misusing the API: when linen
char *linenoiseEditFeed(struct linenoiseState *l) { char *linenoiseEditFeed(struct linenoiseState *l) {
if (dumbmode) return linenoiseDumb(l); if (dumbmode) return linenoiseDumb(l);
uint32_t t1 = 0; uint32_t t1 = 0;
uint32_t t2;
char c; char c;
int nread; int nread;
char seq[3]; char seq[3];
@ -990,16 +1007,20 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
*/ */
t1 = getMillis(); t1 = getMillis();
nread = fread(&c, 1, 1, stdin); nread = fread(&c, 1, 1, stdin);
if (nread <= 0) return NULL; if (nread <= 0) return linenoiseEditMore;
// FIXME: line printed twice after pasting something t2 = getMillis();
if ( (getMillis() - t1) < LINENOISE_PASTE_KEY_DELAY && c != ENTER) { 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. /* Pasting data, insert characters without formatting.
* This can only be performed when the cursor is at the end of the * This can only be performed when the cursor is at the end of the
* line. */ * line. */
if (linenoiseInsertPastedChar(l,c)) { if (linenoiseInsertPastedChar(l,c)) {
errno = EIO; errno = EIO;
xSemaphoreGive(stdout_taken_sem);
return NULL; return NULL;
} }
xSemaphoreGive(stdout_taken_sem);
return linenoiseEditMore; 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 // TODO: how was it supposed to work? c can't be less than 0
// if (c < 0) return NULL; // if (c < 0) return NULL;
/* Read next character when 0 */ /* Read next character when 0 */
if (c == 0) return linenoiseEditMore; if (c == 0) {
xSemaphoreGive(stdout_taken_sem);
return linenoiseEditMore;
}
} }
switch(c) { switch(c) {
@ -1028,9 +1052,11 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
refreshLine(l); refreshLine(l);
hintsCallback = hc; hintsCallback = hc;
} }
xSemaphoreGive(stdout_taken_sem);
return strdup(l->buf); return strdup(l->buf);
case CTRL_C: /* ctrl-c */ case CTRL_C: /* ctrl-c */
errno = EAGAIN; errno = EAGAIN;
xSemaphoreGive(stdout_taken_sem);
return NULL; return NULL;
case BACKSPACE: /* backspace */ case BACKSPACE: /* backspace */
case 8: /* ctrl-h */ case 8: /* ctrl-h */
@ -1044,6 +1070,7 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
history_len--; history_len--;
free(history[history_len]); free(history[history_len]);
errno = ENOENT; errno = ENOENT;
xSemaphoreGive(stdout_taken_sem);
return NULL; return NULL;
} }
break; break;
@ -1124,7 +1151,10 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
} }
break; break;
default: default:
if (linenoiseEditInsert(l,c)) return NULL; if (linenoiseEditInsert(l,c)) {
xSemaphoreGive(stdout_taken_sem);
return NULL;
}
break; break;
case CTRL_U: /* Ctrl+u, delete the whole line. */ case CTRL_U: /* Ctrl+u, delete the whole line. */
l->buf[0] = '\0'; l->buf[0] = '\0';
@ -1151,6 +1181,7 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
break; break;
} }
flushWrite(); flushWrite();
xSemaphoreGive(stdout_taken_sem);
return linenoiseEditMore; return linenoiseEditMore;
} }
@ -1160,8 +1191,10 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
* returns something different than NULL. At this point the user input * returns something different than NULL. At this point the user input
* is in the buffer, and we can restore the terminal in normal mode. */ * is in the buffer, and we can restore the terminal in normal mode. */
void linenoiseEditStop(struct linenoiseState *l) { void linenoiseEditStop(struct linenoiseState *l) {
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
fputc('\n', stdout); fputc('\n', stdout);
flushWrite(); flushWrite();
xSemaphoreGive(stdout_taken_sem);
} }
/* This just implements a blocking loop for the multiplexed API. /* 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() { int linenoiseProbe() {
xSemaphoreTake(stdout_taken_sem, portMAX_DELAY);
/* Switch to non-blocking mode */ /* Switch to non-blocking mode */
int stdin_fileno = fileno(stdin); int stdin_fileno = fileno(stdin);
int flags = fcntl(stdin_fileno, F_GETFL); int flags = fcntl(stdin_fileno, F_GETFL);
flags |= O_NONBLOCK; flags |= O_NONBLOCK;
int res = fcntl(stdin_fileno, F_SETFL, flags); int res = fcntl(stdin_fileno, F_SETFL, flags);
if (res != 0) { if (res != 0) {
xSemaphoreGive(stdout_taken_sem);
return -1; return -1;
} }
/* Device status request */ /* Device status request */
@ -1218,11 +1253,14 @@ int linenoiseProbe() {
flags &= ~O_NONBLOCK; flags &= ~O_NONBLOCK;
res = fcntl(stdin_fileno, F_SETFL, flags); res = fcntl(stdin_fileno, F_SETFL, flags);
if (res != 0) { if (res != 0) {
xSemaphoreGive(stdout_taken_sem);
return -1; return -1;
} }
if (read_bytes < 4) { if (read_bytes < 4) {
xSemaphoreGive(stdout_taken_sem);
return -2; return -2;
} }
xSemaphoreGive(stdout_taken_sem);
return 0; return 0;
} }

View file

@ -46,8 +46,12 @@ extern "C" {
#include <stddef.h> /* For size_t. */ #include <stddef.h> /* For size_t. */
#include <stdbool.h> #include <stdbool.h>
// for semaphore
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
extern char *linenoiseEditMore; extern char *linenoiseEditMore;
extern SemaphoreHandle_t stdout_taken_sem;
/* The linenoiseState structure represents the state during line editing. /* The linenoiseState structure represents the state during line editing.
* We pass this state to functions implementing specific editing * We pass this state to functions implementing specific editing
@ -112,6 +116,7 @@ int linenoiseProbe();
void linenoiseMaskModeEnable(void); void linenoiseMaskModeEnable(void);
void linenoiseMaskModeDisable(void); void linenoiseMaskModeDisable(void);
int linenoiseSetMaxLineLen(size_t len); int linenoiseSetMaxLineLen(size_t len);
void flushWrite(void);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -2,8 +2,9 @@ set(COMPONENT_SRCS
"main.c" "main.c"
"cmd_system.c" "cmd_system.c"
"can.c" "can.c"
"console_task.c" "console.c"
"fs.c" "fs.c"
"xvprintf.c"
) )
set(COMPONENT_ADD_INCLUDEDIRS set(COMPONENT_ADD_INCLUDEDIRS

View file

@ -25,12 +25,19 @@ menu "Can_wizard Configuration"
help help
A priority of FreeRTOS task can_task. See more about tasks priorities in FreeRTOS documentation. A priority of FreeRTOS task can_task. See more about tasks priorities in FreeRTOS documentation.
config CONSOLE_TASK_PRIORITY config CONSOLE_TX_PRIORITY
int "Console task priority" int "Console task TX priority"
range 0 22 range 0 22
default 2 default 2
help 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.

View file

@ -4,9 +4,14 @@
#include "can.h" #include "can.h"
#include "esp_log.h" #include "esp_log.h"
#include "freertos/projdefs.h"
#include "hal/twai_types.h" #include "hal/twai_types.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#include <stddef.h>
#include <stdio.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_timing_config_t t_config = TWAI_TIMING_CONFIG_125KBITS();
static const twai_general_config_t g_config = { 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; if (twai_receive(&rx_msg, pdMS_TO_TICKS(10)) != ESP_OK) continue;
// TODO: add software filtering // TODO: add software filtering
// if ((((rx_msg.identifier >> 8) & 0xFF) != CONFIG_DEVICE_ID) && (((rx_msg.identifier >> 8) & 0xFF) != 0xFF)) continue; // 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); // ESP_LOGI(LOG_TAG, "received can frame: %" PRIu32, rx_msg.identifier);
// printf("received can package with ID: %" PRIu32, rx_msg.identifier); xprintf("received can frame: %" PRIu32 "\n", rx_msg.identifier);
} }
} }

155
main/console.c Normal file
View 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
View 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

View file

@ -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);
}
}

View file

@ -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

View file

@ -1,80 +1,17 @@
#include <stdio.h> #include <stdio.h>
#include <fcntl.h> #include "freertos/FreeRTOS.h"
#include "esp_err.h" #include "freertos/task.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 "can.h" #include "can.h"
#include "fs.h" #include "fs.h"
#include "console_task.h" #include "console.h"
#include "xvprintf.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);
}
void app_main(void) { void app_main(void) {
can_init(); can_init();
init_tx_ringbuf();
xTaskCreate(can_task, "can task", 4096, NULL, CONFIG_CAN_TASK_PRIORITY, NULL); xTaskCreate(can_task, "can task", 4096, NULL, CONFIG_CAN_TASK_PRIORITY, NULL);
initialize_filesystem(); initialize_filesystem();
initialize_console(); initialize_console();
xTaskCreate(console_task_tx, "console tsk tx", 4096, NULL, CONFIG_CONSOLE_TX_PRIORITY, NULL);
/* Register commands */ xTaskCreate(console_task_interactive, "console tsk int", 4096, NULL, CONFIG_CONSOLE_INT_PRIORITY, NULL);
esp_console_register_help_command();
register_system();
xTaskCreate(console_task, "console task", 4096, NULL, CONFIG_CONSOLE_TASK_PRIORITY, NULL);
} }

30
main/xvprintf.c Normal file
View 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
View 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

View file

@ -399,7 +399,8 @@ CONFIG_ENV_GPIO_OUT_RANGE_MAX=21
CONFIG_CAN_RX_GPIO=9 CONFIG_CAN_RX_GPIO=9
CONFIG_CAN_TX_GPIO=8 CONFIG_CAN_TX_GPIO=8
CONFIG_CAN_TASK_PRIORITY=5 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 # end of Can_wizard Configuration
# #
@ -987,7 +988,7 @@ CONFIG_FATFS_VFS_FSTAT_BLKSIZE=0
# #
# CONFIG_FREERTOS_SMP is not set # CONFIG_FREERTOS_SMP is not set
CONFIG_FREERTOS_UNICORE=y CONFIG_FREERTOS_UNICORE=y
CONFIG_FREERTOS_HZ=100 CONFIG_FREERTOS_HZ=1000
CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y CONFIG_FREERTOS_OPTIMIZED_SCHEDULER=y
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set # CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set