cmd_sd.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /*
  2. * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the
  12. * distribution.
  13. * 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
  14. * its contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. */
  29. #include <string.h>
  30. //#include "console.h"
  31. #include "sdmmc/sys/sys_debug.h"
  32. #include "cmd/cmd_util.h"
  33. #include "cmd/cmd_sd.h"
  34. #include "sdmmc/hal/hal_def.h"
  35. #include "sdmmc/hal_sdhost.h"
  36. #include "sdmmc/sdmmc.h"
  37. //#include "FreeRTOS_CLI.h"
  38. static struct mmc_card *card;
  39. extern int32_t mmc_test(uint32_t host_id, uint32_t cd_mode, uint32_t sdc_degmask, uint32_t card_dbgmask);
  40. extern int32_t mmc_test_init(uint32_t host_id, SDC_InitTypeDef *sdc_param, uint32_t scan);
  41. extern int32_t mmc_test_exit(uint16_t sd_id, uint16_t host_id);
  42. extern struct mmc_card *mmc_scan_init(uint16_t sd_id, uint16_t sdc_id, SDCard_InitTypeDef *card_param);
  43. /* drv sd init [<card_id> <debug_mask>]
  44. * eg:
  45. * 1. drv sd init
  46. * 2. drv sd init 0 0x7f
  47. */
  48. static enum cmd_status cmd_sd_init_exec(char *cmd)
  49. {
  50. uint32_t cnt;
  51. uint32_t card_id, debug_mask;
  52. SDC_InitTypeDef sdc_param = { 0 };
  53. cnt = cmd_sscanf(cmd, "%u 0x%x", HAL_PR_SZ_P(&card_id), HAL_PR_SZ_P(&debug_mask));
  54. if (cnt != 2) {
  55. mmc_test_init(0, NULL, 0);
  56. } else {
  57. sdc_param.cd_mode = CARD_ALWAYS_PRESENT;
  58. sdc_param.debug_mask = debug_mask;
  59. mmc_test_init(card_id, &sdc_param, 0);
  60. }
  61. return CMD_STATUS_OK;
  62. }
  63. /* drv sd scan [<card_id> <host_id> <card_type> <debug_mask>]
  64. * eg:
  65. * 1. drv sd scan
  66. * 2. drv sd scan 0 0 2 0x7f
  67. */
  68. static enum cmd_status cmd_sd_scan_exec(char *cmd)
  69. {
  70. uint32_t cnt;
  71. uint32_t card_id, host_id, type, debug_mask;
  72. SDCard_InitTypeDef card_param = { 0 };
  73. cnt = cmd_sscanf(cmd, "%u %u %u 0x%x", HAL_PR_SZ_P(&card_id), HAL_PR_SZ_P(&host_id), HAL_PR_SZ_P(&type), HAL_PR_SZ_P(&debug_mask));
  74. if (cnt != 4) {
  75. card = mmc_scan_init(0, 0, NULL);
  76. } else {
  77. card_param.debug_mask = debug_mask;
  78. card_param.type = type;
  79. card = mmc_scan_init(card_id, host_id, &card_param);
  80. }
  81. if (!card) {
  82. CMD_ERR("scan card failed!\n");
  83. return CMD_STATUS_OK;;
  84. }
  85. return CMD_STATUS_OK;
  86. }
  87. /*
  88. * drv sd read s=<Start_Sector> n=<sector_num>
  89. */
  90. static enum cmd_status cmd_sd_read_exec(char *cmd)
  91. {
  92. int32_t err;
  93. uint32_t cnt;
  94. uint32_t start_sector, r_secnum;
  95. char *buf;
  96. cnt = cmd_sscanf(cmd, "s=%u n=%u", HAL_PR_SZ_P(&start_sector), HAL_PR_SZ_P(&r_secnum));
  97. if (cnt != 2) {
  98. CMD_ERR("invalid argument %s\n", cmd);
  99. return CMD_STATUS_FAIL;
  100. }
  101. buf = cmd_malloc(r_secnum*512);
  102. if (!buf)
  103. return CMD_STATUS_OK;;
  104. err = mmc_block_read(card, (uint8_t *)buf, start_sector, r_secnum);
  105. if (err) {
  106. CMD_ERR("mmc mult blocks read err!\n");
  107. return CMD_STATUS_FAIL;
  108. }
  109. CMD_DBG("read from %d sector, %d sectors\n", (unsigned int)start_sector, (unsigned int)r_secnum);
  110. print_hex_dump_bytes(buf, r_secnum*512);
  111. return CMD_STATUS_OK;
  112. }
  113. /*
  114. * eg:
  115. * 1. drv sd test
  116. * 2. drv sd test 0 3 0x3c 0x3c
  117. * 3. drv sd test 0 2 0x3c 0x3c
  118. */
  119. //static enum cmd_status cmd_sd_test_exec(char *cmd)
  120. enum cmd_status cmd_sd_test_exec(char *cmd)
  121. {
  122. uint32_t cnt = 0;
  123. uint32_t host_id = 0, cd_mode = 0, sdc_degmask = 0, card_dbgmask = 0;
  124. // cnt = cmd_sscanf(cmd, "%d %d 0x%x 0x%x", &host_id, &cd_mode, &sdc_degmask, &card_dbgmask);
  125. if (cnt != 4) {
  126. CMD_DBG("use defaule argument %s\n", cmd);
  127. host_id = 0;
  128. cd_mode = CARD_ALWAYS_PRESENT;
  129. /*
  130. sdc_degmask = (ROM_DUMP_MASK | ROM_DBG_MASK | ROM_INF_MASK | \
  131. ROM_WRN_MASK | ROM_ERR_MASK | ROM_ANY_MASK);
  132. card_dbgmask = (ROM_DUMP_MASK | ROM_DBG_MASK | ROM_INF_MASK | \
  133. ROM_WRN_MASK | ROM_ERR_MASK | ROM_ANY_MASK);
  134. */
  135. sdc_degmask = (ROM_INF_MASK | \
  136. ROM_WRN_MASK | ROM_ERR_MASK | ROM_ANY_MASK);
  137. card_dbgmask = ( ROM_INF_MASK | \
  138. ROM_WRN_MASK | ROM_ERR_MASK | ROM_ANY_MASK);
  139. }
  140. mmc_test(host_id, cd_mode, sdc_degmask, card_dbgmask);
  141. /*
  142. {
  143. sdio_claim_irq(NULL,NULL);
  144. sdio_release_irq(NULL);
  145. sdio_readw(NULL,NULL,NULL);
  146. sdio_readl(NULL,NULL,NULL);
  147. sdio_writel(NULL,NULL,NULL,NULL);
  148. sdio_writew(NULL,NULL,NULL,NULL);
  149. }
  150. */
  151. return CMD_STATUS_OK;
  152. }
  153. /*
  154. * drv sd deinit [<card_id> <host_id>]
  155. * eg.
  156. * 1. sd deinit
  157. * 2. sd deinit 0 0
  158. */
  159. static enum cmd_status cmd_sd_deinit_exec(char *cmd)
  160. {
  161. uint32_t cnt;
  162. uint32_t card_id, host_id;
  163. cnt = cmd_sscanf(cmd, "%u %u", HAL_PR_SZ_P(&card_id), HAL_PR_SZ_P(&host_id));
  164. if (cnt != 2) {
  165. card_id = 0;
  166. host_id = 0;
  167. }
  168. mmc_test_exit(card_id, host_id);
  169. return CMD_STATUS_OK;
  170. }
  171. #define CMD_ARG_LEN 64
  172. struct sd_test_param {
  173. uint8_t task_idx;
  174. uint8_t random;
  175. uint8_t task_num;
  176. uint8_t card_dma_use;
  177. uint16_t time_sec;
  178. uint16_t host_debug_mask;
  179. uint16_t card_debug_mask;
  180. uint32_t start_sector;
  181. uint32_t sector_num;
  182. };
  183. static void cmd_sd_bench_task(void *arg)
  184. {
  185. int32_t err;
  186. char *cmd = (char *)arg;
  187. uint32_t start_sector;
  188. uint32_t cnt;
  189. uint32_t throuth_mb, throuth_kb;
  190. OS_Time_t tick_use;
  191. uint32_t bench_sector;
  192. cnt = cmd_sscanf(cmd, "s=%u", HAL_PR_SZ_P(&start_sector));
  193. if (cnt != 1) {
  194. CMD_ERR("invalid argument %s\n", cmd);
  195. goto out;
  196. }
  197. mmc_test_init(0, NULL, 1);
  198. card = mmc_card_open(0);
  199. if (!card) {
  200. CMD_ERR("card open failed!\n");
  201. goto out;
  202. }
  203. bench_sector = start_sector - 1;
  204. for (int i = 0; i < sizeof(unsigned int)*8 - 10; i++) {
  205. unsigned int bench_size = 512 * (1 << i);
  206. uint8_t *buf = cmd_malloc(bench_size);
  207. if (!buf) {
  208. CMD_DBG("%s test end for malloc buff failed!\n", __func__);
  209. goto out;
  210. }
  211. for (int j = 0; j < bench_size/4; j++)
  212. ((unsigned int *)buf)[j] = j;
  213. bench_sector += bench_size/512;
  214. tick_use = OS_GetTicks();
  215. err = mmc_block_write(card, buf, bench_sector, bench_size/512);
  216. tick_use = OS_GetTicks() - tick_use;
  217. if (!tick_use)
  218. tick_use = 1;
  219. if (err) {
  220. CMD_ERR("mmc mult blocks write err!\n");
  221. goto next;
  222. } else {
  223. throuth_kb = bench_size*1000/1024/(uint32_t)OS_TicksToMSecs(tick_use);
  224. throuth_mb = throuth_kb/1000;
  225. CMD_DBG("%s mult blocks write ok, ", __func__);
  226. if (bench_size <= 512)
  227. CMD_LOG(CMD_DBG_ON, "0.5");
  228. else
  229. CMD_LOG(CMD_DBG_ON, "%3d", (unsigned int)bench_size/1024);
  230. CMD_LOG(CMD_DBG_ON, " KB use:%3d ms, throughput:%d.%d MB/S\n",
  231. (unsigned int)OS_TicksToMSecs(tick_use),
  232. (unsigned int)throuth_mb,(unsigned int)(throuth_kb - throuth_mb));
  233. }
  234. for (int j = 0; j < bench_size/4; j++)
  235. ((unsigned int *)buf)[j] = 0;
  236. tick_use = OS_GetTicks();
  237. err = mmc_block_read(card, buf, bench_sector, bench_size/512);
  238. tick_use = OS_GetTicks() - tick_use;
  239. if (!tick_use)
  240. tick_use = 1;
  241. if (err) {
  242. CMD_ERR("mmc mult blocks read err!\n");
  243. goto next;
  244. } else {
  245. throuth_kb = bench_size*1000/1024/(uint32_t)OS_TicksToMSecs(tick_use);
  246. throuth_mb = throuth_kb/1000;
  247. CMD_DBG("%s mult blocks read ok, ", __func__);
  248. if (bench_size <= 512)
  249. CMD_LOG(CMD_DBG_ON, "0.5");
  250. else
  251. CMD_LOG(CMD_DBG_ON, "%3d", bench_size/1024);
  252. CMD_LOG(CMD_DBG_ON, " KB use:%3d ms, throughput:%d.%d MB/S\n",
  253. (unsigned int)OS_TicksToMSecs(tick_use),
  254. (unsigned int)throuth_mb, (unsigned int)(throuth_kb - throuth_mb));
  255. }
  256. err = 0;
  257. for (int j = 0; j < bench_size/4; j++) {
  258. if (((unsigned int *)buf)[j] != j) {
  259. err = -1;
  260. break;
  261. }
  262. }
  263. if (err) {
  264. CMD_ERR("mmc %d blocks write data err!\n", (unsigned int)bench_size/512);
  265. goto next;
  266. }
  267. next:
  268. cmd_free(buf);
  269. if (err)
  270. break;
  271. }
  272. mmc_card_close(0);
  273. out:
  274. CMD_DBG("%s test end\n", __func__);
  275. mmc_test_exit(card->id, 0);
  276. cmd_free(arg);
  277. OS_ThreadDelete(NULL);
  278. }
  279. #define PRESS_FILE_SIZE (20 * 1024 * 1024) /* 20M */
  280. #define PRESS_READ_SIZE 2048
  281. #define PRESS_WRITE_SIZE 8192
  282. static OS_Semaphore_t sem_wait;
  283. static void cmd_sd_press_read_task(void *arg)
  284. {
  285. int32_t err;
  286. struct sd_test_param *param = (struct sd_test_param *)arg;
  287. OS_Time_t tick_now = 0, tick_print = 0;
  288. OS_Time_t tick_end = OS_GetTicks() + OS_MSecsToTicks(param->time_sec * 1000);
  289. uint32_t random_sleep = param->random;
  290. char *buf;
  291. uint32_t start_sector = param->start_sector;
  292. card = mmc_card_open(0);
  293. if (!card) {
  294. CMD_ERR("card open failed!\n");
  295. goto fail;
  296. }
  297. if (param->task_idx == 0) {
  298. buf = cmd_malloc(4096);
  299. for (int i = 0; i < 512/4; i++) {
  300. ((unsigned int *)buf)[i] = i;
  301. }
  302. memcpy(buf+512, buf, 512);
  303. memcpy(buf+1024, buf, 1024);
  304. memcpy(buf+2048, buf, 2048);
  305. CMD_DBG("%s do nothing until sd card prepare ok!\n", __func__);
  306. for (int i = 0; i < (PRESS_FILE_SIZE+4095)/4096; i++) { /* 10M */
  307. int32_t err;
  308. err = mmc_block_write(card, (uint8_t *)buf, start_sector + (i*(4096/512)), 4096/512);
  309. if (err)
  310. goto out;
  311. }
  312. CMD_DBG("%s sd card prepared ok!\n", __func__);
  313. for (int j = 0; j < param->task_num - 1; j++)
  314. OS_SemaphoreRelease(&sem_wait);
  315. cmd_free(buf);
  316. } else {
  317. OS_SemaphoreWait(&sem_wait, OS_WAIT_FOREVER);
  318. }
  319. buf = cmd_malloc(param->sector_num*512);
  320. if (!buf)
  321. goto exit;
  322. if (!random_sleep)
  323. random_sleep = 2;
  324. OS_MSleep(random_sleep);
  325. CMD_DBG("%s id:%d random:%d start_sector:%d\n", __func__, (unsigned int)param->task_idx,
  326. (unsigned int)random_sleep, (unsigned int)start_sector);
  327. while (tick_now < tick_end) {
  328. int j;
  329. err = mmc_block_read(card, (uint8_t *)buf, start_sector, param->sector_num);
  330. if (err) {
  331. CMD_ERR("mmc mult blocks read err!\n");
  332. goto out;
  333. }
  334. err = 0;
  335. for (j = 0; j < param->sector_num*(512/4); j++) {
  336. if (((unsigned int *)buf)[j] != (j & 0x07f)) {
  337. err = -1;
  338. CMD_ERR("%x %x\n", j, ((unsigned int *)buf)[j]);
  339. break;
  340. }
  341. }
  342. if (err) {
  343. CMD_ERR("mmc %d blocks read data err! at sector:%d count:%d\n",
  344. (unsigned int)param->sector_num, (unsigned int)start_sector, j);
  345. goto out;
  346. } else
  347. CMD_DBG("%s mmc blocks read data ok! at sector:%u\n",
  348. __func__, HAL_PR_SZ(start_sector));
  349. start_sector += param->sector_num;
  350. if (start_sector >= param->start_sector + PRESS_FILE_SIZE/512) {
  351. start_sector = param->start_sector;
  352. }
  353. OS_MSleep(random_sleep);
  354. tick_now = OS_GetTicks();
  355. if (tick_now >= tick_print + 5000) {
  356. CMD_DBG("%s id:%d testing... at sector:%d\n", __func__,
  357. (unsigned int)param->task_idx, (unsigned int)start_sector);
  358. tick_print = tick_now;
  359. }
  360. }
  361. out:
  362. CMD_DBG("%s id:%d test end\n", __func__, (unsigned int)param->task_idx);
  363. cmd_free(buf);
  364. exit:
  365. mmc_card_close(0);
  366. fail:
  367. cmd_free(param);
  368. if (param->task_idx == 0)
  369. OS_SemaphoreDelete(&sem_wait);
  370. OS_ThreadDelete(NULL);
  371. }
  372. static void cmd_sd_press_write_task(void *arg)
  373. {
  374. int32_t err;
  375. struct sd_test_param *param = (struct sd_test_param *)arg;
  376. OS_Time_t tick_now = 0, tick_print = 0;
  377. OS_Time_t tick_end = OS_GetTicks() + OS_MSecsToTicks(param->time_sec * 1000);
  378. uint32_t random_sleep = param->random;
  379. char *buf;
  380. uint32_t start_sector = param->start_sector;
  381. uint32_t round = 0;
  382. uint32_t total_num;
  383. card = mmc_card_open(0);
  384. if (!card) {
  385. CMD_ERR("card open failed!\n");
  386. goto fail;
  387. }
  388. buf = cmd_malloc(param->sector_num*512);
  389. if (!buf)
  390. goto out;
  391. for (int i = 0; i < 512/4; i++)
  392. ((unsigned int *)buf)[i] = i;
  393. for (int i = 1; i < param->sector_num; i++)
  394. memcpy(buf + i * 512, buf, 512);
  395. if (!random_sleep)
  396. random_sleep = 2;
  397. OS_MSleep(random_sleep);
  398. CMD_DBG("%s id:%d random:%d\n", __func__, (unsigned int)param->task_idx, (unsigned int)random_sleep);
  399. while (tick_now < tick_end) {
  400. err = mmc_block_write(card, (uint8_t *)buf, start_sector, param->sector_num);
  401. if (err) {
  402. CMD_ERR("mmc mult blocks write err!\n");
  403. goto out;
  404. }
  405. start_sector += param->sector_num;
  406. if (start_sector >= param->start_sector + PRESS_FILE_SIZE/512) {
  407. start_sector = param->start_sector;
  408. round = 1;
  409. }
  410. OS_MSleep(random_sleep);
  411. tick_now = OS_GetTicks();
  412. if (tick_now >= tick_print + 5000) {
  413. CMD_DBG("%s id:%d testing... at sector:%d\n", __func__,
  414. (unsigned int)param->task_idx, (unsigned int)start_sector);
  415. tick_print = tick_now;
  416. }
  417. }
  418. CMD_DBG("%s test end. round:%d start_sector:%d end_sector:%d\n", __func__,
  419. (unsigned int)round, (unsigned int)param->start_sector, (unsigned int)start_sector);
  420. if (round) {
  421. total_num = PRESS_FILE_SIZE/512;
  422. } else {
  423. // BUG_ON(start_sector <= param->start_sector);
  424. total_num = start_sector - param->start_sector;
  425. }
  426. total_num /= param->sector_num;
  427. start_sector = param->start_sector;
  428. CMD_DBG("%s test checking... start_sector:%d total_num:%d\n", __func__,
  429. (unsigned int)start_sector, (unsigned int)total_num);
  430. for (int i = 0; i < total_num; i++) {
  431. int j;
  432. memset(buf, 0, param->sector_num*512);
  433. err = mmc_block_read(card, (uint8_t *)buf, start_sector, param->sector_num);
  434. if (err) {
  435. CMD_ERR("mmc mult blocks read err!\n");
  436. goto out;
  437. }
  438. err = 0;
  439. for (j = 0; j < param->sector_num*(512/4); j++) {
  440. if (((unsigned int *)buf)[j] != (j & 0x07f)) {
  441. err = -1;
  442. break;
  443. }
  444. }
  445. if (err) {
  446. CMD_ERR("%x %x\n", ((unsigned int *)buf)[j], (j & 0x07f));
  447. CMD_ERR("mmc %d blocks write data err! at sector:%d count:%d\n",
  448. (unsigned int)param->sector_num, (unsigned int)start_sector, j);
  449. goto out;
  450. } else
  451. CMD_DBG("%s mmc blocks write data ok! at sector:%u\n",
  452. __func__, HAL_PR_SZ(start_sector));
  453. start_sector += param->sector_num;
  454. }
  455. out:
  456. mmc_card_close(0);
  457. CMD_DBG("%s id:%d test end\n", __func__, (unsigned int)param->task_idx);
  458. cmd_free(buf);
  459. fail:
  460. cmd_free(param);
  461. OS_ThreadDelete(NULL);
  462. }
  463. /*
  464. * drv sd bench s=<Start_Sector>
  465. */
  466. static enum cmd_status cmd_sd_bench_exec(char *cmd)
  467. {
  468. OS_Thread_t thread;
  469. char *param;
  470. uint32_t len;
  471. len = strlen(cmd);
  472. if (len >= CMD_ARG_LEN) {
  473. CMD_ERR("should adjust CMD_ARG_LEN to %d\n", (unsigned int)len);
  474. return CMD_STATUS_FAIL;
  475. }
  476. param = cmd_malloc(CMD_ARG_LEN);
  477. if (!param)
  478. return CMD_STATUS_FAIL;
  479. memcpy(param, cmd, len);
  480. param[len+1] = 0;
  481. OS_ThreadSetInvalid(&thread);
  482. if (OS_ThreadCreate(&thread,
  483. "",
  484. cmd_sd_bench_task,
  485. param,
  486. OS_THREAD_PRIO_APP,
  487. 2 * 1024) != OS_OK) {
  488. CMD_ERR("create sd bench test task failed\n");
  489. return CMD_STATUS_FAIL;
  490. }
  491. return CMD_STATUS_OK;
  492. }
  493. /*
  494. * drv sd press r=<threads_num> s=<Start_Sector> n=<sector_num> w=<threads_num>
  495. * s=<Start_Sector> n=<sector_num> t=<secons>
  496. * eg:
  497. * drv sd press r=2 s=200000 n=20 w=2 s=400000 n=20 t=600
  498. */
  499. static enum cmd_status cmd_sd_press_exec(char *cmd)
  500. {
  501. OS_Thread_t thread;
  502. struct sd_test_param *param;
  503. uint32_t r_threads, w_threads;
  504. uint32_t r_secnum, w_secnum;
  505. uint32_t cnt;
  506. uint32_t time_sec;
  507. uint32_t start_rsector, start_wsector;
  508. cnt = cmd_sscanf(cmd, "r=%u s=%u n=%u w=%u s=%u n=%d t=%u",
  509. HAL_PR_SZ_P(&r_threads), HAL_PR_SZ_P(&start_rsector), HAL_PR_SZ_P(&r_secnum),
  510. HAL_PR_SZ_P(&w_threads), HAL_PR_SZ_P(&start_wsector), HAL_PR_SZ_P(&w_secnum), HAL_PR_SZ_P(&time_sec));
  511. if (cnt != 7) {
  512. CMD_ERR("invalid argument %s\n", cmd);
  513. return CMD_STATUS_FAIL;
  514. }
  515. OS_SemaphoreCreate(&sem_wait, 0, OS_SEMAPHORE_MAX_COUNT);
  516. OS_MSleep(5);
  517. for (uint32_t i = 0; i < r_threads; i++) {
  518. param = cmd_malloc(sizeof(struct sd_test_param));
  519. if (!param)
  520. return CMD_STATUS_FAIL;
  521. param->task_idx = i;
  522. param->task_num = r_threads;
  523. param->start_sector = start_rsector;
  524. param->sector_num = r_secnum;
  525. param->time_sec = time_sec;
  526. param->random = rand() % 8 + i;
  527. if (!r_secnum || time_sec < 2) {
  528. CMD_ERR("%s read n=<sector_num> should not 0 !\n", __func__);
  529. cmd_free(param);
  530. goto out;
  531. }
  532. OS_ThreadSetInvalid(&thread);
  533. if (OS_ThreadCreate(&thread,
  534. "",
  535. cmd_sd_press_read_task,
  536. param,
  537. OS_THREAD_PRIO_APP,
  538. 2 * 1024) != OS_OK) {
  539. CMD_ERR("create sd press read task:%d failed\n", (unsigned int)i);
  540. return CMD_STATUS_FAIL;
  541. }
  542. (void)cmd_sd_press_read_task;
  543. OS_MSleep(2);
  544. }
  545. for (uint32_t i = 0; i < w_threads; i++) {
  546. param = cmd_malloc(sizeof(struct sd_test_param));
  547. if (!param)
  548. return CMD_STATUS_FAIL;
  549. param->task_idx = i;
  550. param->task_num = w_threads;
  551. param->start_sector = start_wsector;
  552. param->sector_num = w_secnum;
  553. param->time_sec = time_sec;
  554. param->random = rand() % 20 + i;
  555. if (!w_secnum || time_sec < 2) {
  556. CMD_ERR("%s write n=<sector_num> should not 0 !\n", __func__);
  557. cmd_free(param);
  558. goto out;
  559. }
  560. OS_ThreadSetInvalid(&thread);
  561. if (OS_ThreadCreate(&thread,
  562. "",
  563. cmd_sd_press_write_task,
  564. param,
  565. OS_THREAD_PRIO_APP,
  566. 2 * 1024) != OS_OK) {
  567. CMD_ERR("create sd press write task:%d failed\n", (unsigned int)i);
  568. return CMD_STATUS_FAIL;
  569. }
  570. OS_MSleep(2);
  571. }
  572. out:
  573. return CMD_STATUS_OK;
  574. }
  575. static const struct cmd_data g_sd_cmds[] = {
  576. { "init", cmd_sd_init_exec },
  577. { "deinit", cmd_sd_deinit_exec },
  578. { "scan", cmd_sd_scan_exec },
  579. { "read", cmd_sd_read_exec },
  580. { "test", cmd_sd_test_exec },
  581. { "bench", cmd_sd_bench_exec },
  582. { "press", cmd_sd_press_exec },
  583. };
  584. #if 0
  585. static portBASE_TYPE prvSdmmcTestCommand( char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString )
  586. {
  587. const char *const pcHeader = "sdmmc test\r\n";
  588. /* Remove compile time warnings about unused parameters, and check the
  589. write buffer is not NULL. NOTE - for simplicity, this example assumes the
  590. write buffer length is adequate, so does not check for buffer overflows. */
  591. ( void ) pcCommandString;
  592. ( void ) xWriteBufferLen;
  593. configASSERT( pcWriteBuffer );
  594. /* Generate a table of task stats. */
  595. strcpy( pcWriteBuffer, pcHeader );
  596. vTaskList( pcWriteBuffer + strlen( pcHeader ) );
  597. {
  598. //static enum cmd_status cmd_sd_test_exec(char *cmd);
  599. printf("%s,%d\r\n",__FUNCTION__, __LINE__ );
  600. cmd_sd_test_exec(NULL);
  601. }
  602. /* There is no more data to return after this single string, so return
  603. pdFALSE. */
  604. return pdFALSE;
  605. }
  606. static const CLI_Command_Definition_t xSdmmcTest =
  607. {
  608. "sdmmc-test", /* The command string to type. */
  609. "\r\nsdmmc-test:\r\n test sdmmc drivers\r\n",
  610. prvSdmmcTestCommand, /* The function to run. */
  611. 0 /* No parameters are expected. */
  612. };
  613. void xSdmmc_regcmd(void)
  614. {
  615. FreeRTOS_CLIRegisterCommand( &xSdmmcTest );
  616. }
  617. #endif
  618. /*
  619. enum cmd_status cmd_sd_exec(char *cmd)
  620. {
  621. return cmd_exec(cmd, g_sd_cmds, cmd_nitems(g_sd_cmds));
  622. }
  623. */
  624. int cmd_sdmmc_sample(int argc, char ** argv)
  625. {
  626. int i = 0;
  627. while(argc--)
  628. {
  629. printf("argv[%d] = %s\n", i, argv[i]);
  630. i++;
  631. }
  632. cmd_sd_test_exec(NULL);
  633. return 0;
  634. }
  635. FINSH_FUNCTION_EXPORT_CMD(cmd_sdmmc_sample, sdmmctest, SdmmcTestCommand);