Revision dd8738ea os/core/src/aos_shell.c
os/core/src/aos_shell.c | ||
---|---|---|
44 | 44 |
static size_t _channelwrite(void *instance, const uint8_t *bp, size_t n) |
45 | 45 |
{ |
46 | 46 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) { |
47 |
return streamWrite(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n);
|
|
47 |
return streamWrite(((AosShellChannel*)instance)->asyncchannel, bp, n); |
|
48 | 48 |
} else { |
49 | 49 |
return 0; |
50 | 50 |
} |
... | ... | |
55 | 55 |
*/ |
56 | 56 |
static size_t _channelread(void *instance, uint8_t *bp, size_t n) |
57 | 57 |
{ |
58 |
return streamRead(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n); |
|
58 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) { |
|
59 |
return streamRead(((AosShellChannel*)instance)->asyncchannel, bp, n); |
|
60 |
} else { |
|
61 |
return 0; |
|
62 |
} |
|
59 | 63 |
} |
60 | 64 |
|
61 | 65 |
/** |
... | ... | |
64 | 68 |
static msg_t _channelput(void *instance, uint8_t b) |
65 | 69 |
{ |
66 | 70 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) { |
67 |
return streamPut(((AosShellChannel*)instance)->iochannel->asyncchannel, b);
|
|
71 |
return streamPut(((AosShellChannel*)instance)->asyncchannel, b); |
|
68 | 72 |
} else { |
69 | 73 |
return MSG_RESET; |
70 | 74 |
} |
... | ... | |
75 | 79 |
*/ |
76 | 80 |
static msg_t _channelget(void *instance) |
77 | 81 |
{ |
78 |
return streamGet(((AosShellChannel*)instance)->iochannel->asyncchannel); |
|
82 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) { |
|
83 |
return streamGet(((AosShellChannel*)instance)->asyncchannel); |
|
84 |
} else { |
|
85 |
return MSG_RESET; |
|
86 |
} |
|
79 | 87 |
} |
80 | 88 |
|
81 | 89 |
/** |
... | ... | |
84 | 92 |
static msg_t _channelputt(void *instance, uint8_t b, systime_t time) |
85 | 93 |
{ |
86 | 94 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) { |
87 |
return chnPutTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, b, time);
|
|
95 |
return chnPutTimeout(((AosShellChannel*)instance)->asyncchannel, b, time); |
|
88 | 96 |
} else { |
89 | 97 |
return MSG_RESET; |
90 | 98 |
} |
... | ... | |
95 | 103 |
*/ |
96 | 104 |
static msg_t _channelgett(void *instance, systime_t time) |
97 | 105 |
{ |
98 |
return chnGetTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, time); |
|
106 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) { |
|
107 |
return chnGetTimeout(((AosShellChannel*)instance)->asyncchannel, time); |
|
108 |
} else { |
|
109 |
return MSG_RESET; |
|
110 |
} |
|
99 | 111 |
} |
100 | 112 |
|
101 | 113 |
/** |
... | ... | |
104 | 116 |
static size_t _channelwritet(void *instance, const uint8_t *bp, size_t n, systime_t time) |
105 | 117 |
{ |
106 | 118 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) { |
107 |
return chnWriteTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n, time);
|
|
119 |
return chnWriteTimeout(((AosShellChannel*)instance)->asyncchannel, bp, n, time); |
|
108 | 120 |
} else { |
109 | 121 |
return 0; |
110 | 122 |
} |
... | ... | |
115 | 127 |
*/ |
116 | 128 |
static size_t _channelreadt(void *instance, uint8_t *bp, size_t n, systime_t time) |
117 | 129 |
{ |
118 |
return chnReadTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n, time); |
|
130 |
if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) { |
|
131 |
return chnReadTimeout(((AosShellChannel*)instance)->asyncchannel, bp, n, time); |
|
132 |
} else { |
|
133 |
return 0; |
|
134 |
} |
|
119 | 135 |
} |
120 | 136 |
|
121 | 137 |
static const struct AosShellChannelVMT _channelvmt = { |
... | ... | |
163 | 179 |
|
164 | 180 |
// local variables |
165 | 181 |
AosShellChannel* channel = ((AosShellStream*)instance)->channel; |
166 |
msg_t ret; |
|
182 |
msg_t ret = MSG_OK;
|
|
167 | 183 |
|
168 | 184 |
// iterate through the list of channels |
169 | 185 |
while (channel != NULL) { |
170 |
ret = streamPut(channel, b); |
|
171 |
if (ret != MSG_OK) { |
|
172 |
return ret; |
|
173 |
} |
|
186 |
msg_t ret_ = streamPut(channel, b); |
|
187 |
ret = (ret_ < ret) ? ret_ : ret; |
|
174 | 188 |
channel = channel->next; |
175 | 189 |
} |
176 | 190 |
|
177 |
return MSG_OK;
|
|
191 |
return ret;
|
|
178 | 192 |
} |
179 | 193 |
|
180 | 194 |
static msg_t _streamget(void *instance) |
... | ... | |
535 | 549 |
// local variables |
536 | 550 |
aos_shellaction_t action = AOS_SHELL_ACTION_NONE; |
537 | 551 |
char c; |
552 |
special_key_t key; |
|
538 | 553 |
|
539 | 554 |
// initialize output variables |
540 | 555 |
*n = 0; |
541 | 556 |
|
542 | 557 |
// read character by character from the channel |
543 | 558 |
while (chnReadTimeout(channel, (uint8_t*)&c, 1, TIME_IMMEDIATE)) { |
544 |
special_key_t key = KEY_UNKNOWN;
|
|
559 |
key = KEY_UNKNOWN; |
|
545 | 560 |
|
546 | 561 |
// parse escape sequence |
547 | 562 |
if (shell->inputdata.escp > 0) { |
... | ... | |
1094 | 1109 |
/** |
1095 | 1110 |
* @brief Initialize an AosShellChannel object with the specified parameters. |
1096 | 1111 |
* |
1097 |
* @param[in] channel The AosShellChannel to initialize. |
|
1098 |
* @param[in] iochannel An AosIOChannel this AosShellChannel is associated with.
|
|
1112 |
* @param[in] channel The AosShellChannel to initialize.
|
|
1113 |
* @param[in] asyncchannel An BaseAsynchronousChannel this AosShellChannel is associated with.
|
|
1099 | 1114 |
*/ |
1100 |
void aosShellChannelInit(AosShellChannel* channel, AosIOChannel* iochannel)
|
|
1115 |
void aosShellChannelInit(AosShellChannel* channel, BaseAsynchronousChannel* asyncchannel)
|
|
1101 | 1116 |
{ |
1102 | 1117 |
aosDbgCheck(channel != NULL); |
1103 |
aosDbgCheck(iochannel != NULL && iochannel->asyncchannel != NULL);
|
|
1118 |
aosDbgCheck(asyncchannel != NULL); |
|
1104 | 1119 |
|
1105 | 1120 |
channel->vmt = &_channelvmt; |
1106 |
channel->iochannel = iochannel; |
|
1121 |
channel->asyncchannel = asyncchannel; |
|
1122 |
channel->listener.wflags = 0; |
|
1107 | 1123 |
channel->next = NULL; |
1108 | 1124 |
channel->flags = 0; |
1109 | 1125 |
|
... | ... | |
1225 | 1241 |
void aosShellStreamAddChannel(AosShellStream* stream, AosShellChannel* channel) |
1226 | 1242 |
{ |
1227 | 1243 |
aosDbgCheck(stream != NULL); |
1228 |
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL && channel->next == NULL && (channel->flags & AOS_SHELLCHANNEL_ATTACHED) == 0);
|
|
1244 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL && channel->next == NULL && (channel->flags & AOS_SHELLCHANNEL_ATTACHED) == 0); |
|
1229 | 1245 |
|
1230 | 1246 |
// prepend the new channel |
1231 | 1247 |
chSysLock(); |
... | ... | |
1247 | 1263 |
aos_status_t aosShellStreamRemoveChannel(AosShellStream* stream, AosShellChannel* channel) |
1248 | 1264 |
{ |
1249 | 1265 |
aosDbgCheck(stream != NULL); |
1250 |
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL && channel->flags & AOS_SHELLCHANNEL_ATTACHED);
|
|
1266 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL && channel->flags & AOS_SHELLCHANNEL_ATTACHED); |
|
1251 | 1267 |
|
1252 | 1268 |
// local varibales |
1253 | 1269 |
AosShellChannel* prev = NULL; |
... | ... | |
1282 | 1298 |
*/ |
1283 | 1299 |
void aosShellChannelInputEnable(AosShellChannel* channel) |
1284 | 1300 |
{ |
1285 |
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1301 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL); |
|
1286 | 1302 |
|
1287 | 1303 |
chSysLock(); |
1288 | 1304 |
channel->listener.wflags |= CHN_INPUT_AVAILABLE; |
... | ... | |
1299 | 1315 |
*/ |
1300 | 1316 |
void aosShellChannelInputDisable( AosShellChannel* channel) |
1301 | 1317 |
{ |
1302 |
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1318 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL); |
|
1303 | 1319 |
|
1304 | 1320 |
chSysLock(); |
1305 | 1321 |
channel->listener.wflags &= ~CHN_INPUT_AVAILABLE; |
... | ... | |
1316 | 1332 |
*/ |
1317 | 1333 |
void aosShellChannelOutputEnable(AosShellChannel* channel) |
1318 | 1334 |
{ |
1319 |
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1335 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL); |
|
1320 | 1336 |
|
1321 | 1337 |
channel->flags |= AOS_SHELLCHANNEL_OUTPUT_ENABLED; |
1322 | 1338 |
|
... | ... | |
1330 | 1346 |
*/ |
1331 | 1347 |
void aosShellChannelOutputDisable(AosShellChannel* channel) |
1332 | 1348 |
{ |
1333 |
aosDbgCheck(channel != NULL && channel->iochannel != NULL && channel->iochannel->asyncchannel != NULL);
|
|
1349 |
aosDbgCheck(channel != NULL && channel->asyncchannel != NULL); |
|
1334 | 1350 |
|
1335 | 1351 |
channel->flags &= ~AOS_SHELLCHANNEL_OUTPUT_ENABLED; |
1336 | 1352 |
|
... | ... | |
1361 | 1377 |
chEvtRegisterMask(((aos_shell_t*)shell)->os.eventSource, &(((aos_shell_t*)shell)->os.eventListener), AOS_SHELL_EVENTMASK_OS); |
1362 | 1378 |
// register events to all input channels |
1363 | 1379 |
for (channel = ((aos_shell_t*)shell)->stream.channel; channel != NULL; channel = channel->next) { |
1364 |
chEvtRegisterMaskWithFlags(&(channel->iochannel->asyncchannel->event), &(channel->listener), AOS_SHELL_EVENTMASK_INPUT, channel->listener.wflags);
|
|
1380 |
chEvtRegisterMaskWithFlags(&(channel->asyncchannel->event), &(channel->listener), AOS_SHELL_EVENTMASK_INPUT, channel->listener.wflags); |
|
1365 | 1381 |
} |
1366 | 1382 |
|
1367 | 1383 |
// fire start event |
... | ... | |
1401 | 1417 |
eventflags = chEvtGetAndClearFlags(&channel->listener); |
1402 | 1418 |
// if there is new input |
1403 | 1419 |
if (eventflags & CHN_INPUT_AVAILABLE) { |
1404 |
// if the channel is configured as input |
|
1405 |
if (channel->flags & AOS_SHELLCHANNEL_INPUT_ENABLED) { |
|
1406 |
// read input from channel |
|
1407 |
readeval = _readChannel((aos_shell_t*)shell, channel, &nchars); |
|
1408 |
// parse input line to argument list only if the input shall be executed |
|
1409 |
nargs = (readeval == AOS_SUCCESS && nchars > 0) ? _parseArguments((aos_shell_t*)shell) : 0; |
|
1410 |
// check number of arguments |
|
1411 |
if (nargs > ((aos_shell_t*)shell)->arglistsize) { |
|
1412 |
// error too many arguments |
|
1413 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n"); |
|
1414 |
} else if (nargs > 0) { |
|
1415 |
// search command list for arg[0] and execute callback |
|
1416 |
cmd = ((aos_shell_t*)shell)->commands; |
|
1417 |
while (cmd != NULL) { |
|
1418 |
if (strcmp(((aos_shell_t*)shell)->arglist[0], cmd->name) == 0) { |
|
1419 |
((aos_shell_t*)shell)->execstatus.command = cmd; |
|
1420 |
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC); |
|
1421 |
((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, nargs, ((aos_shell_t*)shell)->arglist); |
|
1422 |
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE); |
|
1423 |
// notify if the command was not successful |
|
1424 |
if (((aos_shell_t*)shell)->execstatus.retval != 0) { |
|
1425 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "command returned exit status %d\n", ((aos_shell_t*)shell)->execstatus.retval); |
|
1426 |
} |
|
1427 |
break; |
|
1420 |
// read input from channel |
|
1421 |
readeval = _readChannel((aos_shell_t*)shell, channel, &nchars); |
|
1422 |
// parse input line to argument list only if the input shall be executed |
|
1423 |
nargs = (readeval == AOS_SUCCESS && nchars > 0) ? _parseArguments((aos_shell_t*)shell) : 0; |
|
1424 |
// check number of arguments |
|
1425 |
if (nargs > ((aos_shell_t*)shell)->arglistsize) { |
|
1426 |
// error too many arguments |
|
1427 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "\ttoo many arguments\n"); |
|
1428 |
} else if (nargs > 0) { |
|
1429 |
// search command list for arg[0] and execute callback |
|
1430 |
cmd = ((aos_shell_t*)shell)->commands; |
|
1431 |
while (cmd != NULL) { |
|
1432 |
if (strcmp(((aos_shell_t*)shell)->arglist[0], cmd->name) == 0) { |
|
1433 |
((aos_shell_t*)shell)->execstatus.command = cmd; |
|
1434 |
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_EXEC); |
|
1435 |
((aos_shell_t*)shell)->execstatus.retval = cmd->callback((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, nargs, ((aos_shell_t*)shell)->arglist); |
|
1436 |
chEvtBroadcastFlags(&(((aos_shell_t*)shell)->eventSource), AOS_SHELL_EVTFLAG_DONE); |
|
1437 |
// notify if the command was not successful |
|
1438 |
if (((aos_shell_t*)shell)->execstatus.retval != 0) { |
|
1439 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "command returned exit status %d\n", ((aos_shell_t*)shell)->execstatus.retval); |
|
1428 | 1440 |
} |
1429 |
cmd = cmd->next; |
|
1430 |
} /* end of while */ |
|
1431 |
|
|
1432 |
// if no matching command was found, print an error |
|
1433 |
if (cmd == NULL) { |
|
1434 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "%s: command not found\n", ((aos_shell_t*)shell)->arglist[0]); |
|
1441 |
break; |
|
1435 | 1442 |
} |
1436 |
} |
|
1443 |
cmd = cmd->next; |
|
1444 |
} /* end of while */ |
|
1437 | 1445 |
|
1438 |
// rreset some internal variables and eprint a new prompt |
|
1439 |
if (readeval == AOS_SUCCESS && !chThdShouldTerminateX()) { |
|
1440 |
((aos_shell_t*)shell)->inputdata.cursorpos = 0; |
|
1441 |
((aos_shell_t*)shell)->inputdata.lineend = 0; |
|
1442 |
_printPrompt((aos_shell_t*)shell); |
|
1446 |
// if no matching command was found, print an error |
|
1447 |
if (cmd == NULL) { |
|
1448 |
chprintf((BaseSequentialStream*)&((aos_shell_t*)shell)->stream, "%s: command not found\n", ((aos_shell_t*)shell)->arglist[0]); |
|
1443 | 1449 |
} |
1444 | 1450 |
} |
1445 |
// if the channel is not configured as input |
|
1446 |
else { |
|
1447 |
// read but drop all data |
|
1448 |
uint8_t c; |
|
1449 |
while (chnReadTimeout(channel, &c, 1, TIME_IMMEDIATE)) { |
|
1450 |
continue; |
|
1451 |
} |
|
1451 |
|
|
1452 |
// reset some internal variables and eprint a new prompt |
|
1453 |
if (readeval == AOS_SUCCESS && !chThdShouldTerminateX()) { |
|
1454 |
((aos_shell_t*)shell)->inputdata.cursorpos = 0; |
|
1455 |
((aos_shell_t*)shell)->inputdata.lineend = 0; |
|
1456 |
_printPrompt((aos_shell_t*)shell); |
|
1452 | 1457 |
} |
1453 | 1458 |
} |
1454 | 1459 |
|
Also available in: Unified diff