File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <fcntl.h>
0027 #include <stdio.h>
0028 #include <stdlib.h>
0029
0030 #include <errno.h>
0031 #include <rtems/shell.h>
0032
0033 #include <dev/flash/flashdev.h>
0034
0035 static int flashdev_shell_read(char *dev_path, int argc, char *argv[]);
0036 static int flashdev_shell_write(char *dev_path, int argc, char *argv[]);
0037 static int flashdev_shell_erase(char *dev_path, int argc, char *argv[]);
0038 static int flashdev_shell_type(char *dev_path);
0039 static int flashdev_shell_jedecid(char *dev_path);
0040 static int flashdev_shell_page_off(char *dev_path, int argc, char *argv[]);
0041 static int flashdev_shell_page_idx(char *dev_path, int argc, char *argv[]);
0042 static int flashdev_shell_pg_count(char *dev_path);
0043 static int flashdev_shell_wb_size(char *dev_path);
0044 static int flashdev_shell_sector_off(char *dev_path, int argc, char *argv[]);
0045 static int flashdev_shell_sector_count(char *dev_path);
0046
0047 static int flashdev_shell_ioctl_value(
0048 char *dev_path,
0049 int ioctl_call,
0050 void *ret
0051 );
0052
0053 static int flashdev_shell_page(
0054 char *dev_path,
0055 int argc,
0056 char *argv[],
0057 int ioctl_call
0058 );
0059
0060 static const char rtems_flashdev_shell_usage [] =
0061 "simple flash read / write / erase\n"
0062 "\n"
0063 "flashdev <FLASH_DEV_PATH> [OPTION]\n"
0064 " -r <address> <bytes> Read at address for bytes\n"
0065 " -w <address> <file> Write file to address\n"
0066 " -e <address> <bytes> Erase at address for bytes\n"
0067 " -t Print the flash type\n"
0068 " -d Print the JEDEC ID of flash device\n"
0069 " -o <address> Print the page information of page at address\n"
0070 " -i <index> Print the page information of page at index\n"
0071 " -p Print the number of pages\n"
0072 " -b Print the write block size\n"
0073 " -s <address> Print the sector information of erase sector"
0074 " at address\n"
0075 " -c Print the number of erase sectors\n"
0076 " -h Print this help\n";
0077
0078
0079 static int rtems_flashdev_shell_main( int argc, char *argv[] ) {
0080
0081 char *dev_path = NULL;
0082 int i;
0083
0084 for (i = 1; i < argc; ++i) {
0085 if (argv[i][0] == '-') {
0086
0087
0088
0089
0090 if (dev_path == NULL) {
0091 printf("Please input FLASH_DEV_PATH before instruction\n");
0092 return 1;
0093 }
0094
0095 switch (argv[i][1]) {
0096 case ('r'):
0097
0098 return flashdev_shell_read(dev_path, argc, &argv[i]);
0099 case ('w'):
0100
0101 return flashdev_shell_write(dev_path, argc, &argv[i]);
0102 case ('e'):
0103
0104 return flashdev_shell_erase(dev_path, argc, &argv[i]);
0105 case ('t'):
0106
0107 return flashdev_shell_type(dev_path);
0108 case ('d'):
0109
0110 return flashdev_shell_jedecid(dev_path);
0111 case ('o'):
0112
0113 return flashdev_shell_page_off(dev_path, argc, &argv[i]);
0114 case ('i'):
0115
0116 return flashdev_shell_page_idx(dev_path, argc, &argv[i]);
0117 case ('p'):
0118
0119 return flashdev_shell_pg_count(dev_path);
0120 case ('b'):
0121
0122 return flashdev_shell_wb_size(dev_path);
0123 case ('s'):
0124
0125 return flashdev_shell_sector_off(dev_path, argc, &argv[i]);
0126 case ('c'):
0127
0128 return flashdev_shell_sector_count(dev_path);
0129 case ('h'):
0130 default:
0131
0132 printf(rtems_flashdev_shell_usage);
0133 break;
0134 }
0135 } else if (dev_path == NULL) {
0136 dev_path = argv[i];
0137 } else {
0138 printf("Invalid argument: %s\n", argv[i]);
0139 return 1;
0140 }
0141 }
0142
0143 if (argc == 1) {
0144 printf(rtems_flashdev_shell_usage);
0145 }
0146
0147 return 0;
0148 }
0149
0150 int flashdev_shell_read(
0151 char *dev_path,
0152 int argc,
0153 char *argv[]
0154 )
0155 {
0156 uint32_t address;
0157 uint32_t bytes;
0158 int fd;
0159 int status;
0160 void *buffer;
0161
0162
0163 if (argc < 5) {
0164 printf("Missing argument\n");
0165 return -1;
0166 }
0167
0168
0169 errno = 0;
0170 address = (uint32_t) strtoul(argv[1], NULL, 0);
0171 if (errno != 0) {
0172 printf("Could not read address\n");
0173 }
0174 errno = 0;
0175 bytes = (uint32_t) strtoul(argv[2], NULL, 0);
0176 if (errno != 0) {
0177 printf("Could not read address\n");
0178 }
0179
0180
0181 fd = open(dev_path, O_RDONLY);
0182 if (fd == -1) {
0183 printf("Couldn't open %s\n", dev_path);
0184 return -1;
0185 }
0186
0187
0188 status = lseek(fd, address, SEEK_SET);
0189 if (status == -1) {
0190 printf("Reading failed\n");
0191 close(fd);
0192 return -1;
0193 }
0194
0195
0196 buffer = calloc((bytes + bytes%4), 1);
0197 if (buffer == NULL) {
0198 printf("Failed to allocate read buffer\n");
0199 close(fd);
0200 return -1;
0201 }
0202
0203
0204 status = read(fd, buffer, bytes);
0205 if (status == -1) {
0206 printf("Reading failed\n");
0207 free(buffer);
0208 close(fd);
0209 return -1;
0210 }
0211
0212
0213 printf("Reading %s at 0x%08x for 0x%x bytes\n", dev_path, address, bytes);
0214 for (int i = 0; i < (bytes/4); i++) {
0215 printf("%08x ", ((uint32_t*)buffer)[i]);
0216 if ((i+1)%4 == 0) {
0217 printf("\n");
0218 }
0219 }
0220 printf("\n");
0221
0222
0223 free(buffer);
0224 close(fd);
0225 return 0;
0226 }
0227
0228 int flashdev_shell_write(
0229 char *dev_path,
0230 int argc,
0231 char *argv[]
0232 )
0233 {
0234 uint32_t address;
0235 int flash;
0236 int file;
0237 int status;
0238 int read_len;
0239 off_t length;
0240 void *buffer;
0241 uint32_t offset;
0242 char *file_path;
0243
0244
0245 if (argc < 5) {
0246 printf("Missing argument\n");
0247 return -1;
0248 }
0249
0250
0251 errno = 0;
0252 address = (uint32_t) strtoul(argv[1], NULL, 0);
0253 if (errno != 0) {
0254 printf("Could not read address\n");
0255 }
0256 errno = 0;
0257 file_path = argv[2];
0258
0259
0260 flash = open(dev_path, O_WRONLY);
0261 if (flash == -1) {
0262 printf("Couldn't open %s\n", dev_path);
0263 return -1;
0264 }
0265 status = lseek(flash, address, SEEK_SET);
0266 if (status == -1) {
0267 printf("Reading failed\n");
0268 close(flash);
0269 return -1;
0270 }
0271
0272
0273 file = open(file_path, O_RDONLY);
0274 if (file == -1) {
0275 printf("Couldn't open %s\n", file_path);
0276 close(flash);
0277 return -1;
0278 }
0279
0280 length = lseek(file, 0, SEEK_END);
0281 if (length == -1) {
0282 close(flash);
0283 close(file);
0284 printf("Couldn't find length of file\n");
0285 return -1;
0286 }
0287
0288 if (lseek(file, 0, SEEK_SET) == -1) {
0289 close(flash);
0290 close(file);
0291 printf("Couldn't find length of file\n");
0292 return -1;
0293 }
0294
0295 printf(
0296 "Writing %s to %s at 0x%08x for 0x%jx bytes\n",
0297 file_path,
0298 dev_path,
0299 address,
0300 length
0301 );
0302
0303
0304 buffer = calloc(1, 0x1000);
0305
0306
0307 offset = 0;
0308 while (offset != length) {
0309
0310 read_len = length - offset;
0311 if (read_len > 0x1000) {
0312 read_len = 0x1000;
0313 }
0314
0315 status = read(file, buffer, read_len);
0316 if (status == -1) {
0317 free(buffer);
0318 close(flash);
0319 close(file);
0320 printf("Can't read %s\n", file_path);
0321 return -1;
0322 }
0323
0324 status = write(flash, buffer, read_len);
0325 if (status == -1) {
0326 free(buffer);
0327 close(flash);
0328 close(file);
0329 printf("Can't write %s\n", dev_path);
0330 return -1;
0331 }
0332
0333 offset = offset + read_len;
0334 }
0335
0336
0337 close(flash);
0338 close(file);
0339 free(buffer);
0340 return 0;
0341 }
0342
0343 int flashdev_shell_erase(
0344 char *dev_path,
0345 int argc,
0346 char *argv[]
0347 )
0348 {
0349 uint32_t address;
0350 uint32_t bytes;
0351 int fd;
0352 int status;
0353 rtems_flashdev_region args;
0354
0355
0356 if (argc < 5) {
0357 printf("Missing argument\n");
0358 return -1;
0359 }
0360
0361
0362 errno = 0;
0363 address = (uint32_t) strtoul(argv[1], NULL, 0);
0364 if (errno != 0) {
0365 printf("Could not read address\n");
0366 }
0367 errno = 0;
0368 bytes = (uint32_t) strtoul(argv[2], NULL, 0);
0369 if (errno != 0) {
0370 printf("Could not read address\n");
0371 }
0372
0373
0374 fd = open(dev_path, O_RDWR);
0375 if (fd == -1) {
0376 printf("Couldn't open %s\n", dev_path);
0377 return -1;
0378 }
0379
0380 printf("Erasing at 0x%08x for 0x%x bytes\n", address, bytes);
0381
0382
0383 args.offset = address;
0384 args.size = bytes;
0385
0386 status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_ERASE, &args);
0387 if (status == -1) {
0388 printf("Erase failed\n");
0389 close(fd);
0390 return -1;
0391 }
0392
0393
0394 close(fd);
0395
0396 return 0;
0397 }
0398
0399 int flashdev_shell_type( char *dev_path )
0400 {
0401 int type;
0402 int status;
0403
0404
0405 status = flashdev_shell_ioctl_value(
0406 dev_path,
0407 RTEMS_FLASHDEV_IOCTL_TYPE,
0408 &type
0409 );
0410
0411 if (status) {
0412 printf("Failed to get flash type\n");
0413 return status;
0414 }
0415
0416
0417 switch(type) {
0418 case RTEMS_FLASHDEV_NOR:
0419 printf("NOR flash\n");
0420 break;
0421 case RTEMS_FLASHDEV_NAND:
0422 printf("NAND flash\n");
0423 break;
0424 default:
0425 printf("Unknown type\n");
0426 }
0427
0428 return 0;
0429 }
0430
0431 int flashdev_shell_jedecid( char *dev_path ) {
0432 uint32_t ret;
0433 int status;
0434
0435
0436 status = flashdev_shell_ioctl_value(
0437 dev_path,
0438 RTEMS_FLASHDEV_IOCTL_JEDEC_ID,
0439 &ret
0440 );
0441
0442
0443 if (status) {
0444 printf("Failed to get JEDEC Id\n");
0445 return status;
0446 } else {
0447 printf("JEDEC Id: 0x%x\n", ret);
0448 }
0449 return 0;
0450 }
0451
0452 static int flashdev_shell_page_off(
0453 char *dev_path,
0454 int argc,
0455 char *argv[]
0456 )
0457 {
0458 return flashdev_shell_page(
0459 dev_path,
0460 argc,
0461 argv,
0462 RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_OFFSET
0463 );
0464 }
0465
0466 static int flashdev_shell_page_idx(
0467 char *dev_path,
0468 int argc,
0469 char *argv[]
0470 )
0471 {
0472 return flashdev_shell_page(
0473 dev_path,
0474 argc,
0475 argv,
0476 RTEMS_FLASHDEV_IOCTL_PAGEINFO_BY_INDEX
0477 );
0478 }
0479
0480 static int flashdev_shell_pg_count( char *dev_path )
0481 {
0482 uint32_t ret;
0483 int status;
0484
0485
0486 status = flashdev_shell_ioctl_value(
0487 dev_path,
0488 RTEMS_FLASHDEV_IOCTL_PAGE_COUNT,
0489 &ret
0490 );
0491
0492
0493 if (status) {
0494 printf("Failed to get page count\n");
0495 return status;
0496 } else {
0497 printf("Page count: 0x%x\n", ret);
0498 }
0499 return 0;
0500 }
0501
0502 static int flashdev_shell_wb_size( char *dev_path )
0503 {
0504 size_t ret;
0505 int status;
0506
0507
0508 status = flashdev_shell_ioctl_value(
0509 dev_path,
0510 RTEMS_FLASHDEV_IOCTL_WRITE_BLOCK_SIZE,
0511 &ret
0512 );
0513
0514
0515 if (status) {
0516 printf("Failed to get write block size\n");
0517 return status;
0518 } else {
0519 printf("Write block size: 0x%zx\n", ret);
0520 }
0521 return 0;
0522 }
0523
0524 static int flashdev_shell_sector_off(
0525 char *dev_path,
0526 int argc,
0527 char *argv[]
0528 )
0529 {
0530 rtems_flashdev_ioctl_sector_info sec_info;
0531 int fd;
0532 int status;
0533
0534
0535 if (argc < 4) {
0536 printf("Missing argument\n");
0537 return -1;
0538 }
0539
0540
0541 errno = 0;
0542 sec_info.location = (off_t) strtoul(argv[1], NULL, 0);
0543 if (errno != 0) {
0544 printf("Could not read address\n");
0545 }
0546
0547
0548 fd = open(dev_path, O_RDWR);
0549 if (fd == -1) {
0550 printf("Couldn't open %s\n", dev_path);
0551 return -1;
0552 }
0553
0554 status = ioctl(fd, RTEMS_FLASHDEV_IOCTL_SECTORINFO_BY_OFFSET, &sec_info);
0555 if (status == -1) {
0556 printf("Failed to get sector info\n");
0557 close(fd);
0558 return -1;
0559 }
0560
0561 printf(
0562 "Sector offset: 0x%jx\nPage length: 0x%zx\n",
0563 sec_info.sector_info.offset,
0564 sec_info.sector_info.size
0565 );
0566
0567
0568 close(fd);
0569 return 0;
0570 }
0571
0572 static int flashdev_shell_sector_count( char *dev_path )
0573 {
0574 uint32_t ret;
0575 int status;
0576
0577
0578 status = flashdev_shell_ioctl_value(
0579 dev_path,
0580 RTEMS_FLASHDEV_IOCTL_SECTOR_COUNT,
0581 &ret
0582 );
0583
0584
0585 if (status) {
0586 printf("Failed to get sector count\n");
0587 return status;
0588 } else {
0589 printf("Sector count: 0x%x\n", ret);
0590 }
0591 return 0;
0592 }
0593
0594 static int flashdev_shell_ioctl_value(
0595 char *dev_path,
0596 int ioctl_call,
0597 void *ret
0598 )
0599 {
0600 int fd;
0601 int status;
0602
0603 fd = open(dev_path, O_RDONLY);
0604 if (fd == -1) {
0605 printf("Couldn't open %s\n", dev_path);
0606 return -1;
0607 }
0608
0609 status = ioctl(fd, ioctl_call, ret);
0610 if (status == -1) {
0611 close(fd);
0612 return -1;
0613 }
0614
0615 close(fd);
0616 return 0;
0617 }
0618
0619 static int flashdev_shell_page(
0620 char *dev_path,
0621 int argc,
0622 char *argv[],
0623 int ioctl_call
0624 )
0625 {
0626 rtems_flashdev_ioctl_page_info pg_info;
0627 int fd;
0628 int status;
0629
0630
0631 if (argc < 4) {
0632 printf("Missing argument\n");
0633 return -1;
0634 }
0635
0636
0637 errno = 0;
0638 pg_info.location = (off_t) strtoul(argv[1], NULL, 0);
0639 if (errno != 0) {
0640 printf("Could not read address\n");
0641 }
0642
0643
0644 fd = open(dev_path, O_RDWR);
0645 if (fd == -1) {
0646 printf("Couldn't open %s\n", dev_path);
0647 return -1;
0648 }
0649
0650 status = ioctl(fd, ioctl_call, &pg_info);
0651 if (status == -1) {
0652 printf("Failed to get page info\n");
0653 close(fd);
0654 return -1;
0655 }
0656
0657 printf(
0658 "Page offset: 0x%jx\nPage length: 0x%zx\n",
0659 pg_info.page_info.offset,
0660 pg_info.page_info.size
0661 );
0662
0663
0664 close(fd);
0665 return 0;
0666 }
0667
0668 rtems_shell_cmd_t rtems_shell_FLASHDEV_Command = {
0669 .name = "flashdev",
0670 .usage = rtems_flashdev_shell_usage,
0671 .topic = "misc",
0672 .command = rtems_flashdev_shell_main,
0673 };