Rt-thread 中有一个完整的finsh(shell )系统,使用串口做命令行输入输出.但是想要用这个炫酷的工具就必须要上rtthread系统,或者花大力气将其移植出来.于是我就自己写了一个类似于这样的插件.只需要把一对.c/.h文件加入到你的工程,就可以实现这个简易版的shell.
git: https://github.com/KimAlittleStar/ExternFunc
ExternFunc.c
1 #include "stdio.h"
2 #include "string.h"
3 #include "ExternFunc.h"
4 #include "stm32f4xx_hal.h"
5
6 #define MATCH_CASE_ENABLE 0 //函数调用名称大小写是否敏感 1表示敏感 0 表示不敏感
7
8 void show(int i); 9 void showcircle(char ch,int r); 10
11 static int ExternFunc_Find(char* funcname); 12 static void ExternFunc_list(void); 13 static void ExternFunc_SocReset(void); 14 static unsigned char matchString(const char* str1,const char* str2); 15
16 const CALLFUNCTIONTABLE functable[] =
17 { 18 EXPOTRFUNC(LIST,ExternFunc_list, ,函数列表), 19 EXPOTRFUNC(RST,ExternFunc_SocReset,,芯片软件复位), 20 EXPOTRFUNC(circle,showcircle,%c %d,串口显示一个圆), 21 EXPOTRFUNC(九九乘法表,show,%d,%d乘法表) 22 }; 23 //EXPOTRFUNC( 函数别名命令行调用的名字 |真正的函数名 | 函数传参的格式字符串 |这个函数的简介)
24 void simplefunction(char* str,unsigned int sum,float dee,char ch) 25 { 26
27 printf("接收到的字符串是:%s,\n\
28 接收到的字符是: %c \n\ 29 接受到的数字是 %d\n\ 30 接收到的小数是 %f __ \n ",str,ch,sum,dee);
31 } 32
33 void showcircle(char ch,int r) 34 { 35 for(int i = 1; i<=(2*r); i++) 36 { 37 for(int j = 1; j<(2*r); j++) 38 { 39 if(((i-r)*(i-r)+(j-r)*(j-r))<=(r*r)) 40 printf("%c ",ch); 41 else
42 printf("%c ",' '); 43 } 44 printf("\n"); 45 } 46 } 47
48 void show(int i) 49 { 50 for(int qq = 1;qq<= i;qq++) 51 { 52 for(int j = 1;j<=qq;j++) 53 { 54 printf("%dx%d=%2d ",j,qq,j*qq); 55 } 56 printf("\n"); 57 } 58 } 59 //以上是示例的测试函数 60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 //以下是真正的实现函数 86
87 //找到对应函数的 函数指针 返回数组号 88 // 输入: "circle * 16" return 2
89 static int ExternFunc_Find(char* funcname) 90 { 91 int size = sizeof(functable)/sizeof(functable[0]); 92 for(int i = 0; i<size; i++) 93 { 94 if(matchString(funcname,functable[i].FuncName) == 0) 95 return i; 96 } 97 return -1; 98 } 99
100
101 //因为需要兼容字符串,所以需要二维数组 最多可以传参字符串长度为 (100-1)*4
102 static void* args[7][100] = {0}; 103
104 //外部调用函数,传入字符串自动找到对应函数 并执行.(不会打印返回值)
105 void ExternFunc_excute(char* str) 106 { 107 char* ptemp; 108 char ch; 109 ptemp = strstr(str," "); 110 if(ptemp == NULL) 111 { 112 ptemp = str+strlen(str); 113 ch = *ptemp; 114 } 115 else
116 { 117 ch = '\0'; 118 *ptemp = '\0'; 119 ptemp++; 120 } 121
122
123
124
125 int loc = ExternFunc_Find(str); //寻找函数
126 if(loc == -1) 127 { 128 printf("%s are not find\n the function list :\n",str); 129 ExternFunc_list(); 130 return ; 131 } 132
133 if(ch != '\0') 134 *ptemp = ch; 135 int success = sscanf(ptemp,functable[loc].fmt,&args[0][1],&args[1][1],&args[2][1],&args[3][1],&args[4][1],&args[5][1]); 136
137 //为兼容 可以输入字符串而做出的妥协
138 int i = 0; 139 ptemp = (char*)functable[loc].fmt; 140 for(i = 0;i<7;i++) 141 { 142 if((ptemp=strstr(ptemp,"%")) !=NULL) 143 { 144
145 if(*(++ptemp) == 's') 146 args[i][0] = &args[i][1]; 147 else
148 args[i][0] = args[i][1]; 149 }else break; 150 } 151 if(i!= success) 152 { 153 printf("Err: 函数%s 参数应该为%d个,但只有%d\n",functable[loc].FuncName,i,success); 154 return ; 155 } 156 //调用真正的函数
157 functable[loc].func(args[0][0],args[1][0],args[2][0],args[3][0],args[4][0],args[5][0],args[6][0]); 158