Revision ba516b61

View differences:

os/amiroos.h
67 67

  
68 68
#include "core/inc/aos_confcheck.h"
69 69
#include "core/inc/aos_debug.h"
70
#include <core/inc/aos_iostream.h>
70 71
#include "core/inc/aos_shell.h"
71
#include "core/inc/aos_ssm.h"
72 72
#include "core/inc/aos_system.h"
73 73
#include "core/inc/aos_thread.h"
74 74
#include "core/inc/aos_time.h"
os/core/core.mk
31 31

  
32 32
# C source files
33 33
AMIROOSCORECSRC = $(AMIROOS_CORE_DIR)src/aos_debug.c \
34
                  $(AMIROOS_CORE_DIR)src/aos_iostream.c \
34 35
                  $(AMIROOS_CORE_DIR)src/aos_shell.c \
35
                  $(AMIROOS_CORE_DIR)src/aos_ssm.c \
36 36
                  $(AMIROOS_CORE_DIR)src/aos_system.c \
37 37
                  $(AMIROOS_CORE_DIR)src/aos_thread.c \
38 38
                  $(AMIROOS_CORE_DIR)src/aos_timer.c \
os/core/inc/aos_iostream.h
1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

  
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

  
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

  
15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

  
19
#ifndef _AMIROOS_IOSTREAM_H_
20
#define _AMIROOS_IOSTREAM_H_
21

  
22
#include <hal.h>
23
#include <aos_types.h>
24
#include <stdarg.h>
25

  
26

  
27

  
28
/**
29
 * @brief   Channel flag to indicate whether the channel is attached to a stream.
30
 */
31
#define AOS_IOCHANNEL_ATTACHED                  (1 << 0)
32

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

  
38
/*
39
 * forward definitions
40
 */
41
typedef struct aos_iochannel AosIOChannel;
42
typedef struct aos_ostream AosIOStream;
43

  
44
/**
45
 * @brief   AosI=Channel specific methods.
46
 */
47
#define _aos_iochannel_methods                                              \
48
  _base_asynchronous_channel_methods
49

  
50
/**
51
 * @brief   AosIOChannel specific data.
52
 */
53
#define _aos_iochannel_data                                                 \
54
  /* pointer to a BaseAsynchronousChannel object */                         \
55
  BaseAsynchronousChannel* asyncchannel;                                    \
56
  /* pointer to the next channel in a AosIOStream */                        \
57
  AosIOChannel* next;                                                       \
58
  /* flags related to the channel */                                        \
59
  uint8_t flags;
60

  
61
/**
62
 * @extends BaseAsynchronousChannelVMT
63
 *
64
 * @brief   AosIOChannel virtual methods table.
65
 */
66
struct AosIOChannelVMT {
67
  _aos_iochannel_methods
68
};
69

  
70
/**
71
 * @extends BaseAsynchronousChannel
72
 *
73
 * @brief   I/O Channel class.
74
 * @details This class implements an asynchronous I/O channel.
75
 */
76
struct aos_iochannel {
77
  /** @brief Virtual Methods Table. */
78
  const struct AosIOChannelVMT* vmt;
79
  _aos_iochannel_data
80
};
81

  
82
/**
83
 * @brief   AosIOStream methods.
84
 */
85
#define _aos_iostream_methods                                               \
86
  _base_sequential_stream_methods
87

  
88
/**
89
 * @brief   AosIOStream data.
90
 */
91
#define _aos_iostream_data                                                  \
92
  /* Pointer to the first channel in a list. */                             \
93
  AosIOChannel* channel;
94

  
95
/**
96
 * @extends BaseSequentialStream
97
 *
98
 * @brief   AosIOStream virtual methods table.
99
 */
100
struct AosIOStreamVMT {
101
  _aos_iostream_methods
102
};
103

  
104
/**
105
 * @extends BaseSequentialStream
106
 *
107
 * @brief   I/O Stream class.
108
 * @details This class implements an base sequential stream.
109
 * @todo    So far only output but no input is supported.
110
 */
111
struct aos_ostream {
112
  const struct AosIOStreamVMT* vmt;
113
  _aos_iostream_data
114
};
115

  
116
#ifdef __cplusplus
117
extern "C" {
118
#endif
119
  void aosIOStreamInit(AosIOStream* stream);
120
  void aosIOChannelInit(AosIOChannel* channel, BaseAsynchronousChannel* asyncchannel);
121
  void aosIOStreamAddChannel(AosIOStream* stream, AosIOChannel* channel);
122
  aos_status_t aosIOStreamRemoveChannel(AosIOStream* stream, AosIOChannel* channel);
123
  void aosIOChannelOutputEnable(AosIOChannel* channel);
124
  void aosIOChannelOutputDisable(AosIOChannel* channel);
125
#ifdef __cplusplus
126
}
127
#endif
128

  
129
#endif /* _AMIROOS_IOSTREAM_H_ */
os/core/inc/aos_shell.h
19 19
#ifndef _AMIROOS_SHELL_H_
20 20
#define _AMIROOS_SHELL_H_
21 21

  
22
#include <aosconf.h>
23
#if (AMIROOS_CFG_SHELL_ENABLE == true)
24

  
22 25
#include <hal.h>
23 26
#include <aos_types.h>
27
#include <aos_iostream.h>
24 28

  
25 29
/**
26 30
 * @brief   Shell event flag that is emitted when the thread starts.
27 31
 */
28
#define AOS_SHELL_EVTFLAG_START                 ((eventflags_t)(1 << 0))
32
#define AOS_SHELL_EVTFLAG_START                   ((eventflags_t)(1 << 0))
29 33

  
30 34
/**
31 35
 * @brief   Shell event flag that is emitted when a command is executed.
32 36
 */
33
#define AOS_SHELL_EVTFLAG_EXEC                  ((eventflags_t)(1 << 1))
37
#define AOS_SHELL_EVTFLAG_EXEC                    ((eventflags_t)(1 << 1))
34 38

  
35 39
/**
36 40
 * @brief   Shell event flag that is emitted when a command execution finished.
37 41
 */
38
#define AOS_SHELL_EVTFLAG_DONE                  ((eventflags_t)(1 << 2))
42
#define AOS_SHELL_EVTFLAG_DONE                    ((eventflags_t)(1 << 2))
39 43

  
40 44
/**
41 45
 * @brief   Shell event flag that is emitted when the shread stops.
42 46
 */
43
#define AOS_SHELL_EVTFLAG_EXIT                  ((eventflags_t)(1 << 3))
47
#define AOS_SHELL_EVTFLAG_EXIT                    ((eventflags_t)(1 << 3))
44 48

  
45 49
/**
46 50
 * @brief   Shell event flag that is emitted when an I/O error occurred.
47 51
 */
48
#define AOS_SHELL_EVTFLAG_IOERROR               ((eventflags_t)(1 << 4))
52
#define AOS_SHELL_EVTFLAG_IOERROR                 ((eventflags_t)(1 << 4))
49 53

  
50 54
/**
51 55
 * @brief   Shell input configuration for replacing content by user input.
52 56
 */
53
#define AOS_SHELL_CONFIG_INPUT_OVERWRITE        (1 << 0)
57
#define AOS_SHELL_CONFIG_INPUT_OVERWRITE          (1 << 0)
54 58

  
55 59
/**
56 60
 * @brief   Shell prompt configuration print a minimalistic prompt.
57 61
 */
58
#define AOS_SHELL_CONFIG_PROMPT_MINIMAL         (1 << 1)
62
#define AOS_SHELL_CONFIG_PROMPT_MINIMAL           (1 << 1)
59 63

  
60 64
/**
61 65
 * @brief   Shell prompt configuration to additionally print the system uptime with the prompt.
62 66
 */
63
#define AOS_SHELL_CONFIG_PROMPT_UPTIME          (1 << 2)
67
#define AOS_SHELL_CONFIG_PROMPT_UPTIME            (1 << 2)
64 68

  
65 69
/**
66 70
 * @brief   Shell prompt configuration to additionally print the system uptime with the prompt.
67 71
 */
68
#define AOS_SHELL_CONFIG_MATCH_CASE             (1 << 3)
72
#define AOS_SHELL_CONFIG_MATCH_CASE               (1 << 3)
73

  
74
/**
75
 * @brief   Shell I/O channel flag whether the channel is attached to a list.
76
 */
77
#define AOS_SHELLCHANNEL_ATTACHED                 (1 << 0)
78

  
79
/**
80
 * @brief   Shell I/O channel flag whether the channel is enabled as input.
81
 */
82
#define AOS_SHELLCHANNEL_INPUT_ENABLED            (1 << 1)
83

  
84
/**
85
 * @brief   Shell I/O channel flag whether the channel is enabled as output.
86
 */
87
#define AOS_SHELLCHANNEL_OUTPUT_ENABLED           (1 << 2)
88

  
89
/*
90
 * forward definitions
91
 */
92
typedef struct aos_shellchannel AosShellChannel;
93
typedef struct aos_shellstream AosShellStream;
94

  
95
/**
96
 * @brief   AosShellChannel specific methods.
97
 */
98
#define _aos_shell_channel_methods                                          \
99
  _base_asynchronous_channel_methods
100

  
101
/**
102
 * @brief   AosShellChannel specific data.
103
 */
104
#define _aos_shell_channel_data                                             \
105
  /* pointer to a AosIOChannel object */                                    \
106
  AosIOChannel* iochannel;                                                  \
107
  /* event listener for the associated BaseAsynchronousChannel */           \
108
  event_listener_t listener;                                                \
109
  /* pointer to the next chennal in a AosShellStream */                     \
110
  AosShellChannel* next;                                                    \
111
  /* flags related to the channel */                                        \
112
  uint8_t flags;
113

  
114
/**
115
 * @extends BaseAsynchronousChannelVMT
116
 *
117
 * @brief   AosShellChannel virtual methods table.
118
 */
119
struct AosShellChannelVMT {
120
  _aos_shell_channel_methods
121
};
122

  
123
/**
124
 * @extends BaseAsynchronousChannel
125
 *
126
 * @brief   Shell channel class.
127
 * @details This class implements an asynchronous I/O channel.
128
 */
129
struct aos_shellchannel {
130
  /** @brief Virtual Methods Table. */
131
  const struct AosShellChannelVMT* vmt;
132
  _aos_shell_channel_data
133
};
134

  
135
/**
136
 * @brief   AosShellStream methods.
137
 */
138
#define _aos_shellstream_methods                                            \
139
  _base_sequential_stream_methods
140

  
141
/**
142
 * @brief   AosShellStream data.
143
 */
144
#define _aos_shellstream_data                                               \
145
  /* Pointer to the first channel in a list. */                             \
146
  AosShellChannel* channel;
147

  
148
/**
149
 * @extends BaseSequentialStream
150
 *
151
 * @brief   AosShellStream virtual methods table.
152
 */
153
struct AosShellStreamVMT {
154
  _aos_shellstream_methods
155
};
156

  
157
/**
158
 * @extends BaseSequentialStream
159
 *
160
 * @brief   Shell Stream class.
161
 * @details This class implements an base sequential stream.
162
 * @todo    So far only output but no input is supported.
163
 */
164
struct aos_shellstream {
165
  const struct AosShellStreamVMT* vmt;
166
  _aos_shellstream_data
167
};
69 168

  
70 169
/**
71 170
 * @brief   Shell command calback type.
......
90 189
   * @brief   Pointer to next command in a singly linked list.
91 190
   */
92 191
  struct aos_shellcommand* next;
192

  
93 193
} aos_shellcommand_t;
94 194

  
95 195
/**
96 196
 * @brief   Execution status of a shell command.
97 197
 */
98 198
typedef struct aos_shellexecstatus {
99
  aos_shellcommand_t* command;  /**< Pointer to the command that was executed. */
100
  int retval;                   /**< Return value of the executed command. */
199
  /**
200
   * @brief   Pointer to the command that was executed.
201
   */
202
  aos_shellcommand_t* command;
203

  
204
  /**
205
   * @brief   Return value of the executed command.
206
   */
207
  int retval;
101 208
} aos_shellexecstatus_t;
102 209

  
103 210
/**
211
 * @brief   Enumerator to encode shell actions.
212
 */
213
typedef enum aos_shellaction {
214
  AOS_SHELL_ACTION_READCHAR,
215
  AOS_SHELL_ACTION_AUTOFILL,
216
  AOS_SHELL_ACTION_SUGGEST,
217
  AOS_SHELL_ACTION_INSERTTOGGLE,
218
  AOS_SHELL_ACTION_DELETEFORWARD,
219
  AOS_SHELL_ACTION_DELETEBACKWARD,
220
  AOS_SHELL_ACTION_RECALLLAST,
221
  AOS_SHELL_ACTION_CLEAR,
222
  AOS_SHELL_ACTION_CURSOR2START,
223
  AOS_SHELL_ACTION_CURSOR2END,
224
  AOS_SHELL_ACTION_CURSORLEFT,
225
  AOS_SHELL_ACTION_CURSORRIGHT,
226
  AOS_SHELL_ACTION_EXECUTE,
227
  AOS_SHELL_ACTION_ESCSTART,
228
  AOS_SHELL_ACTION_NONE,
229
} aos_shellaction_t;
230

  
231
/**
104 232
 * @brief   Shell structure.
105 233
 */
106 234
typedef struct aos_shell {
......
115 243
  event_source_t eventSource;
116 244

  
117 245
  /**
118
   * @brief   Stream for user I/O.
246
   * @brief   Struct for OS related events
119 247
   */
120
  BaseSequentialStream* stream;
248
  struct {
249
    /**
250
     * @brief   Pointer to the OS' event source.
251
     */
252
    event_source_t* eventSource;
253

  
254
    /**
255
     * @brief   Listener for OS related events.
256
     */
257
    event_listener_t eventListener;
258
  } os;
259

  
260
  /**
261
     * @brief   Pointer to the first I/O channel.
262
     */
263
  AosShellStream stream;
121 264

  
122 265
  /**
123 266
   * @brief   String to printed as prompt.
......
146 289
  size_t linesize;
147 290

  
148 291
  /**
292
   * @brief   Structure containing data for internal input parsing.
293
   */
294
  struct {
295
    /**
296
     * @brief   The last action executed by the shell.
297
     */
298
    aos_shellaction_t lastaction;
299

  
300
    /**
301
     * @brief   Number of character in the current escape sequence.
302
     */
303
    uint8_t escp;
304

  
305
    /**
306
     * @brief   Buffer to store an escape sequence.
307
     */
308
    char escseq[5];
309

  
310
    /**
311
     * @brief   Current curso position.
312
     */
313
    size_t cursorpos;
314

  
315
    /**
316
     * @brief   Current line width.
317
     */
318
    size_t lineend;
319

  
320
    /**
321
     * @brief   Flag whether there was input since the prompt was printed the last time.
322
     */
323
    bool noinput;
324
  } inputdata;
325

  
326
  /**
149 327
   * @brief   Argument buffer.
150 328
   */
151 329
  char** arglist;
......
164 342
#ifdef __cplusplus
165 343
extern "C" {
166 344
#endif
167
  void aosShellInit(aos_shell_t* shell, BaseSequentialStream* stream, const char* prompt, char* line, size_t linesize, char** arglist, size_t arglistsize);
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
  void aosShellStreamInit(AosShellStream* stream);
347
  void aosShellChannelInit(AosShellChannel* channel, AosIOChannel* iochannel);
168 348
  aos_status_t aosShellAddCommand(aos_shell_t* shell, aos_shellcommand_t* cmd);
169 349
  aos_status_t aosShellRemoveCommand(aos_shell_t* shell, char* cmd, aos_shellcommand_t** removed);
350
  void aosShellStreamAddChannel(AosShellStream* stream, AosShellChannel* channel);
351
  aos_status_t aosShellStreamRemoveChannel(AosShellStream* stream, AosShellChannel* channel);
352
  void aosShellChannelInputEnable(AosShellChannel* channel);
353
  void aosShellChannelInputDisable( AosShellChannel* channel);
354
  void aosShellChannelOutputEnable(AosShellChannel* channel);
355
  void aosShellChannelOutputDisable(AosShellChannel* channel);
170 356
  THD_FUNCTION(aosShellThread, shell);
171 357
#ifdef __cplusplus
172 358
}
173 359
#endif
174 360

  
361
#endif /* AMIROOS_CFG_SHELL_ENABLE == true */
362

  
175 363
#endif /* _AMIROOS_SHELL_H_ */
os/core/inc/aos_ssm.h
1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

  
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

  
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

  
15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

  
19
#ifndef _AMIROOS_SSM_H_
20
#define _AMIROOS_SSM_H_
21

  
22
#include <hal.h>
23
#include <aos_types.h>
24
#include <aos_debug.h>
25

  
26
/**
27
 * @brief   Sequential Stream Multiplexer output structure.
28
 */
29
typedef struct ssm_output {
30
  /**
31
   * @brief   Pointer to a BaseSequentialStream object.
32
   */
33
  BaseSequentialStream* stream;
34

  
35
  /**
36
   * @brief   Pointer to the next element in a singly linked list.
37
   */
38
  struct ssm_output* next;
39

  
40
  /**
41
   * @brief   Flags related to the output.
42
   */
43
  uint8_t flags;
44
} ssm_output_t;
45

  
46
/**
47
 * @brief   Output flag to indicate whether the output is attached to a SSM list.
48
 */
49
#define SSM_OUTPUT_FLAG_ATTACHED                (1 << 0)
50

  
51
/**
52
 * @brief   Output flag to indicate whether the output is enabled.
53
 */
54
#define SSM_OUTPUT_FLAG_ENABLED                 (1 << 1)
55

  
56
/**
57
 * @brief   Sequential Stream Multiplexer specific methods.
58
 */
59
#define _sequential_stream_mux_methods          \
60
  _base_sequential_stream_methods               \
61

  
62
/**
63
 * @brief   Sequential Stream Multiplexer specific data.
64
 */
65
#define _sequential_stream_mux_data             \
66
  _base_sequential_stream_data                  \
67
  ssm_output_t* outputs;                        \
68
  BaseSequentialStream* input;                  \
69

  
70
/**
71
 * @brief   Sequential Stream Multiplexer virtual methods table.
72
 */
73
struct SequentialStreamMuxVMT {
74
  _sequential_stream_mux_methods
75
};
76

  
77
/**
78
 * @brief   Sequential Stream Multiplexer structure.
79
 */
80
typedef struct {
81
  /**
82
   * @brief   Virtual methods table.
83
   */
84
  const struct SequentialStreamMuxVMT *vmt;
85

  
86
  /**
87
   * @brief   Data fields.
88
   */
89
  _sequential_stream_mux_data
90
} SequentialStreamMux;
91

  
92
#ifdef __cplusplus
93
extern "C" {
94
#endif
95
  void ssmObjectInit(SequentialStreamMux* ssmp);
96
  void ssmOutputInit(ssm_output_t* op, BaseSequentialStream* stream);
97
  void ssmAddOutput(SequentialStreamMux* ssmp, ssm_output_t* output);
98
  aos_status_t ssmRemoveOutput(SequentialStreamMux* ssmp, BaseSequentialStream* stream, ssm_output_t** removed);
99
  aos_status_t ssmEnableOutput(SequentialStreamMux* ssmp, BaseSequentialStream* stream);
100
  aos_status_t ssmDisableOutput(SequentialStreamMux* ssmp, BaseSequentialStream* stream);
101
#ifdef __cplusplus
102
}
103
#endif
104

  
105
/**
106
 * @brief   Set the input stream
107
 *
108
 * @param[in] ssmp    pointer to the @p SequentialStreamMux object
109
 * @param[in] stream  pointer to a @p BaseSequentialStream or NULL to disable input
110
 */
111
static inline void ssmSetInput(SequentialStreamMux* ssmp, BaseSequentialStream* stream)
112
{
113
  aosDbgCheck(ssmp != NULL);
114

  
115
  ssmp->input = stream;
116

  
117
  return;
118
}
119

  
120
#endif /* _AMIROOS_SSM_H_ */
os/core/inc/aos_system.h
19 19
#ifndef _AMIROOS_SYSTEM_H_
20 20
#define _AMIROOS_SYSTEM_H_
21 21

  
22
#include <aos_ssm.h>
22
#include <aos_iostream.h>
23 23
#include <amiro-lld.h>
24 24
#include <aos_shell.h>
25 25
#include <aos_time.h>
26 26
#include <chprintf.h>
27 27

  
28 28
/**
29
 * @brief   Default system I/O stream.
30
 */
31
#define AOS_SYSTEM_STDIO                        ((BaseSequentialStream*)aos.ssm)
32

  
33
/**
34
 * @brief   Printf function that uses the default system I/O stream.
29
 * @brief   Resolution of the system time measurement.
35 30
 */
36
#define aosprintf(fmt, ...)                     chprintf((BaseSequentialStream*)AOS_SYSTEM_STDIO, fmt, ##__VA_ARGS__)
31
#define AOS_SYSTEM_TIME_RESOLUTION              ((MICROSECONDS_PER_SECOND + CH_CFG_ST_FREQUENCY - 1) / CH_CFG_ST_FREQUENCY)
37 32

  
38 33
/**
39
 * @brief   Resolution of the system time measurement.
34
 * @brief   System event flag which is emitted when a shutdown was initiated.
40 35
 */
41
#define AOS_SYSTEM_TIME_RESOLUTION              ((MICROSECONDS_PER_SECOND + CH_CFG_ST_FREQUENCY - 1) / CH_CFG_ST_FREQUENCY)
36
#define AOS_SYSTEM_EVENTFLAGS_SHUTDOWN          (eventflags_t)(1 << 0)
42 37

  
43 38
/**
44 39
 * @brief   System event flag which is emitted when a shutdown to transportation mode was initiated.
45 40
 */
46
#define AOS_SYSTEM_EVENTFLAGS_TRANSPORTATION    (eventflags_t)(1 << 0)
41
#define AOS_SYSTEM_EVENTFLAGS_TRANSPORTATION    (AOS_SYSTEM_EVENTFLAGS_SHUTDOWN | (eventflags_t)(1 << 1))
47 42

  
48 43
/**
49 44
 * @brief   System event flag which is emitted when a shutdown to deepsleep mode was initiated.
50 45
 */
51
#define AOS_SYSTEM_EVENTFLAGS_DEEPSLEEP         (eventflags_t)(1 << 1)
46
#define AOS_SYSTEM_EVENTFLAGS_DEEPSLEEP         (AOS_SYSTEM_EVENTFLAGS_SHUTDOWN | (eventflags_t)(1 << 2))
52 47

  
53 48
/**
54 49
 * @brief   System event flag which is emitted when a shutdown to hibernate mode was initiated.
55 50
 */
56
#define AOS_SYSTEM_EVENTFLAGS_HIBERNATE         (eventflags_t)(1 << 2)
51
#define AOS_SYSTEM_EVENTFLAGS_HIBERNATE         (AOS_SYSTEM_EVENTFLAGS_SHUTDOWN | (eventflags_t)(1 << 3))
57 52

  
58 53
/**
59 54
 * @brief   System event flag which is emitted when a system restart was initiated.
60 55
 */
61
#define AOS_SYSTEM_EVENTFLAGS_RESTART           (eventflags_t)(1 << 3)
56
#define AOS_SYSTEM_EVENTFLAGS_RESTART           (AOS_SYSTEM_EVENTFLAGS_SHUTDOWN | (eventflags_t)(1 << 4))
62 57

  
63 58
/**
64 59
 * @brief   Major version of the implemented SSSP.
......
114 109
  aos_ssspstage_t ssspStage;
115 110

  
116 111
  /**
112
   * @brief   System I/O stream.
113
   */
114
  AosIOStream iostream;
115

  
116
  /**
117 117
   * @brief   Event structure.
118 118
   */
119 119
  struct {
......
149 149
    } os;
150 150
  } events;
151 151

  
152
  /**
153
   * @brief   Sequentiel Stream Multiplexer for system I/O
154
   */
155
  SequentialStreamMux* ssm;
156

  
157 152
#if (AMIROOS_CFG_SHELL_ENABLE == true) || defined(__DOXYGEN__)
158 153
  /**
159 154
   * @brief   Pointer to the shell object.
......
168 163
 */
169 164
extern aos_system_t aos;
170 165

  
166
/**
167
 * @brief   Printf function that uses the default system I/O stream.
168
 */
169
#define aosprintf(fmt, ...)                     chprintf((BaseSequentialStream*)&aos.iostream, fmt, ##__VA_ARGS__)
170

  
171 171
#ifdef __cplusplus
172 172
extern "C" {
173 173
#endif
os/core/src/aos_iostream.c
1
/*
2
AMiRo-OS is an operating system designed for the Autonomous Mini Robot (AMiRo) platform.
3
Copyright (C) 2016..2018  Thomas Schöpping et al.
4

  
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9

  
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
GNU General Public License for more details.
14

  
15
You should have received a copy of the GNU General Public License
16
along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
*/
18

  
19
#include <aos_iostream.h>
20

  
21
#include <aos_debug.h>
22
#include <chprintf.h>
23

  
24

  
25

  
26
/**
27
 * @brief   Implementation of the BaseAsynchronousChannel write() method (inherited from BaseSequentialStream).
28
 */
29
static size_t _channelwrite(void *instance, const uint8_t *bp, size_t n)
30
{
31
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_OUTPUT_ENABLE) {
32
    return streamWrite(((AosIOChannel*)instance)->asyncchannel, bp, n);
33
  } else {
34
    return 0;
35
  }
36
}
37

  
38
/**
39
 * @brief   Implementation of the BaseAsynchronousChannel read() method (inherited from BaseSequentialStream).
40
 */
41
static size_t _channelread(void *instance, uint8_t *bp, size_t n)
42
{
43
  return streamRead(((AosIOChannel*)instance)->asyncchannel, bp, n);
44
}
45

  
46
/**
47
 * @brief   Implementation of the BaseAsynchronousChannel put() method (inherited from BaseSequentialStream).
48
 */
49
static msg_t _channelput(void *instance, uint8_t b)
50
{
51
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_OUTPUT_ENABLE) {
52
    return streamPut(((AosIOChannel*)instance)->asyncchannel, b);
53
  } else {
54
    return MSG_RESET;
55
  }
56
}
57

  
58
/**
59
 * @brief   Implementation of the BaseAsynchronousChannel get() method (inherited from BaseSequentialStream).
60
 */
61
static msg_t _channelget(void *instance)
62
{
63
  return streamGet(((AosIOChannel*)instance)->asyncchannel);
64
}
65

  
66
/**
67
 * @brief   Implementation of the BaseAsynchronousChannel putt() method.
68
 */
69
static msg_t _channelputt(void *instance, uint8_t b, systime_t time)
70
{
71
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_OUTPUT_ENABLE) {
72
    return chnPutTimeout(((AosIOChannel*)instance)->asyncchannel, b, time);
73
  } else {
74
    return MSG_RESET;
75
  }
76
}
77

  
78
/**
79
 * @brief   Implementation of the BaseAsynchronousChannel gett() method.
80
 */
81
static msg_t _channelgett(void *instance, systime_t time)
82
{
83
  return chnGetTimeout(((AosIOChannel*)instance)->asyncchannel, time);
84
}
85

  
86
/**
87
 * @brief   Implementation of the BaseAsynchronousChannel writet() method.
88
 */
89
static size_t _channelwritet(void *instance, const uint8_t *bp, size_t n, systime_t time)
90
{
91
  if (((AosIOChannel*)instance)->flags & AOS_IOCHANNEL_OUTPUT_ENABLE) {
92
    return chnWriteTimeout(((AosIOChannel*)instance)->asyncchannel, bp, n, time);
93
  } else {
94
    return 0;
95
  }
96
}
97

  
98
/**
99
 * @brief   Implementation of the BaseAsynchronousChannel readt() method.
100
 */
101
static size_t _channelreadt(void *instance, uint8_t *bp, size_t n, systime_t time)
102
{
103
  return chnReadTimeout(((AosIOChannel*)instance)->asyncchannel, bp, n, time);
104
}
105

  
106
/**
107
 * @brief   Virtual methods table for all AosIOChannel objects.
108
 */
109
static const struct AosIOChannelVMT _channelvmt = {
110
  _channelwrite,
111
  _channelread,
112
  _channelput,
113
  _channelget,
114
  _channelputt,
115
  _channelgett,
116
  _channelwritet,
117
  _channelreadt,
118
};
119

  
120
/**
121
 * @brief   Implementation of the BaseSequentialStream write() method.
122
 */
123
static size_t _streamwrite(void *instance, const uint8_t *bp, size_t n)
124
{
125
  aosDbgCheck(instance != NULL);
126

  
127
  // local variables
128
  AosIOChannel* channel = ((AosIOStream*)instance)->channel;
129
  size_t bytes;
130
  size_t maxbytes = 0;
131

  
132
  // iterate through the list of channels
133
  while (channel != NULL) {
134
    bytes = streamWrite(channel, bp, n);
135
    maxbytes = (bytes > maxbytes) ? bytes : maxbytes;
136
    channel = channel->next;
137
  }
138

  
139
  return maxbytes;
140
}
141

  
142
/**
143
 * @brief   Implementation of the BaseSequentialStream read() method.
144
 */
145
static size_t _stremread(void *instance, uint8_t *bp, size_t n)
146
{
147
  (void)instance;
148
  (void)bp;
149
  (void)n;
150

  
151
  return 0;
152
}
153

  
154
/**
155
 * @brief   Implementation of the BaseSequentialStream put() method.
156
 */
157
static msg_t _streamput(void *instance, uint8_t b)
158
{
159
  aosDbgCheck(instance != NULL);
160

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

  
165
  // iterate through the list of channels
166
  while (channel != NULL) {
167
    ret = streamPut(channel, b);
168
    if (ret != MSG_OK) {
169
      return ret;
170
    }
171
    channel = channel->next;
172
  }
173

  
174
  return MSG_OK;
175
}
176

  
177
/**
178
 * @brief   Implementation of the BaseSequentialStream get() method.
179
 */
180
static msg_t _streamget(void *instance)
181
{
182
  (void)instance;
183

  
184
  return 0;
185
}
186

  
187
/**
188
 * @brief   Virtual methods table for all AosIOStream objects.
189
 */
190
static const struct AosIOStreamVMT _streamvmt = {
191
  _streamwrite,
192
  _stremread,
193
  _streamput,
194
  _streamget,
195
};
196

  
197
/**
198
 * @brief   Initializes an aos_iostream_t object.
199
 *
200
 * @param[in] stream    Th aos_iostream_t object to initialize.
201
 */
202
void aosIOStreamInit(AosIOStream* stream)
203
{
204
  aosDbgCheck(stream != NULL);
205

  
206
  stream->vmt = &_streamvmt;
207
  stream->channel = NULL;
208

  
209
  return;
210
}
211

  
212
/**
213
 * @brief   Initializes an aos_iostream_channel_t object.
214
 *
215
 * @param[in] channel       The aos_iostream_channel_t to initialize.
216
 * @param[in] asyncchannel  The BaseAsynchronousChannel object to associate with te channel.
217
 */
218
void aosIOChannelInit(AosIOChannel *channel, BaseAsynchronousChannel *asyncchannel)
219
{
220
  aosDbgCheck(channel != NULL);
221
  aosDbgCheck(asyncchannel != NULL);
222

  
223
  channel->vmt = &_channelvmt;
224
  channel->asyncchannel = asyncchannel;
225
  channel->next = NULL;
226
  channel->flags = 0;
227

  
228
  return;
229
}
230

  
231
/**
232
 * @brief   Adds a channel to a stream.
233
 *
234
 * @param[in] stream    The stream to be expanded.
235
 * @param[in] channel   The channel to be added.
236
 */
237
void aosIOStreamAddChannel(AosIOStream *stream, AosIOChannel* channel)
238
{
239
  aosDbgCheck(stream != NULL);
240
  aosDbgCheck(channel != NULL && channel->asyncchannel != NULL && channel->next == NULL && (channel->flags & AOS_IOCHANNEL_ATTACHED) == 0);
241

  
242
  // prepend the new channel
243
  chSysLock();
244
  channel->flags |= AOS_IOCHANNEL_ATTACHED;
245
  channel->next = stream->channel;
246
  stream->channel = channel;
247
  chSysUnlock();
248

  
249
  return;
250
}
251

  
252
/**
253
 * @brief   Removes a channel from a stream.
254
 *
255
 * @param[in] stream        The stream to remove the channel from.
256
 * @param[in] asyncchannel  The BaseAsynchronousChannel to remove.
257
 * @param[out] removed      Pointer to the removed aos_iostream_channel_t.
258
 * @return
259
 */
260
aos_status_t aosIOStreamRemoveChannel(AosIOStream* stream, AosIOChannel* channel)
261
{
262
  aosDbgCheck(stream != NULL);
263
  aosDbgCheck(channel != NULL);
264

  
265
  // local variables
266
  AosIOChannel* prev = NULL;
267
  AosIOChannel* curr = stream->channel;
268

  
269
  // iterate through the list and search for the specified channel
270
  while (curr != NULL) {
271
    // if the channel was found, remove it
272
    if (curr == channel) {
273
      chSysLock();
274
      // special case: the first channel matches (prev is NULL)
275
      if (prev == NULL) {
276
        stream->channel = curr->next;
277
      } else {
278
        prev->next = curr->next;
279
      }
280
      curr->next = NULL;
281
      curr->flags &= ~AOS_IOCHANNEL_ATTACHED;
282
      chSysUnlock();
283
      return AOS_SUCCESS;
284
    }
285
    // iterate to the next channel
286
    else {
287
      prev = curr;
288
      curr = curr->next;
289
    }
290
  }
291

  
292
  // if the channel was not found, return an error
293
  return AOS_ERROR;
294
}
295

  
296
/**
297
 * @brief   Enable output for a AosIOChannel.
298
 *
299
 * @param[in] channel   The AosIOChannel to enable as output.
300
 */
301
void aosIOChannelOutputEnable(AosIOChannel* channel)
302
{
303
  aosDbgCheck(channel != NULL);
304

  
305
  channel->flags |= AOS_IOCHANNEL_OUTPUT_ENABLE;
306

  
307
  return;
308
}
309

  
310
/**
311
 * @brief   Disable output for a AosIOChannel.
312
 *
313
 * @param[in] channel   The AosIOChannel to disable as output.
314
 */
315
void aosIOChannelOutputDisable(AosIOChannel* channel)
316
{
317
  aosDbgCheck(channel != NULL);
318

  
319
  channel->flags &= ~AOS_IOCHANNEL_OUTPUT_ENABLE;
320

  
321
  return;
322
}
os/core/src/aos_shell.c
18 18

  
19 19
#include <aos_shell.h>
20 20

  
21
#if (AMIROOS_CFG_SHELL_ENABLE == true)
21 22
#include <aos_debug.h>
22 23
#include <aos_time.h>
23 24
#include <aos_system.h>
......
25 26
#include <string.h>
26 27
#include <aos_thread.h>
27 28

  
29

  
30

  
31
/**
32
 * @brief   Event mask to be set on OS related events.
33
 */
34
#define AOS_SHELL_EVENTMASK_OS                  EVENT_MASK(0)
35

  
36
/**
37
 * @brief   Event mask to be set on a input event.
38
 */
39
#define AOS_SHELL_EVENTMASK_INPUT               EVENT_MASK(1)
40

  
41
/**
42
 * @brief   Implementation of the BaseAsynchronous write() method (inherited from BaseSequentialStream).
43
 */
44
static size_t _channelwrite(void *instance, const uint8_t *bp, size_t n)
45
{
46
  if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
47
    return streamWrite(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n);
48
  } else {
49
    return 0;
50
  }
51
}
52

  
53
/**
54
 * @brief   Implementation of the BaseAsynchronous read() method (inherited from BaseSequentialStream).
55
 */
56
static size_t _channelread(void *instance, uint8_t *bp, size_t n)
57
{
58
  return streamRead(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n);
59
}
60

  
61
/**
62
 * @brief   Implementation of the BaseAsynchronous put() method (inherited from BaseSequentialStream).
63
 */
64
static msg_t _channelput(void *instance, uint8_t b)
65
{
66
  if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
67
    return streamPut(((AosShellChannel*)instance)->iochannel->asyncchannel, b);
68
  } else {
69
    return MSG_RESET;
70
  }
71
}
72

  
73
/**
74
 * @brief   Implementation of the BaseAsynchronous get() method (inherited from BaseSequentialStream).
75
 */
76
static msg_t _channelget(void *instance)
77
{
78
  return streamGet(((AosShellChannel*)instance)->iochannel->asyncchannel);
79
}
80

  
81
/**
82
 * @brief   Implementation of the BaseAsynchronous putt() method.
83
 */
84
static msg_t _channelputt(void *instance, uint8_t b, systime_t time)
85
{
86
  if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
87
    return chnPutTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, b, time);
88
  } else {
89
    return MSG_RESET;
90
  }
91
}
92

  
93
/**
94
 * @brief   Implementation of the BaseAsynchronous gett() method.
95
 */
96
static msg_t _channelgett(void *instance, systime_t time)
97
{
98
  return chnGetTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, time);
99
}
100

  
101
/**
102
 * @brief   Implementation of the BaseAsynchronous writet() method.
103
 */
104
static size_t _channelwritet(void *instance, const uint8_t *bp, size_t n, systime_t time)
105
{
106
  if (((AosShellChannel*)instance)->flags & AOS_SHELLCHANNEL_OUTPUT_ENABLED) {
107
    return chnWriteTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n, time);
108
  } else {
109
    return 0;
110
  }
111
}
112

  
113
/**
114
 * @brief   Implementation of the BaseAsynchronous readt() method.
115
 */
116
static size_t _channelreadt(void *instance, uint8_t *bp, size_t n, systime_t time)
117
{
118
  return chnReadTimeout(((AosShellChannel*)instance)->iochannel->asyncchannel, bp, n, time);
119
}
120

  
121
static const struct AosShellChannelVMT _channelvmt = {
122
  _channelwrite,
123
  _channelread,
124
  _channelput,
125
  _channelget,
126
  _channelputt,
127
  _channelgett,
128
  _channelwritet,
129
  _channelreadt,
130
};
131

  
132
static size_t _streamwrite(void *instance, const uint8_t *bp, size_t n)
133
{
134
  aosDbgCheck(instance != NULL);
135

  
136
  // local variables
137
  AosShellChannel* channel = ((AosShellStream*)instance)->channel;
138
  size_t bytes;
139
  size_t maxbytes = 0;
140

  
141
  // iterate through the list of channels
142
  while (channel != NULL) {
143
    bytes = streamWrite(channel, bp, n);
144
    maxbytes = (bytes > maxbytes) ? bytes : maxbytes;
145
    channel = channel->next;
146
  }
147

  
148
  return maxbytes;
149
}
150

  
151
static size_t _stremread(void *instance, uint8_t *bp, size_t n)
152
{
153
  (void)instance;
154
  (void)bp;
155
  (void)n;
156

  
157
  return 0;
158
}
159

  
160
static msg_t _streamput(void *instance, uint8_t b)
161
{
162
  aosDbgCheck(instance != NULL);
163

  
164
  // local variables
165
  AosShellChannel* channel = ((AosShellStream*)instance)->channel;
166
  msg_t ret;
167

  
168
  // iterate through the list of channels
169
  while (channel != NULL) {
170
    ret = streamPut(channel, b);
171
    if (ret != MSG_OK) {
172
      return ret;
173
    }
174
    channel = channel->next;
175
  }
176

  
177
  return MSG_OK;
178
}
179

  
180
static msg_t _streamget(void *instance)
181
{
182
  (void)instance;
183

  
184
  return 0;
185
}
186

  
187
static const struct AosShellStreamVMT _streamvmt = {
188
  _streamwrite,
189
  _stremread,
190
  _streamput,
191
  _streamget,
192
};
193

  
28 194
/**
29 195
 * @brief   Enumerator of special keyboard keys.
30 196
 */
......
64 230
static void _printPrompt(aos_shell_t* shell)
65 231
{
66 232
  aosDbgCheck(shell != NULL);
67
  aosDbgCheck(shell->stream != NULL);
68 233

  
69 234
  // print the system uptime before prompt is configured
70 235
  if (shell->config & AOS_SHELL_CONFIG_PROMPT_UPTIME) {
......
72 237
    aos_timestamp_t uptime;
73 238
    aosSysGetUptime(&uptime);
74 239

  
75
    chprintf(shell->stream, "[%01u:%02u:%02u:%02u:%03u:%03u] ",
76
           (uint32_t)(uptime / MICROSECONDS_PER_DAY),
77
           (uint8_t)(uptime % MICROSECONDS_PER_DAY / MICROSECONDS_PER_HOUR),
78
           (uint8_t)(uptime % MICROSECONDS_PER_HOUR / MICROSECONDS_PER_MINUTE),
79
           (uint8_t)(uptime % MICROSECONDS_PER_MINUTE / MICROSECONDS_PER_SECOND),
80
           (uint16_t)(uptime % MICROSECONDS_PER_SECOND / MICROSECONDS_PER_MILLISECOND),
81
           (uint16_t)(uptime % MICROSECONDS_PER_MILLISECOND / MICROSECONDS_PER_MICROSECOND));
240
    chprintf((BaseSequentialStream*)&shell->stream, "[%01u:%02u:%02u:%02u:%03u:%03u] ",
241
             (uint32_t)(uptime / MICROSECONDS_PER_DAY),
242
             (uint8_t)(uptime % MICROSECONDS_PER_DAY / MICROSECONDS_PER_HOUR),
243
             (uint8_t)(uptime % MICROSECONDS_PER_HOUR / MICROSECONDS_PER_MINUTE),
244
             (uint8_t)(uptime % MICROSECONDS_PER_MINUTE / MICROSECONDS_PER_SECOND),
245
             (uint16_t)(uptime % MICROSECONDS_PER_SECOND / MICROSECONDS_PER_MILLISECOND),
246
             (uint16_t)(uptime % MICROSECONDS_PER_MILLISECOND / MICROSECONDS_PER_MICROSECOND));
82 247
  }
83 248

  
84 249
  // print the actual prompt string
85 250
  if (shell->prompt && !(shell->config & AOS_SHELL_CONFIG_PROMPT_MINIMAL)) {
86
    chprintf(shell->stream, "%s$ ", shell->prompt);
251
    chprintf((BaseSequentialStream*)&shell->stream, "%s$ ", shell->prompt);
87 252
  } else {
88
    chprintf(shell->stream, "%>$ ");
253
    chprintf((BaseSequentialStream*)&shell->stream, "%>$ ");
89 254
  }
90 255

  
91 256
  return;
......
214 379
static int _moveCursor(aos_shell_t* shell, const size_t from, const size_t to)
215 380
{
216 381
  aosDbgCheck(shell != NULL);
217
  aosDbgCheck(shell->stream != NULL);
218 382

  
219 383
  // local variables
220 384
  size_t pos = from;
221 385

  
222 386
  // move cursor left by printing backspaces
223 387
  while (pos > to) {
224
    streamPut(shell->stream, '\b');
388
    streamPut(&shell->stream, '\b');
225 389
    --pos;
226 390
  }
227 391

  
228 392
  // move cursor right by printing line content
229 393
  while (pos < to) {
230
    streamPut(shell->stream, shell->line[pos]);
394
    streamPut(&shell->stream, shell->line[pos]);
231 395
    ++pos;
232 396
  }
233 397

  
......
246 410
static inline size_t _printLine(aos_shell_t* shell, const size_t from, const size_t to)
247 411
{
248 412
  aosDbgCheck(shell != NULL);
249
  aosDbgCheck(shell->stream != NULL);
250 413

  
251 414
  // local variables
252 415
  size_t cnt;
253 416

  
254 417
  for (cnt = 0; from + cnt < to; ++cnt) {
255
    streamPut(shell->stream, shell->line[from + cnt]);
418
    streamPut(&shell->stream, shell->line[from + cnt]);
256 419
  }
257 420

  
258 421
  return cnt;
......
363 526
  return _mapAscii2Custom(str1[i]) - _mapAscii2Custom(str2[i]);
364 527
}
365 528

  
366
/**
367
 * @brief   Reads a line from input stream
368
 * @details The line is directly written to the given shell object.
369
 *
370
 * @param[in] shell   Pointer to the shell object.
371
 *
372
 * @return              A status indicator.
373
 * @retval AOS_SUCCESS  Input sucessfully read, line is valid.
374
 * @retval AOS_ERROR    An I/O error occurred.
375
 */
376
static aos_status_t _readLine(aos_shell_t* shell)
529
static aos_status_t _readChannel(aos_shell_t* shell, AosShellChannel* channel, size_t* n)
377 530
{
378 531
  aosDbgCheck(shell != NULL);
379

  
380
  /*
381
   * Enumerator to encode a function.
382
   */
383
  typedef enum {
384
    READ_CHAR,
385
    AUTOFILL,
386
    SUGGEST,
387
    INS_TOGGLE,
388
    DELETE_FORWARD,
389
    DELETE_BACKWARD,
390
    RECALL_LAST,
391
    CLEAR,
392
    CURSOR2START,
393
    CURSOR2END,
394
    CURSOR_LEFT,
395
    CURSOR_RIGHT,
396
    EXECUTE,
397
    ESC_START,
398
    NONE,
399
  } func_t;
532
  aosDbgCheck(channel != NULL);
533
  aosDbgCheck(n != NULL);
400 534

  
401 535
  // local variables
402
  func_t func = NONE;
403
  func_t lastfunc = NONE;
404
  bool noinput = true;
405
  size_t lineend = 0;
406
  size_t cursorpos = 0;
536
  aos_shellaction_t action = AOS_SHELL_ACTION_NONE;
407 537
  char c;
408
  uint8_t escp = 0;
409
  char escseq[5] = {'\0'};
410 538

  
411
  // read character by character from stream
412
  while (streamRead(shell->stream, (uint8_t*)&c, 1)) {
539
  // initialize output variables
540
  *n = 0;
541

  
542
  // read character by character from the channel
543
  while (chnReadTimeout(channel, (uint8_t*)&c, 1, TIME_IMMEDIATE)) {
413 544
    special_key_t key = KEY_UNKNOWN;
414 545

  
415 546
    // parse escape sequence
416
    if (escp > 0) {
417
      escseq[escp] = c;
418
      ++escp;
419
      key = _interpreteEscapeSequence(escseq);
547
    if (shell->inputdata.escp > 0) {
548
      shell->inputdata.escseq[shell->inputdata.escp] = c;
549
      ++shell->inputdata.escp;
550
      key = _interpreteEscapeSequence(shell->inputdata.escseq);
420 551
      if (key == KEY_AMBIGUOUS) {
421 552
        // read next byte to resolve ambiguity
422 553
        continue;
423 554
      } else {
424
        // if the escape sequence could either be parsed sucessfully
425
        // or there is no match (KEY_UNKNOWN),
426
        // reset the sequence variables and interprete key/character
427
        escp = 0;
428
        memset(escseq, '\0', sizeof(escseq));
555
        /*
556
         * If the escape sequence could either be parsed sucessfully
557
         * or there is no match (KEY_UNKNOWN),
558
         * reset the sequence variable and interprete key/character
559
         */
560
        shell->inputdata.escp = 0;
561
        memset(shell->inputdata.escseq, '\0', sizeof(shell->inputdata.escseq)*sizeof(shell->inputdata.escseq[0]));
429 562
      }
430 563
    }
431 564

  
432
    // interprete keys or characters
565
    /* interprete keys or character */
433 566
    {
434
      func = NONE; // default
435
      if (key == KEY_UNKNOWN &&
436
          (/* printable character */ c >= '\x20' && c <= '\x7E') ) {
437
        func = READ_CHAR;
438
      } else if (key == KEY_TAB ||
439
                 /* horizontal tab ('\t') */ c == '\x09') {
440
        // pressing tab once applies auto fill,
441
        // presing a second time prints suggestions
442
        if (lastfunc == AUTOFILL || lastfunc == SUGGEST) {
443
          func = SUGGEST;
567
      // default
568
      action = AOS_SHELL_ACTION_NONE;
569

  
570
      // printable character
571
      if (key == KEY_UNKNOWN && c >= '\x20' && c <= '\x7E') {
572
        action = AOS_SHELL_ACTION_READCHAR;
573
      }
574

  
575
      // tab key or character
576
      else if (key == KEY_TAB || c == '\x09') {
577
        /*
578
         * pressing tab once applies auto fill
579
         * pressing tab a second time prints suggestions
580
         */
581
        if (shell->inputdata.lastaction == AOS_SHELL_ACTION_AUTOFILL || shell->inputdata.lastaction == AOS_SHELL_ACTION_SUGGEST) {
582
          action = AOS_SHELL_ACTION_SUGGEST;
444 583
        } else {
445
          func = AUTOFILL;
584
          action = AOS_SHELL_ACTION_AUTOFILL;
446 585
        }
447
      } else if (key == KEY_INSERT) {
448
        func = INS_TOGGLE;
449
      } else if (key == KEY_DELETE ||
450
                 /* [DEL] */ c == '\x7F') {
451
        // ignore of cursor is very right
452
        if (cursorpos < lineend) {
453
          func = DELETE_FORWARD;
586
      }
587

  
588
      // INS key
589
      else if (key == KEY_INSERT) {
590
        action = AOS_SHELL_ACTION_INSERTTOGGLE;
591
      }
592

  
593
      // DEL key or character
594
      else if (key == KEY_DELETE || c == '\x7F') {
595
        // ignore if cursor is at very right
596
        if (shell->inputdata.cursorpos < shell->inputdata.lineend) {
597
          action = AOS_SHELL_ACTION_DELETEFORWARD;
454 598
        }
455
      } else if (key == KEY_BACKSPACE ||
456
                 /* backpace ('\b') */c == '\x08') {
457
        // ignore if cursor is very left
458
        if (cursorpos > 0) {
459
          func = DELETE_BACKWARD;
599
      }
600

  
601
      // backspace key or character
602
      else if (key == KEY_BACKSPACE || c == '\x08') {
603
        // ignore if cursor is at very left
604
        if (shell->inputdata.cursorpos > 0) {
605
          action = AOS_SHELL_ACTION_DELETEBACKWARD;
460 606
        }
461
      } else if (key == KEY_PAGE_UP ||
462
                 key == KEY_ARROW_UP) {
607
      }
608

  
609
      // 'page up' of 'arrow up' key
610
      else if (key == KEY_PAGE_UP || key == KEY_ARROW_UP) {
463 611
        // ignore if there was some input
464
        if (noinput) {
465
          func = RECALL_LAST;
612
        if (shell->inputdata.noinput) {
613
          action = AOS_SHELL_ACTION_RECALLLAST;
466 614
        }
467
      } else if (key == KEY_PAGE_DOWN ||
468
                 key == KEY_ARROW_DOWN ||
469
                 /* end of test */ c == '\x03' ||
470
                 /* end of transmission */ c == '\x04') {
615
      }
616

  
617
      // 'page down' key, 'arrow done' key, 'end of test' character or 'end of transmission' character
618
      else if (key == KEY_PAGE_DOWN || key == KEY_ARROW_DOWN || c == '\x03' || c == '\x03') {
471 619
        // ignore if line is empty
472
        if (lineend > 0) {
473
          func = CLEAR;
620
        if (shell->inputdata.lineend > 0) {
621
          action = AOS_SHELL_ACTION_CLEAR;
474 622
        }
475
      } else if (key == KEY_HOME) {
623
      }
624

  
625
      // 'home' key
626
      else if (key == KEY_HOME) {
476 627
        // ignore if cursor is very left
477
        if (cursorpos > 0) {
478
          func = CURSOR2START;
628
        if (shell->inputdata.cursorpos > 0) {
629
          action = AOS_SHELL_ACTION_CURSOR2START;
479 630
        }
480
      } else if (key == KEY_END) {
481
        // ignore if cursor is very right
482
        if (cursorpos < lineend) {
483
          func = CURSOR2END;
631
      }
632

  
633
      // 'end' key
634
      else if (key == KEY_END) {
635
        // ignore if cursos is very right
636
        if (shell->inputdata.cursorpos < shell->inputdata.lineend) {
637
          action = AOS_SHELL_ACTION_CURSOR2END;
484 638
        }
485
      } else if (key == KEY_ARROW_LEFT) {
639
      }
640

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff