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 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
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 <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
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_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
|
||||||
|
|
Loading…
Reference in a new issue