luat_lib_little_flash.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /*
  2. @module little_flash
  3. @summary flash驱动 软件包(同时支持驱动nor flash和nand flash设备)
  4. @version 1.0
  5. @date 2024.05.11
  6. @demo little_flash
  7. @tag LUAT_USE_LITTLE_FLASH
  8. */
  9. #include "luat_base.h"
  10. #include "luat_spi.h"
  11. #include "luat_mem.h"
  12. #define LUAT_LOG_TAG "little_flash"
  13. #include "luat_log.h"
  14. #include "little_flash.h"
  15. /*
  16. 初始化 little_flash
  17. @api lf.init(spi_device)
  18. @userdata spi_device
  19. @return userdata 成功返回一个数据结构,否则返回nil
  20. @usage
  21. --spi_device
  22. spi_device = spi.deviceSetup(0,17,0,0,8,2000000,spi.MSB,1,0)
  23. log.info("lf.init",lf.init(spi_device))
  24. */
  25. static int luat_little_flash_init(lua_State *L){
  26. luat_spi_device_t* little_flash_spi_device = NULL;
  27. little_flash_t* lf_flash = NULL;
  28. if (lua_type(L, 1) == LUA_TUSERDATA){
  29. little_flash_spi_device = (luat_spi_device_t*)lua_touserdata(L, 1);
  30. lf_flash = luat_heap_malloc(sizeof(little_flash_t));
  31. memset(lf_flash, 0, sizeof(little_flash_t));
  32. lf_flash->spi.user_data = little_flash_spi_device;
  33. }else{
  34. LLOGW("little_flash init spi_device is nil");
  35. return 0;
  36. }
  37. little_flash_init();
  38. lf_err_t re = little_flash_device_init(lf_flash);
  39. if (re == LF_ERR_OK){
  40. lua_pushlightuserdata(L, lf_flash);
  41. return 1;
  42. }
  43. luat_heap_free(lf_flash);
  44. return 0;
  45. }
  46. /*
  47. 擦除 Flash 指定地址指定大小,按照flash block大小进行擦除
  48. @api lf.erase(flash,add,size)
  49. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  50. @number add 擦除地址
  51. @number size 擦除大小
  52. @return bool 成功返回true
  53. @usage
  54. lf.erase(flash,add,size)
  55. */
  56. static int luat_little_flash_erase(lua_State *L){
  57. little_flash_t *flash = lua_touserdata(L, 1);
  58. if (flash == NULL) {
  59. LLOGE("little_flash mount flash is nil");
  60. return 0;
  61. }
  62. uint32_t addr = luaL_checkinteger(L, 2);
  63. size_t size = luaL_checkinteger(L, 3);
  64. lf_err_t ret = little_flash_erase(flash,addr,size);
  65. lua_pushboolean(L, ret ? 1 : 0);
  66. return 1;
  67. }
  68. /*
  69. 擦除 Flash 全部数据
  70. @api lf.chipErase(flash)
  71. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  72. @return bool 成功返回true
  73. @usage
  74. lf.chipErase(flash)
  75. */
  76. static int luat_little_flash_chip_erase(lua_State *L){
  77. little_flash_t *flash = lua_touserdata(L, 1);
  78. if (flash == NULL) {
  79. LLOGE("little_flash mount flash is nil");
  80. return 0;
  81. }
  82. lf_err_t ret = little_flash_chip_erase(flash);
  83. lua_pushboolean(L, ret ? 1 : 0);
  84. return 1;
  85. }
  86. /*
  87. 读取 Flash 数据
  88. @api lf.read(flash, addr, size)
  89. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  90. @int addr 起始地址
  91. @int size 从起始地址开始读取数据的总大小
  92. @return string data 读取到的数据
  93. @usage
  94. log.info("lf.read",lf.read(lf_device,1024,4))
  95. */
  96. static int luat_little_flash_read(lua_State *L){
  97. little_flash_t *flash = lua_touserdata(L, 1);
  98. if (flash == NULL) {
  99. LLOGE("little_flash mount flash is nil");
  100. return 0;
  101. }
  102. uint32_t addr = luaL_checkinteger(L, 2);
  103. size_t size = luaL_checkinteger(L, 3);
  104. uint8_t* data = (uint8_t*)luat_heap_malloc(size);
  105. lf_err_t ret = little_flash_read(flash, addr, data, size);
  106. if(ret != 0){
  107. size = 0;
  108. LLOGD("lf read ret %d", ret);
  109. }
  110. lua_pushlstring(L, (const char*)data, size);
  111. luat_heap_free(data);
  112. return 1;
  113. }
  114. /*
  115. 向 Flash 写数据
  116. @api lf.write(flash, addr,data)
  117. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  118. @int addr 起始地址
  119. @string data 待写入的数据
  120. @return bool 成功返回true
  121. @usage
  122. log.info("lf.write",lf.write(lf_device,1024,"lf"))
  123. */
  124. static int luat_little_flash_write(lua_State *L){
  125. little_flash_t *flash = lua_touserdata(L, 1);
  126. if (flash == NULL) {
  127. LLOGE("little_flash mount flash is nil");
  128. return 0;
  129. }
  130. uint32_t addr = luaL_checkinteger(L, 2);
  131. size_t size = 0;
  132. const char* data = luaL_checklstring(L, 3, &size);
  133. lf_err_t ret = little_flash_write(flash, addr, (const uint8_t*)data, size);
  134. lua_pushboolean(L, ret ? 1 : 0);
  135. return 1;
  136. }
  137. /*
  138. 先擦除再往 Flash 写数据
  139. @api lf.eraseWrite(flash, addr,data)
  140. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  141. @int addr 起始地址
  142. @string data 待写入的数据
  143. @return bool 成功返回true
  144. @usage
  145. log.info("lf.eraseWrite",lf.eraseWrite(lf_device,1024,"lf"))
  146. */
  147. static int luat_little_flash_erase_write(lua_State *L){
  148. little_flash_t *flash = lua_touserdata(L, 1);
  149. if (flash == NULL) {
  150. LLOGE("little_flash mount flash is nil");
  151. return 0;
  152. }
  153. uint32_t addr = luaL_checkinteger(L, 2);
  154. size_t size = 0;
  155. const char* data = luaL_checklstring(L, 3, &size);
  156. lf_err_t ret = little_flash_erase_write(flash, addr, (const uint8_t*)data, size);
  157. lua_pushboolean(L, ret ? 1 : 0);
  158. return 1;
  159. }
  160. /*
  161. 获取 Flash 容量和page大小
  162. @api lf.getInfo(flash)
  163. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  164. @return int Flash 容量
  165. @return int page 页大小
  166. @usage
  167. log.info("lf.getInfo",lf.getInfo(lf_device))
  168. */
  169. static int luat_little_flash_get_info(lua_State *L){
  170. little_flash_t *flash = lua_touserdata(L, 1);
  171. if (flash == NULL) {
  172. LLOGE("little_flash mount flash is nil");
  173. return 0;
  174. }
  175. uint32_t capacity = 0;
  176. uint32_t page = 0;
  177. capacity = flash->chip_info.capacity;
  178. page = flash->chip_info.prog_size;
  179. lua_pushinteger(L, capacity);
  180. lua_pushinteger(L, page);
  181. return 2;
  182. }
  183. #ifdef LUAT_USE_FS_VFS
  184. #include "luat_fs.h"
  185. #include "lfs.h"
  186. extern lfs_t* flash_lfs_lf(little_flash_t* flash, size_t offset, size_t maxsize);
  187. /*
  188. 挂载 little_flash lfs文件系统
  189. @api lf.mount(flash, mount_point, offset, maxsize)
  190. @userdata flash Flash 设备对象 lf.init()返回的数据结构
  191. @string mount_point 挂载目录名
  192. @int 起始偏移量,默认0
  193. @int 总大小, 默认是整个flash
  194. @return bool 成功返回true
  195. @usage
  196. log.info("lf.mount",lf.mount(little_flash_device,"/little_flash"))
  197. */
  198. static int luat_little_flash_mount(lua_State *L) {
  199. little_flash_t *flash = lua_touserdata(L, 1);
  200. if (flash == NULL) {
  201. LLOGE("little_flash mount flash is nil");
  202. return 0;
  203. }
  204. const char* mount_point = luaL_checkstring(L, 2);
  205. size_t offset = luaL_optinteger(L, 3, 0);
  206. size_t maxsize = luaL_optinteger(L, 4, 0);
  207. lfs_t* lfs = flash_lfs_lf(flash, offset, maxsize);
  208. if (lfs) {
  209. luat_fs_conf_t conf = {
  210. .busname = (char*)lfs,
  211. .type = "lfs2",
  212. .filesystem = "lfs2",
  213. .mount_point = mount_point,
  214. };
  215. int ret = luat_fs_mount(&conf);
  216. LLOGD("vfs mount %s ret %d", mount_point, ret);
  217. lua_pushboolean(L, 1);
  218. }
  219. else {
  220. lua_pushboolean(L, 0);
  221. }
  222. return 1;
  223. }
  224. #endif
  225. #include "rotable2.h"
  226. static const rotable_Reg_t reg_little_flash[] =
  227. {
  228. { "init", ROREG_FUNC(luat_little_flash_init)},
  229. { "erase", ROREG_FUNC(luat_little_flash_erase)},
  230. { "chipErase", ROREG_FUNC(luat_little_flash_chip_erase)},
  231. { "read", ROREG_FUNC(luat_little_flash_read)},
  232. { "write", ROREG_FUNC(luat_little_flash_write)},
  233. { "eraseWrite", ROREG_FUNC(luat_little_flash_erase_write)},
  234. { "getInfo", ROREG_FUNC(luat_little_flash_get_info)},
  235. #ifdef LUAT_USE_FS_VFS
  236. { "mount", ROREG_FUNC(luat_little_flash_mount)},
  237. #endif
  238. { NULL, ROREG_INT(0)}
  239. };
  240. LUAMOD_API int luaopen_little_flash( lua_State *L ) {
  241. luat_newlib2(L, reg_little_flash);
  242. return 1;
  243. }