1 Star 4 Fork 8

vtor3478/vtor_elec_module

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
vtor_shell.c 13.71 KB
一键复制 编辑 原始数据 按行查看 历史
#include "vtor_shell.h"
#include "vtor_string.h"
#include "vtor_timer.h"
#ifdef __VTOR_SHELL__
VtorShell* vtorShellHeader = NULL;
void VtorShell_Void(void)
{
}
int VtorShell_Icon(void)
{
// https://www.lddgo.net/string/text-to-ascii-art
// Slant Fitted
VtorShell_PrintString("\r\n");
VtorShell_PrintString(" __ __ __ __\r\n");
VtorShell_PrintString(" _ __ / /_ ____ _____ _____ / /_ ___ / // /\r\n");
VtorShell_PrintString(" | | / // __// __ \\ / ___/ / ___// __ \\ / _ \\ / // / \r\n");
VtorShell_PrintString(" | |/ // /_ / /_/ // / (__ )/ / / // __// // / \r\n");
VtorShell_PrintString(" |___/ \\__/ \\____//_/ /____//_/ /_/ \\___//_//_/ \r\n");
VtorShell_PrintString("\r\n");
VtorShell_PrintString("\r\n");
return 0;
}
void VtorShell_Help(void)
{
VtorShell_PrintString("\tVtorShell_Help(void)\r\n");
VtorShell_PrintString("\tVtorShell designed by vtor3478@qq.com\r\n");
VtorShell_PrintString("\tcurrent date 2024-10-18\r\n\r\n");
VtorShell_PrintString("\texample:\r\n");
VtorShell_PrintString("\t\tlist\r\n");
VtorShell_PrintString("\t\tvoid\r\n");
VtorShell_PrintString("\t\tint 20 \r\n");
VtorShell_PrintString("\t\tint 0x24 \r\n");
VtorShell_PrintString("\t\tstr \"123abc\" \r\n");
VtorShell_PrintString("\t\thexstr '12 3a bc ef'\r\n");
VtorShell_PrintString("\t\tmem :123abc \r\n");
/*
注意,新增了 str hexstr mem参数,
str 使用 英文双引号 " 包起来,自带长度信息,
遇到null会结束,无法嵌套 英文双引号
举例 "123ab" ,实际上是0x31 0x32 0x33 0x41 0x42
hexstr 使用 英文单引号 包起来,缺少长度信息
建议在前面新增一个整型变量表示长度信息
hexstr实际上是使用十六进制表示字符,
可便于modbus rtu等十六进制设备的调试
遇到null或:或其他异常字符会结束,
内部数据只能是 0~9,a-f,A-F,空格
举例 '123abc' ,实际上是0x12 0x3a 0xbc
如果内部长度为奇数,会忽略掉最后一个数据,
为保证数据稳定性,最好使用偶数个数据
mem 使用 英文冒号作为开始符号,缺少长度,
建议在前面新增一个整型变量表示长度信息
mem参数没有结束符,所以仅能作为最后一个参数
mem参数没有结束符,所以可以支持0x00等特殊数值
举例 :12ab,实际上是0x31 0x32 0x41 0x42 ...(后续不确定)
*/
}
void VtorShell_List(void)
{
VtorShell* shell = vtorShellHeader;
if(NULL == shell)
{
return;
}
while(NULL != shell->shellFun)
{
uint8_t shellListBuf[50] = {0};
uint8_t* str = shellListBuf;
int32_t len = 50;
VtorString_Clear(str);
str = VtorString_AppendString(str, &len, "\t");
str = VtorString_AppendString(str, &len, shell->shellName);
str = VtorString_AppendString(str, &len, "\r\n");
VtorShell_PrintString(shellListBuf);
shell++;
}
}
int32_t VtorShell_Int(int32_t num)
{
uint8_t buf[50] = { 0 };
uint8_t* str = buf;
int32_t len = 50;
VtorString_Clear(str);
str = VtorString_AppendString(str, &len, "\tVtorShell_Int(");
str = VtorString_AppendInt(str, &len, num);
str = VtorString_AppendString(str, &len, ") = hex(0x");
str = VtorString_AppendHex(str, &len, num);
str = VtorString_AppendString(str, &len, ")\r\n");
VtorShell_PrintString(buf);
return num;
}
int32_t VtorShell_String(uint8_t* str)
{
uint8_t buf[100] = { 0 };
uint8_t* infoStr = buf;
int32_t len = 100;
VtorString_Clear(buf);
infoStr = VtorString_AppendString(infoStr, &len, "\tVtorShell_String(\"");
infoStr = VtorString_AppendString(infoStr, &len, str);
infoStr = VtorString_AppendString(infoStr, &len, "\")\r\n");
VtorShell_PrintString(buf);
return 0;
}
int32_t VtorShell_HexString(uint8_t* hexstr)
{
uint8_t buf[100] = { 0 };
uint8_t* infoStr = buf;
int32_t strlen = 100;
VtorString_Clear(buf);
infoStr = VtorString_AppendString(infoStr, &strlen, "\tVtorShell_HexString('");
infoStr = VtorString_AppendMemory(infoStr, &strlen, hexstr, 10, 1);
infoStr = VtorString_AppendString(infoStr, &strlen, "')\r\n");
return VtorShell_PrintString(buf);
}
int32_t VtorShell_Memory(uint8_t* memBuf)
{
uint8_t buf[150] = { 0 };
int32_t strlen = 150;
uint8_t* str = buf;
VtorString_Clear(str);
str = VtorString_AppendString(str, &strlen, "VtorShell_Memory :");
str = VtorString_AppendMemory(str, &strlen, memBuf, 10, 1);
str = VtorString_AppendString(str, &strlen, "\r\n");
return VtorShell_PrintString(buf);
}
int32_t VtorShell_Call(uint32_t addr)
{
return 0;
}
int32_t VtorShell_WriteInt32(int32_t addr, int32_t val)
{
*(int32_t*)addr = val;
return *(int32_t*)addr;
}
int32_t VtorShell_ReadInt32(int32_t addr)
{
return *(int32_t*)addr;
}
int32_t VtorShell_WriteMem(uint32_t addr, uint8_t* buf, int32_t cnt, int8_t width)
{
int8_t* byteMem = (int8_t*)addr;
#ifdef __VTOR_STRING_CONFIG_LITTLE_ENDIAN__
byteMem += width;
#endif
while(cnt--)
{
int i;
for(i = 0; i < width; i++)
{
#ifdef __VTOR_STRING_CONFIG_LITTLE_ENDIAN__
*--byteMem = *buf++;
#else
*byteMem++ = *buf++;
#endif
}
#ifdef __VTOR_STRING_CONFIG_LITTLE_ENDIAN__
byteMem += (width << 1);
#endif
}
return *(int32_t*)addr;
}
int32_t VtorShell_ReadMem(uint32_t addr, int32_t cnt, int8_t width)
{
uint8_t buf[150] = { 0 };
int32_t strlen = 150;
uint8_t* str = buf;
VtorString_Clear(str);
str = VtorString_AppendString(str, &strlen, "readmem :");
str = VtorString_AppendMemory(str, &strlen, (uint32_t*)addr, cnt, width);
str = VtorString_AppendString(str, &strlen, "\r\n");
VtorShell_PrintString(buf);
return *(int32_t*)addr;
}
#ifndef __VTOR_SHELL_CONFIG_GET_TIME_BY_USERSELF__
int32_t VtorShell_GetTime()
{
#ifdef __VTOR_TIMER__
return VtorTimer_GetTick();
#else
return 0;
#endif
}
#endif // __VTOR_SHELL_CONFIG_GET_TIME_BY_USERSELF__
VtorShell* VtorShell_GetShell(uint8_t* str)
{
int16_t mostSimilarity = 0;
VtorShell* shell = vtorShellHeader;
VtorShell* mostSimilarityShell = NULL;
if(NULL == shell)
{
return NULL;
}
while(shell->shellFun)
{
int16_t similarity = VtorString_GetSimilarity(str, shell->shellName);
if(similarity > 50 // 有足够的相似度
&& similarity > mostSimilarity) // 并且比历史最高更高
{
// 记录最大相似度的shell
mostSimilarityShell = shell;
mostSimilarity = similarity;
}
shell++;
}
// 返回相似度最高的shell
return mostSimilarityShell;
}
int32_t VtorShell_GetArg(uint8_t* str, int32_t* argv, int8_t* argt)
{
//char* splitArray = {" (),"};
int8_t argc = 0;
uint8_t* argStr = VtorString_FindString(str, " ");
uint8_t finishFlag = 0;
while(*argStr && 0 == finishFlag)
{
argStr = VtorString_GetNextValueType(argStr, argt);
if(VtorVar_Void == *argt)
{
break;
}
if(VtorVar_Int == *argt || VtorVar_Hex == *argt)
{
argStr = VtorString_FindInt(argStr, argv);
}
else if(VtorVar_String == *argt)
{
argStr = VtorString_CutString(argStr, argv);
}
else if(VtorVar_HexString == *argt)
{
argStr = VtorString_CutHexString(argStr, argv);
}
else if(VtorVar_Memory == *argt)
{
*argv = (uint32_t)(argStr + 1); // 后续都是mem
finishFlag = 1;
}
argv++;
argc++;
argt++;
}
return argc;
}
void VtorShell_PrintArg(VtorShell* shell, uint8_t argc, int32_t* argv, int8_t* argt)
{
uint8_t i = 0;
uint8_t infoBuf[127] = {0};
int32_t len = 127;
uint8_t* infoStr = infoBuf;
// 模仿python,3个右尖括号表示输入
infoStr = VtorString_AppendString(infoStr, &len, "\r\n>>> ");
infoStr = VtorString_AppendString(infoStr, &len, shell->shellName);
infoStr = VtorString_AppendString(infoStr, &len, " ");
for(i = 0; i < argc; i++)
{
if(VtorVar_Int == argt[i])
{
infoStr = VtorString_AppendInt(infoStr, &len, argv[i]);
}
else if(VtorVar_Hex == argt[i])
{
infoStr = VtorString_AppendString(infoStr, &len, "0x");
infoStr = VtorString_AppendHex(infoStr, &len, argv[i]);
}
else if(VtorVar_String == argt[i])
{
infoStr = VtorString_AppendString(infoStr, &len, "\"");
infoStr = VtorString_AppendString(infoStr, &len, (uint8_t*)(argv[i]));
infoStr = VtorString_AppendString(infoStr, &len, "\"");
}
else if(VtorVar_HexString == argt[i])
{
infoStr = VtorString_AppendString(infoStr, &len, " '");
infoStr = VtorString_AppendMemory(infoStr, &len, (void*)argv[i], 10, 1);
infoStr = VtorString_AppendString(infoStr, &len, "'");
}
else if(VtorVar_Memory == argt[i])
{
infoStr = VtorString_AppendString(infoStr, &len, ":");
infoStr = VtorString_AppendMemory(infoStr, &len, (void*)argv[i], 10, 1);
}
if(i == argc - 1)
{
break;
}
infoStr = VtorString_AppendString(infoStr, &len, " ");
}
infoStr = VtorString_AppendString(infoStr, &len, "\r\n");
VtorShell_PrintString(infoBuf);
}
void VtorShell_PrintRet(int32_t retVal, int32_t execTick)
{
uint8_t retBuf[127] = {0};
int32_t len = 127;
uint8_t* retStr = retBuf;
// 模仿python,3个左尖括号表示shell结束,将输出汇总到一行,节省空间
retStr = VtorString_AppendString(retStr, &len, "<<< return ");
retStr = VtorString_AppendInt(retStr, &len, retVal);
retStr = VtorString_AppendString(retStr, &len, " (0x");
retStr = VtorString_AppendHex(retStr, &len, retVal);
retStr = VtorString_AppendString(retStr, &len, "); // elapsed ");
retStr = VtorString_AppendInt(retStr, &len, execTick);
retStr = VtorString_AppendString(retStr, &len, " tick\r\n");
VtorShell_PrintString(retBuf);
}
#ifdef __VTOR_SHELL_CONFIG_MINI__
int32_t VtorShell_Scan(uint8_t* str)
{
VtorShell* shell = VtorShell_GetShell(str);
if(shell)
{
shell->shellFun();
}
return 0;
}
#else // __VTOR_SHELL_CONFIG_MINI__
int32_t VtorShell_Scan(uint8_t* userStr)
{
uint8_t str[256] = {0};
memcpy(str, userStr, 255); // 保留最后一个字符作为结束符
VtorString_Preprocess(str); // 允许用户使用注释且不影响使用
if('\t' == str[VtorString_Length(str) - 1])
{
VtorShell_Filter(str);
return 0;
}
VtorShell* shell = VtorShell_GetShell(str);
if(shell)
{
int32_t argValueBuf[10] = { 0 }; // 使用int32_t存储数值
int8_t argTypeBuf[10] = { 0 }; // 使用int32_t存储另外类型
int32_t* argv = argValueBuf;
int8_t* argt = argTypeBuf;
int8_t argc = VtorShell_GetArg(str, argv, argt);
VtorShell_PrintArg(shell, argc, argv, argt);
if(VtorString_GetSimilarity(shell->shellName, "call") > 50) // 如果是函数地址调用
{
// 如果是函数调用,那么移动参数指针,调整参数个数
shell->shellFun = (VtorShellFun)argv[0];
argc--;
argv++;
}
uint32_t execTick = VtorShell_GetTime();
int32_t retVal = VtorShell_Exec(shell, argc, argv);
execTick = VtorShell_GetTime() - execTick;
VtorShell_PrintRet(retVal, execTick);
return retVal;
}
else
{
// 执行失败,需要换行
VtorShell_PrintString("\r\n");
}
return 0;
}
// 扫描有哪些后续可用的函数
int32_t VtorShell_Filter(uint8_t* userStr)
{
VtorShell* shell = vtorShellHeader;
if(NULL == shell)
{
return 0;
}
// 获取长度,删除尾巴处 \t 转义字符,调整长度
int16_t userStrLen = VtorString_Length(userStr);
userStr[userStrLen - 1] = '\0';
userStrLen --;
int16_t simCnt = 0;
VtorShell_PrintString("\r\n"); // 先打印一个换行符,表明是list
while(NULL != shell->shellFun)
{
// 相似度足够的情况下,才打印对应的shell
int16_t sim = VtorString_GetSimilarity(shell->shellName, userStr);
if(sim >= userStrLen)
{
simCnt++;
uint8_t shellListBuf[50] = {0};
uint8_t* str = shellListBuf;
int32_t len = 50;
VtorString_Clear(str);
str = VtorString_AppendString(str, &len, "\t");
str = VtorString_AppendString(str, &len, shell->shellName);
str = VtorString_AppendString(str, &len, "\r\n");
VtorShell_PrintString(shellListBuf);
}
shell++;
}
// 打印用户已输入,为用户提供连贯性操作
VtorShell_PrintString(userStr);
return simCnt; // 返回满足筛选器的shell个数
}
int32_t VtorShell_AppendChar(const uint8_t ch)
{
// 打印用户输入的字符
uint8_t charBuf[2] = {ch, 0};
VtorShell_PrintString(charBuf);
static uint8_t userStrBuf[64] = {0};
static int16_t userStrLen = 0;
uint32_t ret = 0;
userStrBuf[userStrLen++] = ch;
if(userStrLen >= 64 - 1)
{
userStrLen = 0;
return 0;
}
if(userStrBuf[userStrLen - 1] == '\b') // 退格 0x08
{
if(userStrLen >= 2)
{
userStrLen -= 2;
}
userStrBuf[userStrLen] = '\0';
}
if(userStrBuf[userStrLen - 1] == '\t' // tab 0x09
|| userStrBuf[userStrLen - 1] == '\r'
|| userStrBuf[userStrLen - 1] == '\n')
{
userStrBuf[userStrLen] = '\0';
ret = VtorShell_Scan(userStrBuf);
// 只有执行完毕,清除输入缓冲区
if(userStrBuf[userStrLen - 1] == '\t')
{
userStrLen--;
}
else
{
userStrLen = 0;
userStrBuf[userStrLen] = '\0';
}
}
return ret;
}
#endif // __VTOR_SHELL_CONFIG_MINI__
int32_t VtorShell_Exec(VtorShell* shell, uint8_t argc, int32_t* argv)
{
int32_t ret = 0;
switch (argc)
{
case 0:
ret = shell->shellFun();
break;
case 1:
ret = shell->shellFun(argv[0]);
break;
case 2:
ret = shell->shellFun(argv[0], argv[1]);
break;
case 3:
ret = shell->shellFun(argv[0], argv[1], argv[2]);
break;
case 4:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[3]);
break;
case 5:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[3], argv[4]);
break;
case 6:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
break;
case 7:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
break;
case 8:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
break;
case 9:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
break;
case 10:
ret = shell->shellFun(argv[0], argv[1], argv[2], argv[2], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
break;
default:
break;
}
return ret;
}
#endif // __VTOR_SHELL__
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/vtor3478/vtor_elec_module.git
git@gitee.com:vtor3478/vtor_elec_module.git
vtor3478
vtor_elec_module
vtor_elec_module
main

搜索帮助

0d507c66 1850385 C8b1a773 1850385