// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2022-2023 ArtinChip Technology Co., Ltd. * Authors: Zequan.liang */ #include "artinchip/sample_base.h" #include #include #define SDCARD_DEV 0 #define USB_DEV 1 #define NO_FIND_BLOCK_DEV 0 #define FIND_BLOCK_DEV 1 #define FIND_SDCARD_DEV 2 #define FIND_USB_DEV 3 #define SDCARD_TEST_PATH "/mnt/sdcard" #define USB_TEST_PATH "/mnt/usb" int execute_command(const char *command) { FILE *fp = NULL; char buffer[256]; int err = 0; int ret; fp = popen(command, "r"); if (fp == NULL) { printf("Failed to open subprocess\n"); err = -1; goto CLOSE; } while (fgets(buffer, sizeof(buffer), fp) != NULL) { printf("%s", buffer); } CLOSE: ret = pclose(fp); switch (ret) { case 1: printf("command is empty\n"); return -1; case -1: printf("Faild to create child process\n"); return -1; case 0X7F00: printf("Command error unable to execute\n"); return -1; default: break; } return err; } int mount_block_dev(const char *command) { FILE *fp = NULL; char buffer[256]; int ret = 0; int err = 0; fp = popen(command, "r"); if (fp == NULL) { printf("Failed to open subprocess\n"); err = -1; goto CLOSE; } while (fgets(buffer, sizeof(buffer), fp) != NULL) { if (strstr(buffer, "No such file or directory")) { err = -1; break; } } if (err == -1) { printf("mount failure: command is = %s\n", command); } CLOSE: ret = pclose(fp); switch (ret) { case 1: printf("command is empty\n"); return -1; case -1: printf("Faild to create child process\n"); return -1; case 0X7F00: printf("Command error unable to execute\n"); return -1; default: break; } if (err == -1) return -1; return err; } int obtain_block_dev(char *dev, int type, int usb_num) { FILE *fp = NULL; char line[256] = {0}; char device[512] = {0}; int ret = 0; int back_status = -1; /* * ls /sys/class/block/ * mmcblk0 mmcblk0p1 sda sda1 sdb sdb1 */ fp = popen("ls /sys/class/block/", "r"); if (fp == NULL) { printf("Failed to open subprocess\n"); goto CLOSE; } while (fgets(line, sizeof(line), fp) != NULL) { strcat(device, line); } if (type == SDCARD_DEV) { char *mmc = strstr(device, "mmcblk0"); if (mmc) { char *partition = strstr(mmc + 7, "mmcblk0p1"); if (partition) { snprintf(dev, strlen("dev/mmcblk0p1") + 1, "dev/%s", partition); } else { snprintf(dev, strlen("dev/mmcblk0") + 1, "dev/%s", mmc); } back_status = 0; goto CLOSE; } } else if (type == USB_DEV) { char *usb_blk = NULL; char *usb_blk_num = NULL; if (usb_num == 0) { usb_blk = "sda"; usb_blk_num = "sda1"; } else if (usb_num == 1) { usb_blk = "sdb"; usb_blk_num = "sdb1"; } char *usb = strstr(device, usb_blk); if (usb) { char *partition = strstr(usb + 3, usb_blk_num); if (partition) { snprintf(dev, strlen("dev/sdx1") + 1, "dev/%s", partition); } else { snprintf(dev, strlen("dev/sdx") + 1, "dev/%s", usb); } back_status = 0; goto CLOSE; } } CLOSE: ret = pclose(fp); switch (ret) { case 1: printf("command is empty\n"); return -1; case -1: printf("Faild to create child process\n"); return -1; case 0X7F00: printf("Command error unable to execute\n"); return -1; default: break; } return back_status; } static void usage(char *app) { printf("Usage: %s [Options], built on %s %s\n", app, __DATE__, __TIME__); printf("\t-t, --type, select storage block device types, types can use usb or sdcard (default type is sdcard)\n"); printf("\t-c, --circle, loop test\n"); printf("\t-n, --blk_num, block num, (default 0)\n"); printf("\t-u, --usage\n\n"); printf("\texample: test_blkdev -t sdcard -c -n 0\n"); } int main(int argc, char **argv) { FILE *file = NULL; int ret = 0; int i = 0; int success_num = 0; char dev_block[50] = {0}; char command[256] = {0}; char filenames[3][50] = {0}; char contents[3][200] = { "This is the content of file0.\nIt contains multiple lines.\nLorem ipsum dolor sit amet, consectetur adipiscing elit.\n", "This is the content of file1.\nIt contains special characters like @#$%%^&*().\nSuspendisse ornare nibh id consequat lobortis.\n", "This is the content of file2.\nIt contains numbers: 12345.\nNullam aliquam massa vitae justo cursus auctor.\n" }; char content[100] = {0}; int type = SDCARD_DEV; int circle = 0; int usb_num = 0; const char sopts[] = "uct:n:"; static const struct option lopts[] = { {"usage", no_argument, NULL, 'u'}, {"circle", no_argument, NULL, 'c'}, {"type", required_argument, NULL, 't'}, {"num", required_argument, NULL, 'n'}, {NULL, 0, 0, 0}, }; while ((ret = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { switch (ret) { case 't': if (strncmp(optarg, "usb", strlen("usb")) == 0) { type = USB_DEV; break; } else if (strncmp(optarg, "sdcard", strlen("sdcard")) == 0) { type = SDCARD_DEV; break; } else { printf("Invalid parameter: %#x\n", ret); return 0; } break; case 'u': usage(argv[0]); return 0; case 'c': circle = 1; break; case 'n': usb_num = str2int(optarg); break; default: printf("Invalid parameter: %#x\n", ret); return 0; } } for (i = 0; i < 3; i++) { char str[50] = {0}; if (type == SDCARD_DEV) snprintf(str, sizeof(str), "%s/file%d.txt", SDCARD_TEST_PATH, i); else snprintf(str, sizeof(str), "%s/file%d.txt", USB_TEST_PATH, i); strncpy(filenames[i], str, strlen(str)); } memset(command, 0, sizeof(command)); strcat(command, "mkdir "); if (type == SDCARD_DEV) strcat(command, SDCARD_TEST_PATH); else strcat(command, USB_TEST_PATH); ret = execute_command(command); if (ret < 0) { return 0; } ret = obtain_block_dev(dev_block, type, usb_num); if (ret < 0) { printf("can't find block dev, dev_block = %s\n", dev_block); return 0; } printf("dev_block name is = %s\n", dev_block); /* example: mount -t vfat /dev/mmcblk1 /mnt/sdcard */ memset(command, 0, sizeof(command)); strcpy(command, "mount -t vfat "); strcat(command, dev_block); strcat(command, " "); if (type == SDCARD_DEV) strcat(command, SDCARD_TEST_PATH); else strcat(command, USB_TEST_PATH); ret = mount_block_dev(command); if (ret < 0) { return 0; } do { /* Create files */ for (i = 0; i < 3; i++) { file = fopen(filenames[i], "w"); if (file == NULL) { printf("Unable to create file: %s\n", filenames[i]); return 0; } fclose(file); } /* Write complex content to files */ for (i = 0; i < 3; i++) { file = fopen(filenames[i], "w"); if (file == NULL) { printf("Unable to open file: %s\n", filenames[i]); return 0; } fprintf(file, "%s", contents[i]); fclose(file); } /* Read and print content from files */ for (i = 0; i < 3; i++) { file = fopen(filenames[i], "r"); if (file == NULL) { printf("Unable to open file: %s\n", filenames[i]); return 0; } while (fgets(content, sizeof(content), file) != NULL) { if (strncmp(contents[i], content, strlen(content)) == 0) success_num++; } fclose(file); } /* Check file conditions */ for (i = 0; i < 3; i++) { file = fopen(filenames[i], "r"); if (file != NULL) { fseek(file, 0, SEEK_END); long size = ftell(file); if (size > 0) { success_num++; } else { printf("%s is empty.\n", filenames[i]); } fclose(file); } } /* Delete files */ for (i = 0; i < 3; i++) { if (remove(filenames[i]) == 0) { success_num++; } else { printf("Unable to delete the file: %s\n", filenames[i]); } } long long failed_time = 0; if (success_num == 9) { printf("storage block dev test success\n"); } else { failed_time++; printf("storage block dev test failed, times = %lld\n", failed_time); } if (circle) { usleep(100000); success_num = 0; } } while (circle); memset(command, 0, sizeof(command)); strcat(command, "umount "); if (type == SDCARD_DEV) strcat(command, SDCARD_TEST_PATH); else strcat(command, USB_TEST_PATH); ret = execute_command(command); if (ret < 0) { return 0; } memset(command, 0, sizeof(command)); strcat(command, "rmdir "); if (type == SDCARD_DEV) strcat(command, SDCARD_TEST_PATH); else strcat(command, USB_TEST_PATH); ret = execute_command(command); if (ret < 0) { return 0; } return 0; }