Revision dd8738ea

View differences:

os/core/inc/aos_iostream.h
31 31
#define AOS_IOCHANNEL_ATTACHED                  (1 << 0)
32 32

  
33 33
/**
34
 * @brief   Channel flag to indicate whether the channel is set as input.
35
 */
36
#define AOS_IOCHANNEL_INPUT_ENABLE              (1 << 1)
37

  
38
/**
34 39
 * @brief   Channel flag to indicate whether the channel is set as output.
35 40
 */
36
#define AOS_IOCHANNEL_OUTPUT_ENABLE             (1 << 1)
41
#define AOS_IOCHANNEL_OUTPUT_ENABLE             (1 << 2)
37 42

  
38 43
/*
39 44
 * forward definitions
......
120 125
  void aosIOChannelInit(AosIOChannel* channel, BaseAsynchronousChannel* asyncchannel);
121 126
  void aosIOStreamAddChannel(AosIOStream* stream, AosIOChannel* channel);
122 127
  aos_status_t aosIOStreamRemoveChannel(AosIOStream* stream, AosIOChannel* channel);
128
  void aosIOChannelInputEnable(AosIOChannel* channel);
129
  void aosIOChannelInputDisable(AosIOChannel* channel);
123 130
  void aosIOChannelOutputEnable(AosIOChannel* channel);
124 131
  void aosIOChannelOutputDisable(AosIOChannel* channel);
125 132
#ifdef __cplusplus
os/core/inc/aos_shell.h
24 24

  
25 25
#include <hal.h>
26 26
#include <aos_types.h>
27
#include <aos_iostream.h>
27
//#include <aos_iostream.h>
28 28

  
29 29
/**
30 30
 * @brief   Shell event flag that is emitted when the thread starts.
......
102 102
 * @brief   AosShellChannel specific data.
103 103
 */
104 104
#define _aos_shell_channel_data                                             \
105
  /* pointer to a AosIOChannel object */                                    \
106
  AosIOChannel* iochannel;                                                  \
105
  /* pointer to a BaseAsynchronousChannel object */                         \
106
  BaseAsynchronousChannel* asyncchannel;                                    \
107 107
  /* event listener for the associated BaseAsynchronousChannel */           \
108 108
  event_listener_t listener;                                                \
109 109
  /* pointer to the next chennal in a AosShellStream */                     \
......
211 211
 * @brief   Enumerator to encode shell actions.
212 212
 */
213 213
typedef enum aos_shellaction {
214
  AOS_SHELL_ACTION_NONE,
214 215
  AOS_SHELL_ACTION_READCHAR,
215 216
  AOS_SHELL_ACTION_AUTOFILL,
216 217
  AOS_SHELL_ACTION_SUGGEST,
......
225 226
  AOS_SHELL_ACTION_CURSORRIGHT,
226 227
  AOS_SHELL_ACTION_EXECUTE,
227 228
  AOS_SHELL_ACTION_ESCSTART,
228
  AOS_SHELL_ACTION_NONE,
229 229
} aos_shellaction_t;
230 230

  
231 231
/**
......
344 344
#endif
345 345
  void aosShellInit(aos_shell_t* shell, event_source_t* oseventsource, const char* prompt, char* line, size_t linesize, char** arglist, size_t arglistsize);
346 346
  void aosShellStreamInit(AosShellStream* stream);
347
  void aosShellChannelInit(AosShellChannel* channel, AosIOChannel* iochannel);
347
  void aosShellChannelInit(AosShellChannel* channel, BaseAsynchronousChannel* asyncchannel);
348 348
  aos_status_t aosShellAddCommand(aos_shell_t* shell, aos_shellcommand_t* cmd);
349 349
  aos_status_t aosShellRemoveCommand(aos_shell_t* shell, char* cmd, aos_shellcommand_t** removed);
350 350
  void aosShellStreamAddChannel(AosShellStream* stream, AosShellChannel* channel);
os/core/src/aos_iostream.c
40 40
 */
41 41
static size_t _channelread(void *instance, uint8_t *bp, size_t n)
42 42
{
43
  return streamRead(((AosIOChannel*)instance)->asyncchannel, bp, n);
43
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_INPUT_ENABLE) {
44
    return streamRead(((AosIOChannel*)instance)->asyncchannel, bp, n);
45
  } else {
46
    return 0;
47
  }
44 48
}
45 49

  
46 50
/**
......
60 64
 */
61 65
static msg_t _channelget(void *instance)
62 66
{
63
  return streamGet(((AosIOChannel*)instance)->asyncchannel);
67
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_INPUT_ENABLE) {
68
    return streamGet(((AosIOChannel*)instance)->asyncchannel);
69
  } else {
70
    return MSG_RESET;
71
  }
64 72
}
65 73

  
66 74
/**
......
80 88
 */
81 89
static msg_t _channelgett(void *instance, systime_t time)
82 90
{
83
  return chnGetTimeout(((AosIOChannel*)instance)->asyncchannel, time);
91
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_INPUT_ENABLE) {
92
    return chnGetTimeout(((AosIOChannel*)instance)->asyncchannel, time);
93
  } else {
94
    return MSG_RESET;
95
  }
84 96
}
85 97

  
86 98
/**
......
100 112
 */
101 113
static size_t _channelreadt(void *instance, uint8_t *bp, size_t n, systime_t time)
102 114
{
103
  return chnReadTimeout(((AosIOChannel*)instance)->asyncchannel, bp, n, time);
115
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_INPUT_ENABLE) {
116
    return chnReadTimeout(((AosIOChannel*)instance)->asyncchannel, bp, n, time);
117
  } else {
118
    return 0;
119
  }
104 120
}
105 121

  
106 122
/**
......
160 176

  
161 177
  // local variables
162 178
  AosIOChannel* channel = ((AosIOStream*)instance)->channel;
163
  msg_t ret;
179
  msg_t ret = MSG_OK;
164 180

  
165 181
  // iterate through the list of channels
166 182
  while (channel != NULL) {
167
    ret = streamPut(channel, b);
168
    if (ret != MSG_OK) {
169
      return ret;
170
    }
183
    msg_t ret_ = streamPut(channel, b);
184
    ret = (ret_ < ret) ? ret_ : ret;
171 185
    channel = channel->next;
172 186
  }
173 187

  
174
  return MSG_OK;
188
  return ret;
175 189
}
176 190

  
177 191
/**
......
294 308
}
295 309

  
296 310
/**
311
 * @brief   Enable input for a AosIOChannel.
312
 *
313
 * @param[in] channel   The AosIOChannel to enable as input.
314
 */
315
void aosIOChannelInputEnable(AosIOChannel* channel)
316
{
317
  aosDbgCheck(channel != NULL);
318

  
319
  channel->flags |= AOS_IOCHANNEL_INPUT_ENABLE;
320

  
321
  return;
322
}
323

  
324
/**
325
 * @brief   Disable input for a AosIOChannel.
326
 *
327
 * @param[in] channel   The AosIOChannel to disable as input.
328
 */
329
void aosIOChannelInputDisable(AosIOChannel* channel)
330
{
331
  aosDbgCheck(channel != NULL);
332

  
333
  channel->flags &= ~AOS_IOCHANNEL_INPUT_ENABLE;
334

  
335
  return;
336
}
337

  
338
/**
297 339
 * @brief   Enable output for a AosIOChannel.
298 340
 *
299 341
 * @param[in] channel   The AosIOChannel to enable as output.
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

  
os/core/src/main.c
177 177
  aosIOChannelOutputEnable(&_stdiochannel);
178 178
  aosIOStreamAddChannel(&aos.iostream, &_stdiochannel);
179 179
#if (AMIROOS_CFG_SHELL_ENABLE == true)
180
  aosShellChannelInit(&_stdshellchannel, &_stdiochannel);
180
  aosShellChannelInit(&_stdshellchannel, (BaseAsynchronousChannel*)&MODULE_HAL_PROGIF);
181 181
  aosShellChannelInputEnable(&_stdshellchannel);
182 182
  aosShellChannelOutputEnable(&_stdshellchannel);
183 183
  aosShellStreamAddChannel(&aos.shell->stream, &_stdshellchannel);

Also available in: Unified diff