Advertisement
marcushund

sfs-demo.cpp

Jun 20th, 2014
317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.95 KB | None | 0 0
  1.  
  2. #include "sfs.h"
  3. //VERBOSE defined gives a lot of information on serial port 1
  4. //#define VERBOSE  
  5.  
  6. sfs::sfs() {
  7.     file_mode = FILE_NONE;
  8.     wndx = 0;
  9. }
  10.  
  11. bool sfs::open(char* name) {
  12.  
  13.     filepointer = 0;
  14.     int rc;
  15.     if ((rc = get_handle(name) < 0)) {
  16. #ifdef VERBOSE        
  17.         Serial1.print("get handle error: ");
  18.         Serial1.println(rc, DEC);
  19. #endif        
  20.     };
  21.  
  22. #ifdef VERBOSE
  23.     Serial1.print("open: ");
  24.     Serial1.print(name);
  25.     Serial1.print("\t");
  26.     Serial1.print(handle, DEC);
  27.     Serial1.print("\t");
  28.     Serial1.print(filesize, DEC);
  29.     Serial1.println();
  30. #endif
  31.     if (handle_is_ok() == false) return false;
  32.     file_mode = FILE_READ;
  33.     return true;
  34. }
  35.  
  36. int sfs::size(){
  37.     return filesize;
  38. }
  39. void sfs::close() {
  40. #ifdef VERBOSE
  41.     Serial1.println("close");
  42. #endif    
  43.     if (handle_is_ok() == false) return;
  44.     flush();
  45.     if (file_mode == FILE_WRITE) {
  46.         write_file_size();
  47.     }
  48.     file_mode = FILE_NONE;
  49.     handle = -1;
  50. }
  51.  
  52. void sfs::flush() {
  53.     char buf[3];
  54. #ifdef VERBOSE
  55.     Serial1.println("flush");
  56. #endif
  57.  
  58.     if (pad_flag == true) {
  59.         buf[0] = pad_char;
  60.         buf[1] = 0;
  61.         buf[2] = 0;
  62.         pad_flag = false;
  63.         unsigned long start = calc_file_offset(2);
  64.         write_flash((uint8_t*) buf, start, 2);
  65.         filepointer++;
  66. #ifdef VERBOSE
  67.         Serial1.print("flushing: ");
  68.         Serial1.println(buf);
  69. #endif
  70.     }
  71. }
  72.  
  73. void sfs::erase_file(char* name){
  74.     handle=get_handle(name);
  75.      erase_file(handle);
  76. }
  77. int sfs::get_handle(char *name) {
  78.     uint8_t buf[65];
  79.     filesize = 0;
  80.  
  81.     for (handle = 0; handle < MAX_FILES; handle++) {
  82.         read_flash((uint8_t*) buf, ((unsigned long) handle * DIR_ENTRY), (unsigned long) 64);
  83. #ifdef VERBOSE    
  84.         Serial1.print("get handle ");
  85.         Serial1.print(" ");
  86.         Serial1.println(name);
  87. #endif
  88.         if (strcmp((char*) buf, name) == 0) { //found!
  89.             filesize = atoi((char*) buf + FILE_LEN_OFFSET);
  90. #ifdef VERBOSE
  91.             Serial1.print("get handle:");
  92.             Serial1.print(name);
  93.             Serial1.print("\tsize:");
  94.             Serial1.print(filesize, DEC);
  95.             Serial1.print("\thandle:");
  96.             Serial1.println(handle, DEC);
  97. #endif
  98.             return handle;
  99.         } else
  100.             filesize = 0;
  101.     }
  102.     return -1;
  103. }
  104. int sfs::rename(char*oldname, char* newname){
  105.     Serial1.print("rename");
  106.     if (get_handle(oldname)==-1)
  107.         return FILE_NOT_FOUND;
  108.     erase_handle();
  109.     write_filename(newname);
  110.     write_file_size();
  111.     return 0;
  112.    
  113. }
  114.  
  115. int sfs::dir(char * entry){
  116.    
  117.            
  118.     if (entry==NULL){
  119.        
  120.         dir_index=0;
  121.         return 0;
  122.     }else
  123.         return dir(entry,&dir_index);
  124. }
  125.  
  126. int sfs::dir(char * entry, int * ndx) {
  127. #ifdef VERBOSE
  128.     Serial1.print(" dir: ");
  129. #endif  
  130.  
  131.     if (*ndx < 0 || *ndx > MAX_FILES)
  132.         return -1;
  133.     for (; *ndx < MAX_FILES; (*ndx)++) {
  134.         int rc = get_dir_entry(entry, ndx);
  135.         if (rc > 0) {
  136.             (*ndx)++;
  137.             return rc;
  138.         }
  139.     }
  140.     return -1;
  141. }
  142.  
  143. int sfs::get_dir_entry(char * entry, int * ndx) {
  144.  
  145.     uint8_t buf[68];
  146.     memset(buf, 0, sizeof (buf));
  147.  
  148.     read_flash(buf, (unsigned long) (*ndx * 0x1000), 64);
  149.     buf[16] = 0;
  150.     if (buf[0] != 0xFF) {
  151.         len = strlen((char*) buf);
  152.         memcpy(entry, (char*) buf, len);
  153.         //   len++;
  154.         //entry[len] = ',';
  155.         //len++;
  156.         //memcpy(entry + len, buf + FILE_LEN_OFFSET, 8);
  157.         int flen = atoi((char*)(buf + (FILE_LEN_OFFSET)));
  158. #ifdef VERBOSE      
  159.         Serial1.println((char*) (entry));
  160. #endif      
  161.         return flen;
  162.     } else {
  163.         return -1;
  164.     }
  165. }
  166.  
  167. boolean sfs::create(char* name) {
  168. #ifdef VERBOSE
  169.     Serial1.println("create: ");
  170. #endif  
  171.  
  172.     get_free_handle(name);
  173.     if (handle_is_ok() == false) return false;
  174.     file_mode = FILE_WRITE;
  175.  
  176. #ifdef VERBOSE
  177.     Serial1.print("file create: ");
  178.     Serial1.print(name);
  179.     Serial1.print(" handle: ");
  180.     Serial1.println(handle, DEC);
  181. #endif
  182.  
  183.     erase_handle();
  184.     write_filename(name);
  185.     filepointer = 0;
  186. #ifdef VERBOSE
  187.     Serial1.print("0handle: ");
  188.     Serial1.println(handle, DEC);
  189.     erase_file_data();
  190.     Serial1.print("1handle: ");
  191.     Serial1.println(handle, DEC);
  192. #endif
  193.     return true;
  194. }
  195.  
  196. void sfs::append(char * str) {
  197.     append(str, strlen(str));
  198. }
  199.  
  200. void sfs::add_to_buf(char* str) {
  201.     int len = strlen(str);
  202.     strncpy((wbuf + wndx), str, len);
  203.     wndx = 0;
  204. }
  205.  
  206. void sfs::add_to_buf(char chr) {
  207.     wbuf[0] = chr;
  208.     wndx = 1;
  209. }
  210.  
  211. void sfs::add_to_buf_minus_one(char* str) {
  212.     int len = strlen(str) - 1;
  213.     strncpy((wbuf + wndx), str, len);
  214.     wndx = 0;
  215. }
  216.  
  217. void sfs::append(char* array, int len) {
  218. #ifdef VERBOSE
  219.     Serial1.print("append: ");
  220.     Serial1.println(array);
  221.     int stat = 0;
  222. #endif  
  223.     memset(wbuf, 0, sizeof (wbuf));
  224.     if ((len & 1)) {
  225.         if (pad_flag == true) {
  226.             add_to_buf(pad_char);
  227.             add_to_buf(array);
  228.             pad_flag = false;
  229. #ifdef VERBOSE
  230.             stat = 1;
  231. #endif
  232.         } else {
  233.             pad_char = array[len - 1];
  234.             pad_flag = true;
  235.             if (len == 1)
  236.                 return;
  237.             add_to_buf_minus_one(array);
  238. #ifdef VERBOSE
  239.             stat = 2;
  240. #endif
  241.         }
  242.     } else {
  243.         if (pad_flag == true) {
  244.             add_to_buf(pad_char);
  245.             add_to_buf_minus_one(array);
  246.             pad_char = array[len - 1];
  247.             pad_flag = true;
  248. #ifdef VERBOSE
  249.             stat = 3;
  250. #endif
  251.         } else {
  252.             add_to_buf(array);
  253.             pad_flag = false;
  254. #ifdef VERBOSE
  255.             stat = 4;
  256. #endif
  257.         }
  258.     }
  259.     unsigned long offset = calc_file_offset(3);
  260.     wlen = strlen(wbuf);
  261.     write_flash((uint8_t*) wbuf, offset, wlen);
  262. #ifdef VERBOSE
  263.     Serial1.print("stat: ");
  264. #endif
  265.     filepointer += (unsigned long) wlen;
  266. }
  267.  
  268. void sfs::get_free_handle(char *name) {
  269.  
  270.     uint8_t buf[64];
  271.     memset(buf, '@', 64);
  272.     for (handle = 0; handle < MAX_FILES; handle++) {
  273.         unsigned long loc = ((unsigned long) handle * DIR_ENTRY);
  274.         read_flash(buf, loc, (unsigned long) 16);
  275.         if (strcmp((char*) buf, name) == 0 || buf[0] == 0xFF) { //empty location
  276. #ifdef VERBOSE
  277.             Serial1.print("free handle: ");
  278.             Serial1.println(handle, DEC);
  279. #endif            
  280.             return;
  281.         }
  282.     }
  283. #ifdef VERBOSE
  284.     Serial1.println("no handle available!");
  285. #endif
  286.     handle = -1;
  287. }
  288.  
  289. void sfs::erase_handle() {
  290. #ifdef VERBOSE
  291.     Serial1.print("erase handle: ");
  292.     Serial1.println(handle, DEC);
  293. #endif  
  294.     if (handle_is_ok() == false) return;
  295.     unsigned long start = FLASH_USER_SPACE + ((unsigned long) handle * 0x1000);
  296.     erase_sector(start);
  297. }
  298.  
  299. void sfs::erase_all_files() {
  300.     for (handle = 0; handle < MAX_FILES; handle++) {
  301.         erase_handle();
  302.         erase_file_data();
  303.     }
  304.     handle = 0;
  305. }
  306.  
  307. void sfs::erase_file(int handle) {
  308.     this->handle = handle;
  309.     erase_handle();
  310.     erase_file_data();
  311. }
  312.  
  313. void sfs::erase_file_data() {
  314. #ifdef VERBOSE
  315.     Serial1.print("erase file data: ");
  316. #endif  
  317.     if (handle_is_ok() == false) return;
  318.     unsigned long start = FLASH_USER_SPACE + 0x10000 + ((unsigned long) handle * 0x10000);
  319.     for (int ii = 0; ii < MAX_FILE_BLOCKS; ii++) {
  320.         unsigned long offset = start + (ii * 0x1000);
  321.         erase_sector(offset);
  322.     }
  323. }
  324.  
  325. int sfs::erase_sector(uint32_t start) {
  326. #ifdef VERBOSE
  327.     Serial1.print("erase sector: ");
  328. #endif  
  329.     if (start < FLASH_USER_SPACE) {
  330. #ifdef VERBOSE
  331.         Serial1.println("Attempt to erase sector outside user space!");
  332. #endif
  333.         return -1;
  334.     }
  335. #ifdef VERBOSE
  336.     Serial1.println(start, HEX);
  337. #endif  
  338.     sFLASH_EraseSector(start);
  339.     return 0;
  340. }
  341.  
  342.  
  343. int sfs::read(char *buffer, int len) {
  344.     unsigned long offset = calc_file_offset(1);
  345.     unsigned long br = ((unsigned long) filesize - filepointer);
  346.     int L = 0;
  347.     if (br < (unsigned int) len)
  348.         L = br;
  349.     else
  350.         L = len;
  351.  
  352.     read_flash((uint8_t*) buffer, offset, L);
  353.     buffer[L] = 0;
  354. #ifdef VERBOSE  
  355.     Serial1.print("Offset: ");
  356.     Serial1.print(offset, HEX);
  357.     Serial1.print(" L: ");
  358.     Serial1.print(L, DEC);
  359.     Serial1.print(" ");
  360. #endif  
  361.     filepointer += (unsigned long) L;
  362.     return L;
  363. }
  364.  
  365. unsigned long sfs::calc_file_offset(int where) {
  366. #ifdef VERBOSE
  367.     Serial1.print("calc file offset: ");
  368.     Serial1.println(where, DEC);
  369.     Serial1.println((unsigned long) filepointer, HEX);
  370. #endif  
  371.  
  372.     unsigned long offset;
  373.     offset = filepointer + 0x10000 + (0x10000 * (unsigned long) handle);
  374. #ifdef VERBOSE
  375.     Serial1.print(where, DEC); //who's calling?
  376.     Serial1.print(" handle:");
  377.     Serial1.println(handle, DEC);
  378.     Serial1.print(" offset:");
  379.     Serial1.println((unsigned long) offset, HEX);
  380.     Serial1.print("filepointer:");
  381.     Serial1.print((unsigned long) filepointer, HEX);
  382.     Serial1.print(" ");
  383. #endif
  384.     return (unsigned long) offset;
  385. }
  386.  
  387. bool sfs::handle_is_ok() {
  388.  
  389.     if (handle < 0 || handle >= MAX_FILES) {
  390. #ifdef VERBOSE
  391.         Serial1.print("Bad handle: ");
  392.         Serial1.println(handle, DEC);
  393. #endif
  394.         return false;
  395.     } else
  396.         return true;
  397. }
  398.  
  399. void sfs::write_filename(char* name) {
  400. #ifdef VERBOSE
  401.     Serial1.print("write filename ");
  402. #endif
  403.     if (handle_is_ok() == false) return;
  404.     unsigned long start = calc_dir_entry();
  405. #ifdef VERBOSE
  406.     Serial1.print("start: ");
  407.     Serial1.print(start, HEX);
  408.     Serial1.print(" handle:");
  409.     Serial1.print(handle, DEC);
  410.     Serial1.print(" ");
  411.     Serial1.println(name);
  412. #endif
  413.  
  414.     uint8_t buf[MAX_NAME_LEN + 1];
  415.     pad(buf, name, MAX_NAME_LEN);
  416.     write_flash(buf, start, MAX_NAME_LEN);
  417. }
  418.  
  419. void sfs::pad(uint8_t * dest, char* str, int ln) {
  420.     memset((char*) dest, 0, ln);
  421.     strncpy((char*) dest, str, ln);
  422.  
  423. }
  424.  
  425. void sfs::write_file_size() {
  426.  
  427.     uint8_t buf[MAX_FILESIZE_LEN + 1];
  428.     unsigned char buf2[MAX_FILESIZE_LEN + 1];
  429.     if (handle_is_ok() == false) return;
  430.     unsigned long start = calc_dir_entry();
  431.     String file_size = String(filepointer);
  432.     file_size.getBytes(buf2, MAX_FILESIZE_LEN, 0);
  433.     pad(buf, (char*) buf2, MAX_FILESIZE_LEN);
  434.     write_flash(buf, start + FILE_LEN_OFFSET, MAX_FILESIZE_LEN);
  435.  
  436. #ifdef VERBOSE
  437.     Serial1.print("write size: ");
  438.     Serial1.println(file_size);
  439. #endif
  440. }
  441.  
  442. int sfs::write_to_user_flash(uint8_t *buf, uint32_t start, uint32_t len) {
  443. #ifdef VERBOSE
  444.     Serial1.print("write to user flash: ");
  445. #endif    
  446.     if (start < FLASH_USER_SPACE) {
  447. #ifdef VERBOSE
  448.         Serial1.println("Error: attempt to write outside user space!");
  449. #endif
  450.         return -1;
  451.     }
  452. #ifdef VERBOSE    
  453.     Serial1.print(start, HEX);
  454.     Serial1.print(" to ");
  455.     Serial1.print(start + len - 1, HEX);
  456.     Serial1.print(" len:");
  457.     Serial1.print(len, DEC);
  458.     Serial1.print("\tdata: ");
  459.     Serial1.println((char*) buf);
  460. #endif
  461.     write_flash(buf, FLASH_USER_SPACE + start, len);
  462.     return 0;
  463. }
  464.  
  465. void pad(uint8_t* buf, char* name, int len) {
  466. #ifdef VERBOSE
  467.     Serial1.print("pad: ");
  468. #endif  
  469.     uint8_t nlen = strlen(name);
  470.     if (nlen >= len) {
  471.         nlen = len;
  472.     }
  473.     memset((char*) buf, 0, len + 1);
  474.     memcpy((char*) buf, name, nlen);
  475. }
  476.  
  477. unsigned long sfs::calc_dir_entry() {
  478. #ifdef VERBOSE
  479.     Serial1.println("calc dir entry: ");
  480. #endif  
  481.  
  482.     if (handle_is_ok() == false)
  483.         return -1;
  484.  
  485.     uint32_t loc = ((unsigned long) handle * 0x1000);
  486.     return loc;
  487. }
  488.  
  489. void sfs::dump() {
  490.     uint8_t array[256];
  491.     uint32_t loc = 0x10000;
  492.     int length = 45;
  493.     read_flash(array, loc, length);
  494.     Serial1.println((char*) array);
  495. }
  496.  
  497. void sfs::read_flash(uint8_t* array, uint32_t start, uint32_t len) {
  498.     sFLASH_ReadBuffer(array, FLASH_USER_SPACE + start, len);
  499. }
  500.  
  501. void sfs::write_flash(uint8_t* array, uint32_t start, uint32_t len) {
  502.  
  503.     start += FLASH_USER_SPACE;
  504.     sFLASH_WriteBuffer(array, start, len);
  505. #ifdef VERBOSE
  506.     Serial1.print("writing to:");
  507.     Serial1.print(start, HEX);
  508.     Serial1.print(" len:");
  509.     Serial1.print(len, DEC);
  510.     Serial1.print(" data:");
  511.     Serial1.println((char*) array);
  512. #endif
  513. }
  514.  
  515. void sfs::dump_loc(uint32_t p, int len) {
  516.     Serial1.println("Dump(loc):");
  517.     if (len < 64)
  518.         len = 64;
  519.  
  520.     uint8_t array[len + 1];
  521.  
  522.     //  uint32_t loc;
  523.     for (uint32_t kk = 0; kk < (uint32_t) len; kk += 64) {
  524.         p += kk;
  525.         read_flash(array, p, 64);
  526.         Serial1.print(p, HEX);
  527.         Serial1.print("\t");
  528.         for (int jj = 0; jj < 64; jj++) {
  529.             uint8_t c = array[jj];
  530.             switch (c) {
  531.                 case 0: c = '.';
  532.                     break;
  533.                 case 10: c = '~';
  534.                     break;
  535.                 case 0xFF: c = '`';
  536.                     break;
  537.                 default:
  538.                     if (c < 32 || c > 127)
  539.                         c = '.';
  540.             }
  541.             Serial1.print((char) c);
  542.         }
  543.         Serial1.println();
  544.  
  545.     }
  546. }
  547.  
  548. void sfs::dump(int h, int len) {
  549.     handle = h;
  550.     Serial1.println("Dump(handle):");
  551.     if (len < 64)
  552.         len = 64;
  553.  
  554.     uint8_t array[len + 1];
  555.  
  556.     uint32_t loc;
  557.     for (filepointer = 0; filepointer < (unsigned long) len; filepointer += (unsigned long) 64) {
  558.         loc = calc_file_offset(4);
  559.         read_flash(array, loc, 64);
  560.         Serial1.print(FLASH_USER_SPACE + loc, HEX);
  561.         Serial1.print("\t");
  562.         for (int jj = 0; jj < 64; jj++) {
  563.             uint8_t c = array[jj];
  564.             switch (c) {
  565.                 case 0: c = '.';
  566.                     break;
  567.                 case 10: c = '~';
  568.                     break;
  569.                 case 0xFF: c = '`';
  570.                     break;
  571.                 default:
  572.                     if (c < 32 || c > 127)
  573.                         c = '.';
  574.             }
  575.             Serial1.print((char) c);
  576.         }
  577.         Serial1.println();
  578.     }
  579. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement