-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathttyConsole.cpp
More file actions
336 lines (261 loc) · 9.22 KB
/
ttyConsole.cpp
File metadata and controls
336 lines (261 loc) · 9.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#ifdef TRACE
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
#include <algorithm> // std::min
#include <functional>
#include "ch.h"
#include "hal.h"
#include "microrl/microrlShell.h"
#include "ttyConsole.hpp"
#include "stdutil.h"
#include "cpp_heap_alloc.hpp"
#include "globalVar.h"
#include "printf.h"
#include "portage.h"
#include "config.hpp"
#include "castle_link.hpp"
/*===========================================================================*/
/* START OF EDITABLE SECTION */
/*===========================================================================*/
// declaration des prototypes de fonction
// ces declarations sont necessaires pour remplir le tableau commands[] ci-dessous
static void cmd_mem(BaseSequentialStream *lchp, int argc,const char* const argv[]);
#if CH_DBG_THREADS_PROFILING
static void cmd_threads (BaseSequentialStream *lchp, int argc,const char * const argv[]);
#endif
static void cmd_uid(BaseSequentialStream *lchp, int argc,const char* const argv[]);
static void cmd_duty(BaseSequentialStream *lchp, int argc,const char* const argv[]);
static void cmd_param(BaseSequentialStream *lchp, int argc,const char* const argv[]);
static const ShellCommand commands[] = {
{"mem", cmd_mem}, // affiche la mémoire libre/occupée
#if CH_DBG_THREADS_PROFILING
{"threads", cmd_threads}, // affiche pour chaque thread le taux d'utilisation de la pile et du CPU
#endif
{"uid", cmd_uid}, // affiche le numéro d'identification unique du MCU
{"duty", cmd_duty}, // change pwm duty for attached castle link controler
{"param", cmd_param}, // fonction à but pedagogique qui affiche les
// paramètres qui lui sont passés
{NULL, NULL} // marqueur de fin de tableau
};
/*
definition de la fonction cmd_param asociée à la commande param (cf. commands[])
cette fonction a but pédagogique affiche juste les paramètres fournis, et tente
de convertir les paramètres en entier et en flottant, et affiche le resultat de
cette conversion.
une fois le programme chargé dans la carte, essayer de rentrer
param toto 10 10.5 0x10
dans le terminal d'eclipse pour voir le résultat
*/
static void cmd_param(BaseSequentialStream *lchp, int argc,const char* const argv[])
{
if (argc == 0) { // si aucun paramètre n'a été passé à la commande param
chprintf (lchp, "pas de paramètre en entrée\r\n");
} else { // sinon (un ou plusieurs pararamètres passés à la commande param
for (int argn=0; argn<argc; argn++) { // pour tous les paramètres
chprintf (lchp, "le parametre %d/%d est %s\r\n", argn, argc-1, argv[argn]); // afficher
// tentative pour voir si la chaine peut être convertie en nombre entier et en nombre flottant
int entier = atoi (argv[argn]); // atoi converti si c'est possible une chaine en entier
float flottant = atof (argv[argn]); // atof converti si c'est possible une chaine en flottant
chprintf (lchp, "atoi(%s) = %d ;; atof(%s) = %.3f\r\n",
argv[argn], entier, argv[argn], flottant);
}
}
}
/*
*/
/*===========================================================================*/
/* START OF PRIVATE SECTION : DO NOT CHANGE ANYTHING BELOW THIS LINE */
/*===========================================================================*/
/*===========================================================================*/
/* Command line related. */
/*===========================================================================*/
#define SHELL_WA_SIZE THD_WORKING_AREA_SIZE(4096)
#ifndef CONSOLE_DEV_USB
#define CONSOLE_DEV_USB 0
#endif
#if CONSOLE_DEV_USB == 0
static const SerialConfig ftdiConfig = {
115200,
0,
USART_CR2_STOP1_BITS | USART_CR2_LINEN,
0
};
#endif
#define MAX_CPU_INFO_ENTRIES 20
typedef struct _ThreadCpuInfo {
float ticks[MAX_CPU_INFO_ENTRIES];
float cpu[MAX_CPU_INFO_ENTRIES];
float totalTicks;
_ThreadCpuInfo () {
for (auto i=0; i< MAX_CPU_INFO_ENTRIES; i++) {
ticks[i] = 0.0f;
cpu[i] = -1.0f;
}
totalTicks = 0.0f;
}
} ThreadCpuInfo ;
#if CH_DBG_THREADS_PROFILING
static void stampThreadCpuInfo (ThreadCpuInfo *ti);
static float stampThreadGetCpuPercent (const ThreadCpuInfo *ti, const uint32_t idx);
#endif
static void cmd_uid(BaseSequentialStream *lchp, int argc,const char* const argv[]) {
(void)argv;
if (argc > 0) {
chprintf (lchp, "Usage: uid\r\n");
return;
}
chprintf (lchp, "uniq id : ");
for (uint32_t i=0; i< UniqProcessorIdLen; i++)
chprintf (lchp, "[%x] ", UniqProcessorId[i]);
chprintf (lchp, "\r\n");
}
static void cmd_duty(BaseSequentialStream *lchp, int argc,const char* const argv[]) {
(void)argv;
if (argc != 1) {
chprintf (lchp, "Usage: duty \r\n");
return;
}
const float rawDuty = atof(argv[0]);
const float duty = INRANGE(-20.0, 120.0, rawDuty);
if (duty != 0)
castleLinkSetDuty (500 + duty * 5);
else
castleLinkSetDuty (0);
DebugTrace ("set duty to %u", static_cast<uint16_t>(duty * 100));
}
static void cmd_mem(BaseSequentialStream *lchp, int argc,const char* const argv[]) {
(void)argv;
if (argc > 0) {
chprintf (lchp, "Usage: mem\r\n");
return;
}
chprintf (lchp, "core free memory : %u bytes\r\n", chCoreStatus());
chprintf (lchp, "heap free memory : %u bytes\r\n", getHeapFree());
void * ptr1 = malloc_m (100);
void * ptr2 = malloc_m (100);
chprintf (lchp, "(2x) malloc_m(1000) = %p ;; %p\r\n", ptr1, ptr2);
chprintf (lchp, "heap free memory : %d bytes\r\n", getHeapFree());
free_m (ptr1);
free_m (ptr2);
}
#if CH_DBG_THREADS_PROFILING
static void cmd_threads(BaseSequentialStream *lchp, int argc,const char* const argv[]) {
static const char *states[] = {THD_STATE_NAMES};
Thread *tp = chRegFirstThread();
(void)argv;
(void)argc;
float totalTicks=0;
float idleTicks=0;
static ThreadCpuInfo threadCpuInfo ;
stampThreadCpuInfo (&threadCpuInfo);
chprintf (lchp, " addr stack frestk prio refs state time \t percent name\r\n");
uint32_t idx=0;
do {
chprintf (lchp, "%.8lx %.8lx %6lu %4lu %4lu %9s %9lu %.1f \t%s\r\n",
(uint32_t)tp, (uint32_t)tp->ctx.sp,
get_stack_free (tp),
(uint32_t)tp->prio, (uint32_t)(tp->refs - 1),
states[tp->state], (uint32_t)tp->time,
stampThreadGetCpuPercent (&threadCpuInfo, idx),
chRegGetThreadName(tp));
totalTicks+= (float) tp->time;
if (strcmp (chRegGetThreadName(tp), "idle") == 0)
idleTicks = (float) tp->time;
tp = chRegNextThread ((Thread *)tp);
idx++;
} while (tp != NULL);
const float idlePercent = (idleTicks*100.f)/totalTicks;
const float cpuPercent = 100.f - idlePercent;
chprintf (lchp, "\r\ncpu load = %.2f%%\r\n", cpuPercent);
}
#endif
static const ShellConfig shell_cfg1 = {
#if CONSOLE_DEV_USB == 0
(BaseSequentialStream *) &SD_SHELL,
#else
(BaseSequentialStream *) &SDU1,
#endif
commands
};
void consoleInit (void)
{
/*
* Activates the USB driver and then the USB bus pull-up on D+.
* USBD1 : FS, USBD2 : HS
*/
sdStart(&SD_SHELL, &ftdiConfig);
/*
* Shell manager initialization.
*/
shellInit();
}
void consoleLaunch (void)
{
Thread *shelltp = NULL;
#if CONSOLE_DEV_USB != 0
if (!shelltp) {
systime_t time=90;
while (usbGetDriver()->state != USB_ACTIVE) {
if (time != 100) {
time++;
chThdSleepMilliseconds(100);
} else {
time=90;
//usbSerialReset(&SDU1);
}
}
// activate driver, giovani workaround
chnGetTimeout(&SDU1, TIME_IMMEDIATE);
while (!isUsbConnected()) {
chThdSleepMilliseconds(100);
}
shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
} else if (shelltp && (chThdTerminated(shelltp))) {
chThdRelease(shelltp); /* Recovers memory of the previous shell. */
shelltp = NULL; /* Triggers spawning of a new shell. */
}
#else
if (!shelltp) {
// palSetPad (BOARD_LED3_P, BOARD_LED3);
shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO);
} else if (chThdTerminated(shelltp)) {
chThdRelease(shelltp); /* Recovers memory of the previous shell. */
shelltp = NULL; /* Triggers spawning of a new shell. */
// palClearPad (BOARD_LED3_P, BOARD_LED3);
}
#endif //CONSOLE_DEV_USB
}
#if CH_DBG_THREADS_PROFILING
static void stampThreadCpuInfo (ThreadCpuInfo *ti)
{
const Thread *tp = chRegFirstThread();
uint32_t idx=0;
float totalTicks =0;
do {
totalTicks+= (float) tp->time;
ti->cpu[idx] = (float) tp->time - ti->ticks[idx];;
ti->ticks[idx] = (float) tp->time;
tp = chRegNextThread ((Thread *)tp);
idx++;
} while ((tp != NULL) && (idx < MAX_CPU_INFO_ENTRIES));
const float diffTotal = totalTicks- ti->totalTicks;
ti->totalTicks = totalTicks;
tp = chRegFirstThread();
idx=0;
do {
ti->cpu[idx] = (ti->cpu[idx]*100.f)/diffTotal;
tp = chRegNextThread ((Thread *)tp);
idx++;
} while ((tp != NULL) && (idx < MAX_CPU_INFO_ENTRIES));
}
static float stampThreadGetCpuPercent (const ThreadCpuInfo *ti, const uint32_t idx)
{
if (idx >= MAX_CPU_INFO_ENTRIES)
return -1.f;
return ti->cpu[idx];
}
#endif
#endif