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.
 
 

156 lines
5.1 KiB

/*
* Copyright (c) 2019-2022, Erich Styger
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "platform.h"
#include "Shell.h"
#include "McuShell.h"
#include "McuRTT.h"
#include "McuArmTools.h"
#include "McuShellUart.h"
#include "McuLog.h"
#include "McuUtility.h"
#define SHELL_CMD_ELEM_SIZE (sizeof(Shell_cmd_s))
static QueueHandle_t shellCmdQueue;
static uint8_t splitFlapId = 0;
static void vQueueShellCmd(Shell_cmd_s shellCmd){
if(xQueueSendToBack(shellCmdQueue, &shellCmd, pdMS_TO_TICKS(100)) != pdPASS){
McuLog_warn("Failed adding shell cmd to queue, maybe full?");
}
}
static uint8_t ParseCommand(const uint8_t *cmd, bool *handled, McuShell_ConstStdIOType *io){
uint8_t size = sizeof(SHELL_CMD_IDENTIFY_SF)-1;
if (McuUtility_strcmp((char*)cmd, McuShell_CMD_HELP)==0) {
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
McuShell_SendStr((unsigned char*)McuShell_DASH_LINE, io->stdOut);
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)"SplitFlap Help", (const unsigned char*)"Group of SplitFlap commands\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" help", (const unsigned char*)"Print help this message\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)SHELL_CMD_IDENTIFY_SF, (const unsigned char*)"<SplitFlapId> (uint8_t)\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" ", (const unsigned char*)"the number printed on the splitflap\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" ", (const unsigned char*)"Splitflap Number:16\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)SHELL_CMD_POWEROFF_RPI, (const unsigned char*)"power of the raspberry pi\r\n", io->stdOut);
*handled = TRUE;
return ERR_OK;
} else if(McuUtility_strncmp((char*)cmd, SHELL_CMD_IDENTIFY_SF, size) == 0){
*handled = TRUE;
cmd += sizeof(SHELL_CMD_IDENTIFY_SF)-1;
if(McuUtility_ScanDecimal8uNumber(&cmd, &splitFlapId) != ERR_OK){
// Do not save id
return ERR_FAILED;
}
Shell_cmd_s shellCmd = {.shellCmd = Shell_Identify_SF, .value = (uint32_t)splitFlapId};
vQueueShellCmd(shellCmd);
} else if(McuUtility_strcmp((char*)cmd,SHELL_CMD_POWEROFF_RPI) == 0){
// shutown rpi
Shell_cmd_s shellCmd = {.shellCmd = Shell_Powerof_rpi, .value = 0};
vQueueShellCmd(shellCmd);
}
return ERR_OK;
}
static const McuShell_ParseCommandCallback CmdParserTable[] =
{
ParseCommand,
McuShell_ParseCommand,
McuRTOS_ParseCommand,
NULL /* Sentinel */
};
typedef struct {
McuShell_ConstStdIOType *stdio;
unsigned char *buf;
size_t bufSize;
} SHELL_IODesc;
static const SHELL_IODesc ios[] =
{
{&McuShellUart_stdio, McuShellUart_DefaultShellBuffer, sizeof(McuShellUart_DefaultShellBuffer)},
{&McuRTT_stdio, McuRTT_DefaultShellBuffer, sizeof(McuRTT_DefaultShellBuffer)},
// {&USB_CdcStdio, USB_CdcDefaultShellBuffer, sizeof(USB_CdcDefaultShellBuffer)},
};
QueueHandle_t SHELL_GetShellCmdQueueHandle() {
return shellCmdQueue;
}
void SHELL_SendChar(unsigned char ch) {
for(int i=0;i<sizeof(ios)/sizeof(ios[0]);i++) {
McuShell_SendCh(ch, ios[i].stdio->stdOut);
}
}
uint8_t SHELL_ParseCommandIO(const unsigned char *command, McuShell_ConstStdIOType *io, bool silent) {
if (io==NULL) { /* use a default */
io = McuShell_GetStdio();
}
return McuShell_ParseWithCommandTableExt(command, io, CmdParserTable, silent);
}
void SHELL_SendString(const unsigned char *str) {
for(int i=0;i<sizeof(ios)/sizeof(ios[0]);i++) {
McuShell_SendStr(str, ios[i].stdio->stdOut);
}
}
static void ShellTask(void *pv) {
int i;
McuLog_info("Shell task started");
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)
{
McuLog_fatal("failed creating Shell task");
for(;;){} /* error! probably out of memory */
}
// McuShell_SetStdio(McuRTT_GetStdio()); /* use RTT as the default */
if(McuShell_SetStdio(&McuShellUart_stdio) != ERR_OK){
// couldnt set uart as stdio, try set RTT
McuLog_warn("Failed to choose UART for shell, try RTT");
if(McuShell_SetStdio(McuRTT_GetStdio())!= ERR_OK){ /* use RTT as the default */
//couldnt set rtt!!
McuLog_fatal("failed to set rtt as default for shell");
for(;;){}
}else{
McuLog_info("RTT set for shell");
}
}else{
McuLog_info("UART set for shell");
}
shellCmdQueue = xQueueCreate(SHELL_CMD_QUEUE_LENGTH,SHELL_CMD_ELEM_SIZE);
if(shellCmdQueue == NULL){
McuLog_fatal("failed to create shell cmd queue!");
for(;;){}
}
vQueueAddToRegistry(shellCmdQueue, "Shell CMD Queue");
}
void SHELL_Deinit(void) {}