sd_sim.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. */
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <rtthread.h>
  13. #include <dfs.h>
  14. #define DBG_TAG "sd.sim"
  15. #define DBG_LVL DBG_WARNING
  16. #include <rtdbg.h>
  17. #define SDCARD_SIM "sd.bin"
  18. #define SDCARD_SIZE (16*1024*1024) //16M
  19. struct sdcard_device
  20. {
  21. struct rt_device parent;
  22. FILE *file;
  23. };
  24. static struct sdcard_device _sdcard;
  25. #define SDCARD_DEVICE(device) (( struct sdcard_device*)(device))
  26. static rt_mutex_t lock;
  27. /* RT-Thread device interface */
  28. static rt_err_t rt_sdcard_init(rt_device_t dev)
  29. {
  30. return RT_EOK;
  31. }
  32. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  33. {
  34. return RT_EOK;
  35. }
  36. static rt_err_t rt_sdcard_close(rt_device_t dev)
  37. {
  38. return RT_EOK;
  39. }
  40. /* position: block page address, not bytes address
  41. * buffer:
  42. * size : how many blocks
  43. */
  44. static rt_size_t rt_sdcard_read(rt_device_t device, rt_off_t position, void *buffer, rt_size_t size)
  45. {
  46. struct sdcard_device *sd;
  47. int result = 0;
  48. LOG_I("sd read: pos %d, size %d", position, size);
  49. rt_mutex_take(lock, RT_WAITING_FOREVER);
  50. sd = SDCARD_DEVICE(device);
  51. fseek(sd->file, position * SECTOR_SIZE, SEEK_SET);
  52. result = fread(buffer, size * SECTOR_SIZE, 1, sd->file);
  53. if (result < 0)
  54. goto _err;
  55. rt_mutex_release(lock);
  56. return size;
  57. _err:
  58. LOG_E("sd read errors!");
  59. rt_mutex_release(lock);
  60. return 0;
  61. }
  62. /* position: block page address, not bytes address
  63. * buffer:
  64. * size : how many blocks
  65. */
  66. static rt_size_t rt_sdcard_write(rt_device_t device, rt_off_t position, const void *buffer, rt_size_t size)
  67. {
  68. struct sdcard_device *sd;
  69. int result = 0;
  70. LOG_I("sst write: pos %d, size %d", position, size);
  71. rt_mutex_take(lock, RT_WAITING_FOREVER);
  72. sd = SDCARD_DEVICE(device);
  73. fseek(sd->file, position * SECTOR_SIZE, SEEK_SET);
  74. result = fwrite(buffer, size * SECTOR_SIZE, 1, sd->file);
  75. if (result < 0)
  76. goto _err;
  77. rt_mutex_release(lock);
  78. return size;
  79. _err:
  80. LOG_E("sd write errors!");
  81. rt_mutex_release(lock);
  82. return 0;
  83. }
  84. static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
  85. {
  86. struct sdcard_device *sd;
  87. unsigned int size;
  88. RT_ASSERT(dev != RT_NULL);
  89. sd = SDCARD_DEVICE(dev);
  90. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  91. {
  92. struct rt_device_blk_geometry *geometry;
  93. geometry = (struct rt_device_blk_geometry *)args;
  94. if (geometry == RT_NULL) return -RT_ERROR;
  95. geometry->bytes_per_sector = SECTOR_SIZE;
  96. geometry->block_size = SECTOR_SIZE;
  97. fseek(sd->file, 0, SEEK_END);
  98. size = ftell(sd->file);
  99. geometry->sector_count = size / SECTOR_SIZE;
  100. }
  101. return RT_EOK;
  102. }
  103. rt_err_t rt_hw_sdcard_init(const char *spi_device_name)
  104. {
  105. int size;
  106. struct sdcard_device *sd;
  107. struct rt_device *device;
  108. sd = &_sdcard;
  109. device = &(sd->parent);
  110. lock = rt_mutex_create("lock", RT_IPC_FLAG_PRIO);
  111. if (lock == RT_NULL)
  112. {
  113. LOG_E("Create mutex in rt_hw_sdcard_init failed!");
  114. return -RT_ERROR;
  115. }
  116. /* open sd card file, if not exist, then create it */
  117. sd->file = fopen(SDCARD_SIM, "rb+");
  118. if (sd->file == NULL)
  119. {
  120. /* create a file to simulate sd card */
  121. sd->file = fopen(SDCARD_SIM, "wb+");
  122. fseek(sd->file, 0, SEEK_END);
  123. size = ftell(sd->file);
  124. fseek(sd->file, 0, SEEK_SET);
  125. if (size < SDCARD_SIZE)
  126. {
  127. int i;
  128. unsigned char *ptr;
  129. ptr = (unsigned char *) malloc(1024 * 1024);
  130. if (ptr == NULL)
  131. {
  132. LOG_E("malloc error, no memory!");
  133. return RT_ERROR;
  134. }
  135. memset(ptr, 0x0, 1024 * 1024);
  136. fseek(sd->file, 0, SEEK_SET);
  137. for (i = 0; i < (SDCARD_SIZE / (1024 * 1024)); i++)
  138. fwrite(ptr, 1024 * 1024, 1, sd->file);
  139. free(ptr);
  140. }
  141. }
  142. fseek(sd->file, 0, SEEK_SET);
  143. device->type = RT_Device_Class_Block;
  144. device->init = rt_sdcard_init;
  145. device->open = rt_sdcard_open;
  146. device->close = rt_sdcard_close;
  147. device->read = rt_sdcard_read;
  148. device->write = rt_sdcard_write;
  149. device->control = rt_sdcard_control;
  150. device->user_data = NULL;
  151. rt_device_register(device, "sd0",
  152. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  153. return RT_EOK;
  154. }
  155. #ifdef RT_USING_FINSH
  156. #include <finsh.h>
  157. int sd_erase(void)
  158. {
  159. rt_uint32_t index;
  160. char * buffer;
  161. struct rt_device *device;
  162. device = &_sdcard.parent;
  163. if ((buffer = rt_malloc(SECTOR_SIZE)) == RT_NULL)
  164. {
  165. rt_kprintf("out of memory\n");
  166. return -1;
  167. }
  168. memset(buffer, 0, SECTOR_SIZE);
  169. /* just erase the MBR! */
  170. for (index = 0; index < 2; index ++)
  171. {
  172. rt_sdcard_write(device, index, buffer, SECTOR_SIZE);
  173. }
  174. rt_free(buffer);
  175. return 0;
  176. }
  177. FINSH_FUNCTION_EXPORT(sd_erase, erase all block in SPI flash);
  178. #endif