GadgetSeed  0.9.6
com_mem.c
[詳解]
1 /** @file
2  @brief メモリコマンド
3 
4  @date 2007.04.22
5  @author Takashi SHUDO
6 
7  @section mem_command memコマンド
8 
9  mem コマンドには以下のサブコマンドがあります。
10 
11  | サブコマンド | 機能 | 詳細 |
12  |:------------------|:------------------------------|:----------------------|
13  | dump | @copybrief com_mem_dump | @ref com_mem_dump |
14  | fill | @copybrief com_mem_fill | @ref com_mem_fill |
15  | edit | @copybrief com_mem_edit | @ref com_mem_edit |
16  | check | @copybrief com_mem_check | @ref com_mem_check |
17 */
18 
19 #include "asm.h"
20 #include "shell.h"
21 #include "lineedit.h"
22 #include "console.h"
23 #include "timer.h"
24 #include "str.h"
25 #include "tprintf.h"
26 #include "device.h"
27 
28 
29 /*
30  メモリダンプ
31 */
32 static unsigned char *mdAddr; // ダンプアドレス
33 static unsigned char mdDs; // ダンプメモリサイズ 1:char, 2:short, 4:long
34 
35 static void init_dump(void)
36 {
37 #ifdef GSC_TARGET_SYSTEM_EMU
38  #ifdef GSC_MEMORY_HEAP_IS_NEWLIB
39  mdAddr = 0;
40  #else
41  mdAddr = (unsigned char *)MEM_START;
42  #endif
43 #else
44  mdAddr = 0;
45 #endif
46  mdDs = 1;
47 }
48 
49 static int dump(int argc, uchar *argv[]);
50 
51 /**
52  @brief メモリダンプ結果を表示する
53 */
54 static const struct st_shell_command com_mem_dump = {
55  .name = "dump",
56  .init = init_dump,
57  .command = dump,
58  .attr = CMDATTR_CTAL,
59  .usage_str = "[-b|w|l] [start [end]]",
60  .manual_str = "Dump memory"
61 };
62 
63 static int dump(int argc, uchar *argv[])
64 {
65  unsigned char *ed = mdAddr + 256;
66  unsigned char *dp;
67  int i, an = 0;
68 
69  for(i=1; i<argc; i++) {
70  if(argv[i][0] == '-') {
71  switch(argv[i][1]) {
72  case 'b': mdDs = 1; break;
73  case 'w': mdDs = 2; break;
74  case 'l': mdDs = 4; break;
75  default:
76  break;
77  }
78  } else {
79  switch(an) {
80  case 0:
81  mdAddr = (unsigned char *)(long)hstoi(argv[i]);
82  ed = mdAddr + 256;
83  break;
84 
85  case 1:
86  ed = (unsigned char *)(long)hstoi(argv[i]);
87  break;
88 
89  default:
90  break;
91  }
92  an ++;
93  }
94  }
95 
96  for(dp=mdAddr; dp<ed; dp+=16) {
97  unsigned char *p;
98  uchar rd;
99 
100  tprintf("%p : ", dp);
101 
102  switch(mdDs) {
103  case 1:
104  for(p=dp; p<dp+8; p++) {
105  if(p < ed) {
106  tprintf("%02X ", (int)*p);
107  } else {
108  tprintf(" ");
109  }
110  }
111  tprintf(" ");
112  for(p=dp+8; p<dp+16; p++) {
113  if(p < ed) {
114  tprintf("%02X ", (int)*p);
115  } else {
116  tprintf(" ");
117  }
118  }
119  break;
120  case 2:
121  for(p=dp; p<dp+16; p+=2) {
122  if(p < ed) {
123  tprintf("%04X ", *(unsigned short *)p);
124  } else {
125  tprintf(" ");
126  }
127  }
128  break;
129 
130  case 4:
131  for(p=dp; p<dp+16; p+=4) {
132  if(p < ed) {
133  tprintf("%08lX ", *(unsigned long *)p);
134  } else {
135  tprintf(" ");
136  }
137  }
138  break;
139 
140  default:
141  break;
142  }
143 
144  tprintf(" \"");
145 
146  for(p=dp; p<dp+16; p++) {
147  if(p < ed) {
148  if(((' ' <= *p) && (*p <= 'Z'))
149  || (('a' <= *p) && (*p <= 'z'))) {
150  cputc(*p);
151  } else {
152  cputc('.');
153  }
154  } else {
155  break;
156  }
157  }
158  tprintf("\"\n");
159 
160  if(cgetcnw(&rd) == 0) {
161  if(rd == ASCII_CTRL_D) {
162  tprintf("Abort.\n");
163  return 0;
164  }
165  }
166  }
167 
168  mdAddr = ed;
169 
170  return 0;
171 }
172 
173 
174 static int fill(int argc, uchar *argv[]);
175 
176 /**
177  @brief 任意のメモリ範囲にメモリを任意の値を書き込む
178 */
179 static const struct st_shell_command com_mem_fill = {
180  .name = "fill",
181  .command = fill,
182  .usage_str = "<start> <end> <val>",
183  .manual_str = "Fill memory"
184 };
185 
186 static int fill(int argc, uchar *argv[])
187 {
188  unsigned char ds = 1; // 1:char, 2:short, 4:long
189  unsigned char *st = 0, *ed = 0;
190  unsigned char *dp;
191  unsigned int dt = 0;
192  int i, an = 0;
193 
194  for(i=1; i<argc; i++) {
195  if(argv[i][0] == '-') {
196  switch(argv[i][1]) {
197  case 'b': ds = 1; break;
198  case 'w': ds = 2; break;
199  case 'l': ds = 4; break;
200  default:
201  break;
202  }
203  } else {
204  switch(an) {
205  case 0:
206  st = (unsigned char *)(long)hstou(argv[i]);
207  an++;
208  break;
209 
210  case 1:
211  ed = (unsigned char *)(long)hstou(argv[i]);
212  an++;
213  break;
214 
215  case 2:
216  dt = (unsigned int)hstoi(argv[i]);
217  an++;
218  break;
219 
220  default:
221  break;
222  }
223  }
224  }
225 
226  if(an < 3) {
227  print_command_usage(&com_mem_fill);
228  return 0;
229  }
230 
231  tprintf("Fill memory %p - %p ", st, ed);
232 
233  switch(ds) {
234  case 1:
235  tprintf("%02X", dt);
236  break;
237 
238  case 2:
239  tprintf("%04X", dt);
240  break;
241 
242  case 4:
243  tprintf("%08X", dt);
244  break;
245 
246  default:
247  break;
248  }
249 
250  tprintf("\n");
251 
252  for(dp=st; dp<=ed; dp+=ds) {
253  switch(ds) {
254  case 1:
255  *dp = dt;
256  break;
257 
258  case 2:
259  *(unsigned short *)dp = (unsigned short)dt;
260  break;
261 
262  case 4:
263  *(unsigned long *)dp = (unsigned long)dt;
264  break;
265 
266  default:
267  break;
268  }
269  }
270 
271  return 0;
272 }
273 
274 
275 /*
276  メモリ編集
277 */
278 static void *meAddr; // 編集アドレス
279 
280 static void init_memedit(void)
281 {
282 #ifdef GSC_TARGET_SYSTEM_EMU
283  #ifdef GSC_MEMORY_HEAP_IS_NEWLIB
284  meAddr = 0;
285  #else
286  meAddr = MEM_START;
287  #endif
288 #else
289  meAddr = 0;
290 #endif
291 }
292 
293 static int memedit(int argc, uchar *argv[])
294 {
295  static int wi = 0; // 0:byte 1:word 2:long
296  unsigned char an = 1;
297 
298  switch(argv[0][1]) {
299  case 'b':
300  wi = 0;
301  break;
302 
303  case 'w':
304  wi = 1;
305  break;
306 
307  case 'l':
308  wi = 2;
309  break;
310  }
311 
312  if(argv[1][0] == '-') {
313  switch(argv[1][1]) {
314  case 'b':
315  wi = 0;
316  break;
317 
318  case 'w':
319  wi = 1;
320  break;
321 
322  case 'l':
323  wi = 2;
324  break;
325  }
326 
327  an ++;
328  }
329 
330  if(argc > an) {
331  meAddr = (void *)(unsigned long)hstou(argv[an]);
332  an ++;
333  }
334 
335  if(argc > an) {
336  // メモリ書き込み値あり
337 
338  int i;
339 
340  for(i=an; i<argc; i++) {
341 
342  switch(wi) {
343  case 0:
344  *(unsigned char *)meAddr =
345  (unsigned char)hstoi(argv[i]);
346  meAddr ++;
347  break;
348 
349  case 1:
350  *(unsigned short *)meAddr =
351  (unsigned short)hstoi(argv[i]);
352  meAddr += 2;
353  break;
354 
355  case 2:
356  *(unsigned long *)meAddr =
357  (unsigned long)hstoi(argv[i]);
358  meAddr += 4;
359  break;
360  }
361  }
362  } else {
363  // メモリ書き込み値無し
364 
365  tprintf("%p : ", meAddr);
366 
367  switch(wi) {
368  case 0:
369  tprintf("%02X", (int)*(unsigned char *)meAddr);
370  meAddr ++;
371  break;
372 
373  case 1:
374  tprintf("%04X", (int)*(unsigned short *)meAddr);
375  meAddr += 2;
376  break;
377 
378  case 2:
379  tprintf("%08lX", (long)*(unsigned long *)meAddr);
380  meAddr += 4;
381  break;
382  }
383 
384  tprintf("\n");
385  }
386 
387  return 0;
388 }
389 
390 /**
391  @brief メモリを編集する
392 */
393 static const struct st_shell_command com_mem_edit = {
394  .name = "edit",
395  .init = init_memedit,
396  .command = memedit,
397  .attr = CMDATTR_CTAL,
398  .usage_str = "[-b|w|l] [address] [value ...]",
399  .manual_str = "Edit memory"
400 };
401 
402 static const struct st_shell_command com_memedit_b = {
403  .name = "mb",
404  .command = memedit,
405  .attr = CMDATTR_CTAL,
406  .usage_str = "[address] [value ...]",
407  .manual_str = "Byte edit memory"
408 };
409 
410 static const struct st_shell_command com_memedit_w = {
411  .name = "mw",
412  .command = memedit,
413  .attr = CMDATTR_CTAL,
414  .usage_str = "[address] [value ...]",
415  .manual_str = "Word edit memory"
416 };
417 
418 static const struct st_shell_command com_memedit_l = {
419  .name = "ml",
420  .command = memedit,
421  .attr = CMDATTR_CTAL,
422  .usage_str = "[address] [value ...]",
423  .manual_str = "Long word edit memory"
424 };
425 
426 
427 /*
428  メモリチェック
429 */
430 
431 static int memory_check(unsigned long *sp, unsigned long *ep,
432  unsigned long data)
433 {
434  unsigned long *dp;
435  uchar rd;
436  int err = 0;
437 
438  tprintf("Writing %08lX...\n", data);
439 
440  for(dp=sp; dp<=ep; dp++) {
441  *dp = data;
442  if(cgetcnw(&rd)) {
443  if(rd == ASCII_CTRL_C) {
444  tprintf("\nAbort.\n");
445  return 1;
446  }
447  }
448  }
449 
450  tprintf("Checking...");
451  for(dp=sp; dp<=ep; dp++) {
452  if(*dp != data) {
453  err = 1;
454  tprintf("\nVerify Error at %p W:%08lX R:%08lX",
455  dp, data, *dp);
456  }
457  if(cgetcnw(&rd)) {
458  if(rd == ASCII_CTRL_C) {
459  tprintf("\nAbort.\n");
460  return 1;
461  }
462  }
463  }
464 
465  if(err) {
466  tprintf("\nNG.\n");
467  } else {
468  tprintf("OK.\n");
469  }
470 
471  return 0;
472 }
473 
474 static int memory_check_a(unsigned long *sp, unsigned long *ep)
475 {
476  unsigned long *dp;
477  uchar rd;
478  int err = 0;
479 
480  tprintf("Writing address data...\n");
481 
482  for(dp=sp; dp<=ep; dp++) {
483  *dp = (unsigned long)dp;
484  if(cgetcnw(&rd)) {
485  if(rd == ASCII_CTRL_C) {
486  tprintf("\nAbort.\n");
487  return 1;
488  }
489  }
490  }
491 
492  tprintf("Checking...");
493  for(dp=sp; dp<=ep; dp++) {
494  if(*dp != (unsigned long)dp) {
495  err = 1;
496  tprintf("\nVerify Error at %p W:%08lX R:%08lX", dp,
497  (unsigned long)dp,
498  (unsigned long)*dp);
499  }
500  if(cgetcnw(&rd)) {
501  if(rd == ASCII_CTRL_C) {
502  tprintf("\nAbort.\n");
503  return 1;
504  }
505  }
506  }
507 
508  if(err) {
509  tprintf("\nNG.\n");
510  } else {
511  tprintf("OK.\n");
512  }
513 
514  return 0;
515 }
516 
517 static int memory_check_ar(unsigned long *sp, unsigned long *ep)
518 {
519  unsigned long *dp;
520  uchar rd;
521  int err = 0;
522 
523  tprintf("Writing invert address data...\n");
524 
525  for(dp=sp; dp<=ep; dp++) {
526  *dp = ~((unsigned long)dp);
527  if(cgetcnw(&rd)) {
528  if(rd == ASCII_CTRL_C) {
529  tprintf("\nAbort.\n");
530  return 1;
531  }
532  }
533  }
534 
535  tprintf("Checking...");
536  for(dp=sp; dp<=ep; dp++) {
537  if(*dp != ~((unsigned long)dp)) {
538  err = 1;
539  tprintf("\nVerify Error at %p W:%08lX R:%08lX",
540  dp,
541  ~((unsigned long)dp),
542  (unsigned long)*dp);
543  }
544  if(cgetcnw(&rd)) {
545  if(rd == ASCII_CTRL_C) {
546  tprintf("\nAbort.\n");
547  return 1;
548  }
549  }
550  }
551 
552  if(err) {
553  tprintf("\nNG.\n");
554  } else {
555  tprintf("OK.\n");
556  }
557 
558  return 0;
559 }
560 
561 static int memory_check_aq(unsigned long *sp, unsigned long *ep)
562 {
563  unsigned long *dp;
564  uchar rd;
565  int err = 0;
566 
567  tprintf("Write and checking address data...\n");
568  tprintf("Checking...");
569 
570  for(dp=sp; dp<=ep; dp++) {
571  *dp = (unsigned long)dp;
572  if(*dp != (unsigned long)dp) {
573  err = 1;
574  tprintf("\nVerify Error at %p W:%08lX R:%08lX",
575  dp,
576  (unsigned long)dp,
577  (unsigned long)*dp);
578  }
579  if(cgetcnw(&rd)) {
580  if(rd == ASCII_CTRL_C) {
581  tprintf("\nAbort.\n");
582  return 1;
583  }
584  }
585  }
586 
587  if(err) {
588  tprintf("\nNG.\n");
589  } else {
590  tprintf("OK.\n");
591  }
592 
593  return 0;
594 }
595 
596 
597 static int com_memchk(int argc, uchar *argv[]);
598 
599 /**
600  @brief メモリのチェックを行う
601 */
602 static const struct st_shell_command com_mem_check = {
603  .name = "check",
604  .command = com_memchk,
605  .usage_str = "[Start [End]]",
606  .manual_str = "Memory check"
607 };
608 
609 /**
610  @brief メモリチェック
611  @param[in] argc コマンド引数の数
612  @param[in] argv コマンド引数文字列のポインタ
613  @return コマンド実行結果
614 */
615 static int com_memchk(int argc, uchar *argv[])
616 {
617 #ifdef GSC_TARGET_SYSTEM_EMU
618  #ifdef GSC_MEMORY_HEAP_IS_NEWLIB
619  unsigned long *sp = 0;
620  unsigned long *ep = 0;
621  #else
622  unsigned long *sp = (unsigned long *)MEM_START;
623  unsigned long *ep = (unsigned long *)MEM_END;
624  #endif
625 #else
626  unsigned long *sp = 0;
627  unsigned long *ep = 0;
628 #endif
629 
630  if(argc > 1) {
631  sp = (unsigned long *)(long)hstoi(argv[1]);
632  }
633 
634  if(argc > 2) {
635  ep = (unsigned long *)(long)hstoi(argv[2]);
636  }
637 
638  tprintf("Memory check.\n");
639  tprintf("Start : %p\n", sp);
640  tprintf("End : %p\n", ep);
641 
642  if(memory_check(sp, ep, 0x00000000)) goto end;
643  if(memory_check(sp, ep, 0xffffffff)) goto end;
644  if(memory_check(sp, ep, 0xaaaaaaaa)) goto end;
645  if(memory_check(sp, ep, 0x55555555)) goto end;
646  if(memory_check_a(sp, ep)) goto end;
647  if(memory_check_ar(sp, ep)) goto end;
648  if(memory_check_aq(sp, ep)) goto end;
649  if(memory_check(sp, ep, 0x55aa55aa)) goto end;
650  if(memory_check(sp, ep, 0x00ff00ff)) goto end;
651  if(memory_check(sp, ep, 0x00000000)) goto end;
652 
653 end:
654 
655  return 0;
656 }
657 
658 static const struct st_shell_command * const com_mem_list[] = {
659  &com_mem_dump,
660  &com_mem_fill,
661  &com_mem_edit,
662  &com_memedit_b,
663  &com_memedit_w,
664  &com_memedit_l,
665  &com_mem_check,
666  0
667 };
668 
669 const struct st_shell_command com_mem = {
670  .name = "mem",
671  .manual_str = "Memory operation commands",
672  .sublist = com_mem_list
673 }; ///< メモリ表示、編集
unsigned char uchar
GadgetSeedの文字(列)は unsigned char 型となる
Definition: str.h:13
シェルコマンド構造体
Definition: shell.h:33
コマンドシェル
static const struct st_shell_command com_mem_edit
メモリを編集する
Definition: com_mem.c:393
static const struct st_shell_command com_mem_dump
メモリダンプ結果を表示する
Definition: com_mem.c:54
static int com_memchk(int argc, uchar *argv[])
メモリチェック
Definition: com_mem.c:615
ラインエディタ
int cgetcnw(unsigned char *rd)
標準入力より1文字を取得する(待ち無し)
Definition: console.c:235
文字列処理
カーネルタイマ
static const struct st_shell_command com_mem_fill
任意のメモリ範囲にメモリを任意の値を書き込む
Definition: com_mem.c:179
static const struct st_shell_command com_mem_check
メモリのチェックを行う
Definition: com_mem.c:602
unsigned int hstou(uchar *str)
16進数文字列 unsigned int 変換
Definition: str.c:180
Cortex-M4
uchar name[12]
コマンド名文字列
Definition: shell.h:34
int cputc(unsigned char td)
標準出力より1文字を出力する
Definition: console.c:163
int tprintf(const char *fmt,...)
簡易printf
Definition: tprintf.c:85
コンソールI/O
int hstoi(uchar *str)
16進数文字列 int 変換
Definition: str.c:145
デバイスドライバAPI
機能限定printf