lpm.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020.12.11 wanghaijing first version
  9. */
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include "lpm.h"
  13. struct lpm lpm;
  14. /* 初始化 */
  15. int lpm_init(void)
  16. {
  17. rt_slist_init(&lpm.device_list);
  18. /* init lpm */
  19. return RT_EOK;
  20. }
  21. static void lpmm(uint8_t argc, char **argv)
  22. {
  23. // struct lpm_dev *lpm_dev;
  24. struct lpm_partition *part = NULL;
  25. size_t i = 0, j = 0;
  26. #define CMD_PROBE_INDEX 0
  27. #define CMD_READ_INDEX 1
  28. #define CMD_WRITE_INDEX 2
  29. #define CMD_CREATE_INDEX 3
  30. #define CMD_DELETE_INDEX 4
  31. #define CMD_DUMP_INDEX 5
  32. #define HEXDUMP_WIDTH 16
  33. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  34. const char* help_info[] = {
  35. [CMD_PROBE_INDEX] = "lpmm probe dev_name part_name - e.g: lpmm probe norflash app",
  36. [CMD_READ_INDEX] = "lpmm read dev_name part_name sector_no size - e.g: lpmm read norflash app 0 1",
  37. [CMD_WRITE_INDEX] = "lpmm write dev_name part_name sector_no size - e.g: lpmm write norflash app 0 1",
  38. [CMD_CREATE_INDEX] = "lpmm create dev_name part_name size - e.g: lpmm create norflash app 10",
  39. [CMD_DELETE_INDEX] = "lpmm delete dev_name part_name - e.g: lpmm delete norflash app",
  40. [CMD_DUMP_INDEX] = "lpmm dump dev_name info or part_name info - e.g: lpmm dump or lpm dump part", };
  41. if (argc < 2)
  42. {
  43. rt_kprintf("Usage:\n");
  44. for (i = 0; i < sizeof(help_info) / sizeof(char*); i++)
  45. {
  46. rt_kprintf("%s\n", help_info[i]);
  47. }
  48. rt_kprintf("\n");
  49. }
  50. else
  51. {
  52. const char *operator = argv[1];
  53. if (!strcmp(operator, "probe"))
  54. {
  55. if (argc >= 4)
  56. {
  57. char* dev_name = argv[2];
  58. char* part_name = argv[3];
  59. if ((part = lpm_partition_find(dev_name, part_name)) == RT_NULL)
  60. {
  61. rt_kprintf("Device %s Partition %s NOT found. Probe failed.\n", dev_name, part_name);
  62. part = RT_NULL;
  63. }
  64. else
  65. {
  66. rt_kprintf("Probed a block device | %s | offset: %ld | size: %d |.\n", part->name, part->offset,
  67. part->size);
  68. }
  69. }
  70. }
  71. else if (!strcmp(operator, "create"))
  72. {
  73. if (argc >= 5)
  74. {
  75. char* dev_name = argv[2];
  76. char* part_name = argv[3];
  77. uint32_t part_size = atoi(argv[4]);
  78. if ((part = lpm_partition_create(dev_name, part_name, part_size)) == RT_NULL)
  79. {
  80. rt_kprintf("Create %s Partition %s failed.\n", dev_name, part_name);
  81. part = RT_NULL;
  82. }
  83. else
  84. {
  85. rt_kprintf("Create block device | %s | offset: %ld | size: %d |.\n", part->name, part->offset,
  86. part->size);
  87. }
  88. }
  89. }
  90. else if (!strcmp(operator, "delete"))
  91. {
  92. if (argc >= 4)
  93. {
  94. if(!strcmp(argv[3], "all"))
  95. {
  96. lpm_partition_delete_all(argv[2]);
  97. }
  98. else
  99. {
  100. char* dev_name = argv[2];
  101. char* part_name = argv[3];
  102. if (lpm_partition_delete(dev_name, part_name) != RT_EOK)
  103. {
  104. rt_kprintf("Delete %s Partition %s failed.\n", dev_name, part_name);
  105. }
  106. else
  107. {
  108. rt_kprintf("Delete %s Partition %s Success.\n", dev_name, part_name);
  109. }
  110. }
  111. }
  112. }
  113. else if (!strcmp(operator, "read"))
  114. {
  115. if (argc >= 6)
  116. {
  117. struct lpm_partition *lpm_par;
  118. char* dev_name = argv[2];
  119. char* part_name = argv[3];
  120. uint32_t sector_no = atoi(argv[4]);
  121. uint32_t size = atoi(argv[5]);
  122. uint8_t *read_buf = RT_NULL;
  123. int result;
  124. lpm_par = lpm_partition_find(dev_name, part_name);
  125. if (lpm_par == RT_NULL)
  126. {
  127. rt_kprintf("Error: the Device name (%s) or the partition name (%s) is not found.", dev_name,
  128. part_name);
  129. return;
  130. }
  131. else
  132. {
  133. read_buf = rt_malloc(lpm_par->dev->block_size);
  134. if (read_buf == RT_NULL)
  135. {
  136. rt_kprintf("Low memory!\n");
  137. }
  138. result = lpm_partition_read(lpm_par, sector_no, read_buf, size);
  139. if (result >= 0)
  140. {
  141. size = size * (lpm_par->dev->block_size);
  142. rt_kprintf("Read data success. Start sector_no from 0x%08X, size is %ld. The data is:\n",
  143. sector_no, size);
  144. rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n");
  145. for (i = 0; i < size; i += HEXDUMP_WIDTH)
  146. {
  147. rt_kprintf("[%08X] ", sector_no + i);
  148. /* dump hex */
  149. for (j = 0; j < HEXDUMP_WIDTH; j++)
  150. {
  151. if (i + j < size)
  152. {
  153. rt_kprintf("%02X ", read_buf[i + j]);
  154. }
  155. else
  156. {
  157. rt_kprintf(" ");
  158. }
  159. }
  160. /* dump char for hex */
  161. for (j = 0; j < HEXDUMP_WIDTH; j++)
  162. {
  163. if (i + j < size)
  164. {
  165. rt_kprintf("%c", __is_print(read_buf[i + j]) ? read_buf[i + j] : '.');
  166. }
  167. }
  168. rt_kprintf("\n");
  169. }
  170. rt_kprintf("\n");
  171. rt_free(read_buf);
  172. }
  173. else
  174. {
  175. rt_free(read_buf);
  176. }
  177. }
  178. }
  179. else
  180. {
  181. rt_kprintf("Please enter the correct parameters!\r\n ");
  182. }
  183. }
  184. else if (!strcmp(operator, "write"))
  185. {
  186. if (argc >= 6)
  187. {
  188. struct lpm_partition *lpm_par;
  189. char* dev_name = argv[2];
  190. char* part_name = argv[3];
  191. uint32_t sector_no = atoi(argv[4]);
  192. uint32_t size = atoi(argv[5]); //要写的 block 数量
  193. uint8_t *write_buf = RT_NULL;
  194. int result;
  195. uint32_t num;
  196. if(!size)
  197. {
  198. rt_kprintf("Please set 'size' greater than 0!\n");
  199. return;
  200. }
  201. lpm_par = lpm_partition_find(dev_name, part_name);
  202. if (lpm_par == RT_NULL)
  203. {
  204. rt_kprintf("Error: the Device name (%s) or the partition name (%s) is not found.", dev_name,
  205. part_name);
  206. return;
  207. }
  208. else
  209. {
  210. if(lpm_par->size < size )
  211. {
  212. rt_kprintf("The 'size' of the input is larger than the 'size of the partition'!\n");
  213. return;
  214. }
  215. write_buf = rt_calloc(1, size*(lpm_par->dev->block_size));
  216. if (write_buf == RT_NULL)
  217. {
  218. rt_kprintf("Low memory!\n");
  219. }
  220. num = size * (lpm_par->dev->block_size);
  221. for (i = 0; i < num; i++)
  222. {
  223. write_buf[i] = i & 0xFF;
  224. }
  225. result = lpm_partition_write(lpm_par, sector_no, write_buf, size);
  226. if (result >= 0)
  227. {
  228. rt_kprintf("LPM Write Success at the Device name (%s) the partition name (%s) .\r\n", dev_name,
  229. part_name);
  230. }
  231. else
  232. {
  233. rt_kprintf("LPM Write Failed at the Device name (%s) the partition name (%s) .\r\n", dev_name,
  234. part_name);
  235. }
  236. rt_free(write_buf);
  237. }
  238. }
  239. }
  240. else if (!strcmp(operator, "dump"))
  241. {
  242. if (argc >= 2)
  243. {
  244. if (!strcmp(argv[2], "part"))
  245. {
  246. lpm_dump_partition();
  247. }
  248. else
  249. {
  250. lpm_dump_dev();
  251. }
  252. }
  253. }
  254. else if (!strcmp(operator, "free"))
  255. {
  256. rt_kprintf("LPM device: %08s , residue 0x%08x.\r\n", argv[2], lpm_free(argv[2]));
  257. }
  258. else
  259. {
  260. rt_kprintf("Please enter the correct parameters!\r\n ");
  261. }
  262. }
  263. }
  264. MSH_CMD_EXPORT(lpmm, LPM (Logical partition management) operate.);