Advanced Distributed Systems module at HSLU
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

241 lines
5.9 KiB

/*
* Copyright (c) 2019-2021, Erich Styger
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "platform.h"
#if PL_CONFIG_USE_SHELL
#include "Shell.h"
#include "McuShell.h"
#include "McuRTOS.h"
#include "McuRTT.h"
#include "McuArmTools.h"
#if PL_CONFIG_USE_I2C_SPY
#include "McuI2CSpy.h"
#endif
#if PL_CONFIG_USE_USB_CDC
#include "virtual_com.h"
#endif
#if PL_CONFIG_USE_LINE_SENSOR
#include "Reflectance.h"
#endif
#if PL_CONFIG_USE_BUZZER
#include "Buzzer.h"
#endif
#if PL_CONFIG_USE_MOTORS
#include "Motor.h"
#endif
#if PL_CONFIG_USE_QUADRATURE
#include "QuadCounter.h"
#endif
#if PL_CONFIG_USE_ESP32
#include "McuESP32.h"
#endif
#if PL_CONFIG_USE_PID
#include "Pid.h"
#endif
#if PL_CONFIG_HAS_BATTERY_ADC
#include "Battery.h"
#endif
#include "McuShellUart.h"
#if PL_CONFIG_APP_LINE_FOLLOWING || PL_CONFIG_APP_LINE_MAZE
#include "LineFollow.h"
#endif
#include "Turn.h"
#if PL_CONFIG_APP_LINE_MAZE
#include "Maze.h"
#endif
#include "Drive.h"
#include "Tacho.h"
#include "Identify.h"
#include "Application.h"
#include "Remote.h"
#if PL_CONFIG_HAS_ACCEL
#include "McuFXOS8700.h"
#endif
#include "McuLog.h"
static const McuShell_ParseCommandCallback CmdParserTable[] =
{
McuShell_ParseCommand,
McuRTOS_ParseCommand,
#if McuArmTools_CONFIG_PARSE_COMMAND_ENABLED
McuArmTools_ParseCommand,
#endif
#if PL_CONFIG_USE_IDENTIFY
ID_ParseCommand,
#endif
#if PL_CONFIG_USE_I2C_SPY
McuI2CSpy_ParseCommand,
#endif
#if PL_CONFIG_USE_BUZZER
BUZ_ParseCommand,
#endif
#if PL_CONFIG_USE_LINE_SENSOR
REF_ParseCommand,
#endif
#if PL_CONFIG_USE_MOTORS
MOT_ParseCommand,
#endif
#if PL_CONFIG_USE_QUADRATURE
QuadCounter_ParseCommand,
#endif
#if PL_CONFIG_USE_TACHO
TACHO_ParseCommand,
#endif
#if PL_CONFIG_USE_ESP32
McuESP32_ParseCommand,
#endif
#if PL_CONFIG_USE_PID
PID_ParseCommand,
#endif
#if PL_CONFIG_APP_LINE_FOLLOWING || PL_CONFIG_APP_LINE_MAZE
LF_ParseCommand,
#endif
#if PL_HAS_TURN
TURN_ParseCommand,
#endif
#if PL_CONFIG_USE_DRIVE
DRV_ParseCommand,
#endif
#if PL_CONFIG_APP_LINE_MAZE
MAZE_ParseCommand,
#endif
APP_ParseCommand,
#if PL_CONFIG_HAS_BATTERY_ADC
BATT_ParseCommand,
#endif
#if PL_CONFIG_USE_REMOTE
REMOTE_ParseCommand,
#endif
#if PL_CONFIG_HAS_ACCEL
McuFXOS8700_ParseCommand,
#endif
McuLog_ParseCommand,
NULL /* Sentinel */
};
#if PL_CONFIG_USE_ESP32
/* write output from the ESP to the shell too */
static void ESP_SendChar(unsigned char ch) {
#if 0
/* Do NOT send to all shell I/O console. Because if the ESP32 has echo enabled, it will send back all characters, so they show up twice e.g. on RTT */
SHELL_SendChar(ch);
#endif
#if PL_CONFIG_USE_REMOTE
REMOTE_GatewayRxFromESP(ch); /* pass it to remote module for parsing */
#endif
}
static void ESP_ReadChar(uint8_t *c) {
*c = '\0'; /* nothing received */
}
static bool ESP_CharPresent(void) {
return false;
}
McuShell_ConstStdIOType ESP_ToShellStdio = {
.stdIn = (McuShell_StdIO_In_FctType)ESP_ReadChar,
.stdOut = (McuShell_StdIO_OutErr_FctType)ESP_SendChar,
.stdErr = (McuShell_StdIO_OutErr_FctType)ESP_SendChar,
.keyPressed = ESP_CharPresent, /* if input is not empty */
#if McuShell_CONFIG_ECHO_ENABLED
.echoEnabled = false,
#endif
};
#endif /* PL_CONFIG_USE_ESP32 */
typedef struct {
McuShell_ConstStdIOType *stdio;
unsigned char *buf;
size_t bufSize;
} SHELL_IODesc;
static const SHELL_IODesc ios[] =
{
#if PL_CONFIG_USE_UART_SHELL
{&McuShellUart_stdio, McuShellUart_DefaultShellBuffer, sizeof(McuShellUart_DefaultShellBuffer)},
#endif
#if PL_CONFIG_USE_RTT
{&McuRTT_stdio, McuRTT_DefaultShellBuffer, sizeof(McuRTT_DefaultShellBuffer)},
#endif
#if PL_CONFIG_USE_USB_CDC_SHELL
{&USB_CdcStdio, USB_CdcDefaultShellBuffer, sizeof(USB_CdcDefaultShellBuffer)},
#endif
};
#if 0
/* do not send to all I/Os. Problem is with ESP32 echo enabled:
* everything typed in will end up twice for example in the RTT
*/
void SHELL_SendChar(unsigned char ch) {
for(unsigned int i=0;i<sizeof(ios)/sizeof(ios[0]);i++) {
McuShell_SendCh(ch, ios[i].stdio->stdOut);
}
}
#endif
uint8_t SHELL_ParseCommand(unsigned char *cmd) {
return McuShell_ParseWithCommandTable(cmd, McuShell_GetStdio(), CmdParserTable);
}
uint8_t SHELL_ParseCommandWithIO(unsigned char *cmd, McuShell_ConstStdIOType *io) {
return McuShell_ParseWithCommandTable(cmd, io, CmdParserTable);
}
void SHELL_SendString(unsigned char *str) {
for(unsigned int i=0;i<sizeof(ios)/sizeof(ios[0]);i++) {
McuShell_SendStr(str, ios[i].stdio->stdOut);
}
}
static void ShellTask(void *pv) {
unsigned int i;
(void)pv; /* not used */
McuLog_info("Shell task started.\r\n");
for(i=0;i<sizeof(ios)/sizeof(ios[0]);i++) {
ios[i].buf[0] = '\0';
}
for(;;) {
/* process all I/Os */
for(i=0;i<sizeof(ios)/sizeof(ios[0]);i++) {
(void)McuShell_ReadAndParseWithCommandTable(ios[i].buf, ios[i].bufSize, ios[i].stdio, CmdParserTable);
}
vTaskDelay(pdMS_TO_TICKS(20));
}
}
void SHELL_Init(void) {
if (xTaskCreate(
ShellTask, /* pointer to the task */
"Shell", /* task name for kernel awareness debugging */
800/sizeof(StackType_t), /* task stack size */
(void*)NULL, /* optional task startup argument */
tskIDLE_PRIORITY+2, /* initial priority */
(TaskHandle_t*)NULL /* optional task handle to create */
) != pdPASS)
{
for(;;){} /* error! probably out of memory */
}
McuShell_SetStdio(McuRTT_GetStdio()); /* use RTT as the default */
#if PL_CONFIG_USE_ESP32
McuESP32_SetRxFromESPStdio(&ESP_ToShellStdio); /* copy ESP UART to shell console */
#endif
#if McuLog_CONFIG_IS_ENABLED
#if PL_CONFIG_USE_RTT && PL_CONFIG_USE_UART_SHELL && McuLog_CONFIG_NOF_CONSOLE_LOGGER==2 /* both */
McuLog_set_console(McuRTT_GetStdio(), 0);
McuLog_set_console(&McuShellUart_stdio, 1);
#elif PL_CONFIG_USE_RTT /* only RTT */
McuLog_set_console(McuRTT_GetStdio(), 0);
#elif PL_CONFIG_USE_UART_SHELL /* only UART */
McuLog_set_console(&McuShellUart_stdio, 0);
#endif
#endif
}
void SHELL_Deinit(void) {}
#endif /* PL_CONFIG_USE_SHELL */