GadgetSeed  0.9.6
com_device.c
[詳解]
1 /** @file
2  @brief デバイスアクセスコマンド
3 
4  @date 2007.04.22
5  @author Takashi SHUDO
6 
7  @section dev_command devコマンド
8 
9  dev コマンドには以下のサブコマンドがあります。
10 
11  | サブコマンド | 機能 | 詳細 |
12  |:------------------|:------------------------------|:----------------------|
13  | list | @copybrief com_dev_list | @ref com_dev_list |
14  | open | @copybrief com_dev_open | @ref com_dev_open |
15  | putc | @copybrief com_dev_putc | @ref com_dev_putc |
16  | getc | @copybrief com_dev_getc | @ref com_dev_getc |
17  | write | @copybrief com_dev_write | @ref com_dev_write |
18  | read | @copybrief com_dev_read | @ref com_dev_read |
19  | dump | @copybrief com_dev_dump | @ref com_dev_dump |
20  | ioctl | @copybrief com_dev_ioctl | @ref com_dev_ioctl |
21  | seek | @copybrief com_dev_seek | @ref com_dev_seek |
22  | blockread | @copybrief com_dev_blockread | @ref com_dev_blockread |
23  | capacity | @copybrief com_dev_capacity | @ref com_dev_capacity |
24  | suspend | @copybrief com_dev_suspend | @ref com_dev_suspend |
25  | resume | @copybrief com_dev_resume | @ref com_dev_resume |
26  | close | @copybrief com_dev_close | @ref com_dev_close |
27 */
28 
29 #include "shell.h"
30 #include "lineedit.h"
31 #include "console.h"
32 #include "str.h"
33 #include "tprintf.h"
34 
35 #define MAX_DEVWRITECNT 32
36 
37 static int dev_list(int argc, uchar *argv[])
38 {
39  int i;
40 
41  for(i=0; i<device_num(); i++) {
42  tprintf("%9s : %s\n", device_name(i), device_explan(i));
43  }
44 
45  return 0;
46 }
47 
48 /**
49  @brief 登録されているデバイスリスト表示
50 */
51 static const struct st_shell_command com_dev_list = {
52  .name = "list",
53  .command = dev_list,
54  .manual_str = "Print device list"
55 };
56 
57 
58 static int dev_open(int argc, uchar *argv[]);
59 
60 /**
61  @brief デバイスを開く
62 */
63 static const struct st_shell_command com_dev_open = {
64  .name = "open",
65  .command = dev_open,
66  .usage_str = "<device_name>",
67  .manual_str = "Open(only) device"
68 };
69 
70 static int dev_open(int argc, uchar *argv[])
71 {
72  struct st_device *dev;
73 
74  if(argc < 2) {
75  print_command_usage(&com_dev_open);
76  return 0;
77  }
78 
79  dev = open_device((char *)argv[1]);
80 
81  tprintf("return : 0x%p\n", dev);
82 
83  return 0;
84 }
85 
86 
87 static int dev_putc(int argc, uchar *argv[]);
88 
89 /**
90  @brief デバイスに1バイトデータを書き込む
91 */
92 static const struct st_shell_command com_dev_putc = {
93  .name = "putc",
94  .command = dev_putc,
95  .usage_str = "<device_name> [data ...]",
96  .manual_str = "1byte write data"
97 };
98 
99 static int dev_putc(int argc, uchar *argv[])
100 {
101  struct st_device *dev;
102  int i;
103  unsigned char data;
104  int len = 0;
105  int rt;
106 
107  if(argc < 3) {
108  print_command_usage(&com_dev_putc);
109  return 0;
110  }
111 
112  dev = open_device((char *)argv[1]);
113 
114  if(dev == 0) {
115  tprintf("Cannot open \"%s\".\n", argv[1]);
116  return 0;
117  }
118 
119  for(i=2; i<argc; i++) {
120  data = (unsigned char)hdstou(argv[i]);
121  rt = putc_device(dev, data);
122  len ++;
123  }
124 
125  tprintf("count : %d\n", len);
126 
127  tprintf("return : %d(0x%08X)\n", rt, rt);
128 
129  close_device(dev);
130 
131  return 0;
132 }
133 
134 
135 static int dev_getc(int argc, uchar *argv[]);
136 
137 /**
138  @brief デバイスより1バイトデータを読み出す
139 */
140 static const struct st_shell_command com_dev_getc = {
141  .name = "getc",
142  .command = dev_getc,
143  .usage_str = "<device_name>",
144  .manual_str = "1byte read data"
145 };
146 
147 static int dev_getc(int argc, uchar *argv[])
148 {
149  struct st_device *dev;
150  unsigned char data;
151  int rt;
152 
153  if(argc < 2) {
154  print_command_usage(&com_dev_getc);
155  return 0;
156  }
157 
158  dev = open_device((char *)argv[1]);
159 
160  if(dev == 0) {
161  tprintf("Cannot open \"%s\".\n", argv[1]);
162  return 0;
163  }
164 
165  rt = getc_device(dev, &data);
166 
167  tprintf("data : %02X\n", (int)data);
168 
169  tprintf("return : %d(0x%08X)\n", rt, rt);
170 
171  close_device(dev);
172 
173  return 0;
174 }
175 
176 
177 static int dev_write(int argc, uchar *argv[]);
178 
179 /**
180  @brief デバイスに任意のサイズのデータを書き込む
181 */
182 static const struct st_shell_command com_dev_write = {
183  .name = "write",
184  .command = dev_write,
185  .usage_str = "<device_name> [data ...]",
186  .manual_str = "Write data to device"
187 };
188 
189 static int dev_write(int argc, uchar *argv[])
190 {
191  struct st_device *dev;
192  int i;
193  unsigned char buf[MAX_DEVWRITECNT];
194  unsigned char *bp = buf;
195  unsigned int len = 0;
196  int rt;
197 
198  if(argc < 3) {
199  print_command_usage(&com_dev_write);
200  return 0;
201  }
202 
203  dev = open_device((char *)argv[1]);
204 
205  if(dev == 0) {
206  tprintf("Cannot open \"%s\".\n", argv[1]);
207  return 0;
208  }
209 
210  for(i=2; i<argc; i++) {
211  if(argv[i][0] == '\'') {
212  (void)strncopy(bp, &argv[i][1], MAX_DEVWRITECNT);
213  len += strleng(&argv[i][1]);
214  } else {
215  *bp = (unsigned char)hdstou(argv[i]);
216  bp ++;
217  len ++;
218  }
219  }
220 
221  tprintf("count : %d\n", len);
222 
223  rt = write_device(dev, buf, len);
224 
225  tprintf("return : %d(0x%08X)\n", rt, rt);
226 
227 // close_device(dev);
228 
229  return 0;
230 }
231 
232 #define MAX_DEVREADCNT 512
233 
234 static int dev_read(int argc, uchar *argv[]);
235 
236 /**
237  @brief デバイスより任意のサイズのデータを読み出す
238 */
239 static const struct st_shell_command com_dev_read = {
240  .name = "read",
241  .command = dev_read,
242  .usage_str = "<device_name> <size>",
243  .manual_str = "Read data from device"
244 };
245 
246 static int dev_read(int argc, uchar *argv[])
247 {
248  struct st_device *dev;
249  int i;
250  unsigned char buf[MAX_DEVREADCNT];
251  unsigned int size = 0;
252  int rt;
253 
254  if(argc < 3) {
255  print_command_usage(&com_dev_read);
256  return 0;
257  }
258 
259  dev = open_device((char *)argv[1]);
260 
261  if(dev == 0) {
262  tprintf("Cannot open \"%s\".\n", argv[1]);
263  return 0;
264  }
265 
266  if(argc > 2) {
267  size = (unsigned int)dstoi((uchar *)argv[2]);
268  if(size > MAX_DEVREADCNT) {
269  size = MAX_DEVREADCNT;
270  }
271  }
272 
273  rt = read_device(dev, buf, size);
274 
275  for(i=0; i<rt; i++) {
276  tprintf("%02x ", (int)buf[i]);
277  }
278 
279  tprintf("\n");
280  tprintf("return : %d(0x%08X)\n", rt, rt);
281 
282 // close_device(dev);
283 
284  return 0;
285 }
286 
287 
288 static int dev_dump(int argc, uchar *argv[]);
289 
290 /**
291  @brief デバイスより任意のサイズのデータを読み出しダンプ表示する
292 */
293 static const struct st_shell_command com_dev_dump = {
294  .name = "dump",
295  .command = dev_dump,
296  .usage_str = "<device_name> [start [size]]",
297  .manual_str = "Dump data from device"
298 };
299 
300 static int dev_dump(int argc, uchar *argv[])
301 {
302  struct st_device *dev;
303  int i, j;
304  unsigned char buf[MAX_DEVREADCNT];
305  int start = 0;
306  unsigned int size = MAX_DEVREADCNT;
307  int rt = 0;
308 
309  if(argc < 3) {
310  print_command_usage(&com_dev_dump);
311  return 0;
312  }
313 
314  dev = open_device((char *)argv[1]);
315 
316  if(dev == 0) {
317  tprintf("Cannot open \"%s\".\n", argv[1]);
318  return 0;
319  }
320 
321  if(argc > 2) {
322  start = hdstoi(argv[2]);
323  }
324 
325  if(argc > 3) {
326  size = (unsigned int)hdstoi(argv[3]);
327  if(size > MAX_DEVREADCNT) {
328  size = MAX_DEVREADCNT;
329  }
330  }
331 
332  seek_device(dev, start, SEEK_SET);
333  rt += read_device(dev, buf, size);
334 
335  for(j=0; j<rt; j+=16) {
336  uchar rd;
337 
338  tprintf("%08X : ", start+j);
339 
340  for(i=0; i<8; i++) {
341  if((j+i) < rt) {
342  tprintf("%02X ", (int)buf[j+i]);
343  } else {
344  tprintf(" ");
345  }
346  }
347  tprintf(" ");
348  for(i=8; i<16; i++) {
349  if((j+i) < rt) {
350  tprintf("%02X ", (int)buf[j+i]);
351  } else {
352  tprintf(" ");
353  }
354  }
355 
356  tprintf(" \"");
357 
358  for(i=0; i<16; i++) {
359  if((j+i) < rt) {
360  if(((' ' <= buf[j+i]) && (buf[j+i] <= 'Z'))
361  || (('a' <= buf[j+i]) && (buf[j+i] <= 'z'))) {
362  cputc(buf[j+i]);
363  } else {
364  cputc('.');
365  }
366  } else {
367  break;
368  }
369  }
370  tprintf("\"\n");
371 
372  if(cgetcnw(&rd) == 0) {
373  if(rd == ASCII_CTRL_C) {
374  tprintf("Abort.\n");
375  return 0;
376  }
377  }
378  }
379 
380  tprintf("\n");
381  tprintf("return : %d(0x%08X)\n", rt, rt);
382 
383 // close_device(dev);
384 
385  return 0;
386 }
387 
388 
389 static int dev_seek(int argc, uchar *argv[]);
390 
391 /**
392  @brief デバイスのアクセス位置を設定する
393 */
394 static const struct st_shell_command com_dev_seek = {
395  .name = "seek",
396  .command = dev_seek,
397  .usage_str = "<device_name> [offset [whence]]",
398  .manual_str = "Seek device address"
399 };
400 
401 static int dev_seek(int argc, uchar *argv[])
402 {
403  struct st_device *dev;
404  int offset = 0;
405  int whence = 0;
406  int rt = 0;
407 
408  if(argc < 2) {
409  print_command_usage(&com_dev_seek);
410  return 0;
411  }
412 
413  dev = open_device((char *)argv[1]);
414 
415  if(dev == 0) {
416  tprintf("Cannot open \"%s\".\n", argv[1]);
417  return 0;
418  }
419 
420  if(argc > 2) {
421  offset = hdstoi(argv[2]);
422  }
423 
424  if(argc > 3) {
425  whence = hdstoi(argv[3]);
426  }
427 
428  rt = seek_device(dev, offset, whence);
429 
430  tprintf("return : %d(0x%08X)\n", rt, rt);
431 
432 // close_device(dev);
433 
434  return 0;
435 }
436 
437 
438 static int dev_blockread(int argc, uchar *argv[]);
439 
440 /**
441  @brief デバイスよりブロック読み出しを行う
442 */
443 static const struct st_shell_command com_dev_blockread = {
444  .name = "blockread",
445  .command = dev_blockread,
446  .usage_str = "<device_name> <sector> <count>",
447  .manual_str = "Block read device"
448 };
449 
450 static int dev_blockread(int argc, uchar *argv[])
451 {
452  struct st_device *dev;
453  unsigned char buf[MAX_DEVREADCNT];
454  unsigned int sector = 0;
455  unsigned int count = 0;
456  int rt = 0;
457  int i;
458 
459  if(argc < 4) {
460  print_command_usage(&com_dev_blockread);
461  return 0;
462  }
463 
464  dev = open_device((char *)argv[1]);
465 
466  if(dev == 0) {
467  tprintf("Cannot open \"%s\".\n", argv[1]);
468  return 0;
469  }
470 
471  sector = hdstoi(argv[2]);
472  count = hdstoi(argv[3]);
473 
474  for(i=0; i<count; i++) {
475  rt = block_read_device(dev, buf, sector+i, 1);
476  if(rt != 1) {
477  break;
478  } else {
479  xadump(512*i, buf, 512); // [TODO] 1セクタは512Bytes固定
480  }
481  }
482 
483  tprintf("return : %d(0x%08X)\n", rt, rt);
484 
485 // close_device(dev);
486 
487  return 0;
488 }
489 
490 
491 static int dev_capacity(int argc, uchar *argv[]);
492 
493 /**
494  @brief デバイスの容量を取得する
495 */
496 static const struct st_shell_command com_dev_capacity = {
497  .name = "capacity",
498  .command = dev_capacity,
499  .usage_str = "<device_name>",
500  .manual_str = "Print device capacity"
501 };
502 
503 #include "device/sd_ioctl.h"
504 
505 static int dev_capacity(int argc, uchar *argv[])
506 {
507  struct st_device *dev;
508  int rt = 0;
509 
510  if(argc < 2) {
511  print_command_usage(&com_dev_capacity);
512  return 0;
513  }
514 
515  dev = open_device((char *)argv[1]);
516 
517  if(dev == 0) {
518  tprintf("Cannot open \"%s\".\n", argv[1]);
519  return 0;
520  }
521 
522  rt = ioctl_device(dev, IOCMD_SD_GET_SECTOR_COUNT, 0, 0);
523  if(rt == 0) {
524  tprintf("IOCMD_SD_GET_SECTOR_COUNT return %d\n", rt);
525  } else {
526  tprintf("Sector count : %d(0x%08X)\n", rt, rt);
527  }
528 
529  rt = ioctl_device(dev, IOCMD_SD_GET_SECTOR_SIZE, 0, 0);
530  if(rt == 0) {
531  tprintf("IOCMD_SD_GET_SECTOR_SIZE return %d\n", rt);
532  } else {
533  tprintf("Sector size : %d(0x%08X)\n", rt, rt);
534  }
535 
536  rt = ioctl_device(dev, IOCMD_SD_GET_BLOCK_SIZE, 0, 0);
537  if(rt == 0) {
538  tprintf("IOCMD_SD_GET_BLOCK_SIZE return %d\n", rt);
539  } else {
540  tprintf("Block size : %d(0x%08X)\n", rt, rt);
541  }
542 
543  //close_device(dev);
544 
545  return 0;
546 }
547 
548 
549 static int dev_ioctl(int argc, uchar *argv[]);
550 
551 /**
552  @brief デバイスの制御(ioctl)を行う
553 */
554 static const struct st_shell_command com_dev_ioctl = {
555  .name = "ioctl",
556  .command = dev_ioctl,
557  .usage_str = "<device_name> <command> [arg]",
558  .manual_str = "Ioctl device"
559 };
560 
561 static int dev_ioctl(int argc, uchar *argv[])
562 {
563  struct st_device *dev;
564  unsigned int cmd = 0;
565  unsigned int arg = 0;
566  int rt = 0;
567 
568  if(argc < 2) {
569  print_command_usage(&com_dev_ioctl);
570  return 0;
571  }
572 
573  dev = open_device((char *)argv[1]);
574 
575  if(dev == 0) {
576  tprintf("Cannot open \"%s\".\n", argv[1]);
577  return 0;
578  }
579 
580  if(argc > 2) {
581  cmd = hdstou(argv[2]);
582  }
583 
584  if(argc > 3) {
585  arg = hdstou(argv[3]);
586  }
587 
588  rt = ioctl_device(dev, cmd, arg, 0);
589 
590  tprintf("return : %d(0x%08X)\n", rt, rt);
591 
592  //close_device(dev);
593 
594  return 0;
595 }
596 
597 
598 static int dev_suspend(int argc, uchar *argv[]);
599 
600 /**
601  @brief デバイスをサスペンド状態にする(実験的なAPI)
602 */
603 static const struct st_shell_command com_dev_suspend = {
604  .name = "suspend",
605  .command = dev_suspend,
606  .usage_str = "[device_name]",
607  .manual_str = "Suspend device"
608 };
609 
610 static int dev_suspend(int argc, uchar *argv[])
611 {
612  struct st_device *dev;
613  int rt = 0;
614 
615  if(argc < 2) {
616  suspend();
617  return 0;
618  }
619 
620  dev = open_device((char *)argv[1]);
621 
622  if(dev == 0) {
623  tprintf("Cannot open \"%s\".\n", argv[1]);
624  return 0;
625  }
626 
627  rt = suspend_device(dev);
628 
629  tprintf("return : %d(0x%08X)\n", rt, rt);
630 
631 // close_device(dev);
632 
633  return 0;
634 }
635 
636 
637 static int dev_resume(int argc, uchar *argv[]);
638 
639 /**
640  @brief デバイスをレジューム状態にする(実験的なAPI)
641 */
642 static const struct st_shell_command com_dev_resume = {
643  .name = "resume",
644  .command = dev_resume,
645  .usage_str = "[device_name]",
646  .manual_str = "Resume device"
647 };
648 
649 static int dev_resume(int argc, uchar *argv[])
650 {
651  struct st_device *dev;
652  int rt = 0;
653 
654  if(argc < 2) {
655  resume();
656  return 0;
657  }
658 
659  dev = open_device((char *)argv[1]);
660 
661  if(dev == 0) {
662  tprintf("Cannot open \"%s\".\n", argv[1]);
663  return 0;
664  }
665 
666  rt = resume_device(dev);
667 
668  tprintf("return : %d(0x%08X)\n", rt, rt);
669 
670 // close_device(dev);
671 
672  return 0;
673 }
674 
675 
676 static int dev_close(int argc, uchar *argv[]);
677 
678 /**
679  @brief デバイスを閉じる
680 */
681 static const struct st_shell_command com_dev_close = {
682  .name = "close",
683  .command = dev_close,
684  .usage_str = "<device_name>",
685  .manual_str = "Close device"
686 };
687 
688 static int dev_close(int argc, uchar *argv[])
689 {
690  struct st_device *dev;
691  long rt = 0;
692 
693  if(argc < 2) {
694  print_command_usage(&com_dev_close);
695  return 0;
696  }
697 
698  dev = open_device((char *)argv[1]);
699 
700  rt = close_device(dev);
701 
702  tprintf("return : %ld(0x%08lX)\n", rt, rt);
703 
704  return 0;
705 }
706 
707 
708 static const struct st_shell_command * const com_device_list[] = {
709  &com_dev_list,
710  &com_dev_open,
711  &com_dev_putc,
712  &com_dev_getc,
713  &com_dev_write,
714  &com_dev_read,
715  &com_dev_dump,
716  &com_dev_ioctl,
717  &com_dev_seek,
719 // &com_dev_blockwrite, // @todo devコマンドにblockwrite追加
723  &com_dev_close,
724  0
725 };
726 
727 const struct st_shell_command com_dev = {
728  .name = "dev", ///< デバイスドライバ操作コマンド
729  .manual_str = "Device operation commands",
730  .sublist = com_device_list
731 }; ///< デバイスドライバ操作
unsigned char uchar
GadgetSeedの文字(列)は unsigned char 型となる
Definition: str.h:13
シェルコマンド構造体
Definition: shell.h:33
コマンドシェル
static const struct st_shell_command com_dev_dump
デバイスより任意のサイズのデータを読み出しダンプ表示する
Definition: com_device.c:293
#define IOCMD_SD_GET_SECTOR_COUNT
セクタ数を取得する
Definition: sd_ioctl.h:17
static const struct st_shell_command com_dev_resume
デバイスをレジューム状態にする(実験的なAPI)
Definition: com_device.c:642
#define IOCMD_SD_GET_BLOCK_SIZE
消去ブロックサイズを取得する
Definition: sd_ioctl.h:19
static const struct st_shell_command com_dev_putc
デバイスに1バイトデータを書き込む
Definition: com_device.c:92
struct st_device * open_device(char *name)
デバイスをオープンする
Definition: device.c:262
ラインエディタ
static const struct st_shell_command com_dev_blockread
デバイスよりブロック読み出しを行う
Definition: com_device.c:443
int cgetcnw(unsigned char *rd)
標準入力より1文字を取得する(待ち無し)
Definition: console.c:235
int write_device(struct st_device *dev, const void *buf, unsigned int count)
デバイスにデータを書き込む
Definition: device.c:451
文字列処理
int read_device(struct st_device *dev, void *buf, unsigned int count)
デバイスよりデータを読み出す
Definition: device.c:378
const char * device_name(int num)
デバイス名を取得する
Definition: device.c:132
static const struct st_shell_command com_dev_suspend
デバイスをサスペンド状態にする(実験的なAPI)
Definition: com_device.c:603
int seek_device(struct st_device *dev, int offset, int whence)
デバイスのアクセスポイントを設定する
Definition: device.c:545
static const struct st_shell_command com_dev_ioctl
デバイスの制御(ioctl)を行う
Definition: com_device.c:554
unsigned int hdstou(uchar *str)
10進数または16進数文字列 unsigned int 変換
Definition: str.c:720
int suspend(void)
全デバイスを休止状態にする
Definition: device.c:634
int hdstoi(uchar *str)
10進数または16進数文字列 int 変換
Definition: str.c:701
int resume_device(struct st_device *dev)
デバイスを活性化する
Definition: device.c:618
#define IOCMD_SD_GET_SECTOR_SIZE
1セクタサイズを取得する
Definition: sd_ioctl.h:18
static const struct st_shell_command com_dev_getc
デバイスより1バイトデータを読み出す
Definition: com_device.c:140
static const struct st_shell_command com_dev_write
デバイスに任意のサイズのデータを書き込む
Definition: com_device.c:182
const char * device_explan(int num)
デバイス説明を取得する
Definition: device.c:154
int getc_device(struct st_device *dev, unsigned char *data)
デバイスよりデータを1バイト読み出す
Definition: device.c:429
static const struct st_shell_command com_dev_list
登録されているデバイスリスト表示
Definition: com_device.c:51
int dstoi(uchar *str)
10進数文字列 int 変換
Definition: str.c:523
unsigned int strleng(const uchar *str)
文字列長
Definition: str.c:657
uchar name[12]
コマンド名文字列
Definition: shell.h:34
static const struct st_shell_command com_dev_read
デバイスより任意のサイズのデータを読み出す
Definition: com_device.c:239
int cputc(unsigned char td)
標準出力より1文字を出力する
Definition: console.c:163
int putc_device(struct st_device *dev, unsigned char data)
デバイスにデータを1バイト書き込む
Definition: device.c:502
int suspend_device(struct st_device *dev)
デバイスを休止状態にする
Definition: device.c:600
int device_num(void)
登録されているデバイス数を取得する
Definition: device.c:113
int tprintf(const char *fmt,...)
簡易printf
Definition: tprintf.c:85
static const struct st_shell_command com_dev_seek
デバイスのアクセス位置を設定する
Definition: com_device.c:394
ストレージデバイスドライバ ioctl 用マクロ定義
#define SEEK_SET
設定
Definition: device.h:21
static const struct st_shell_command com_dev_open
デバイスを開く
Definition: com_device.c:63
uchar * strncopy(uchar *dest, const uchar *src, unsigned int n)
文字列コピー
Definition: str.c:632
コンソールI/O
int resume(void)
全デバイスを活性化する
Definition: device.c:655
static const struct st_shell_command com_dev_close
デバイスを閉じる
Definition: com_device.c:681
int close_device(struct st_device *dev)
デバイスをクローズする
Definition: device.c:291
デバイスドライバ構造体
Definition: device.h:25
static const struct st_shell_command com_dev_capacity
デバイスの容量を取得する
Definition: com_device.c:496
int ioctl_device(struct st_device *dev, unsigned int com, unsigned int arg, void *param)
デバイスを制御する
Definition: device.c:525
int block_read_device(struct st_device *dev, void *buf, unsigned int sector, unsigned int blkcount)
デバイスよりブロックデータを読み出す
Definition: device.c:410
機能限定printf