romfile.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "FreeRTOS.h"
  4. #include "chip.h"
  5. #include "board.h"
  6. #include "flash.h"
  7. #include "ota_update.h"
  8. #include "romfile.h"
  9. static RomHeader *romheader = NULL;
  10. static SemaphoreHandle_t romfileMutex;
  11. #ifndef ROMFILE_USE_SMALL_MEM
  12. #ifndef READ_ROMFILE_ONCE
  13. static unsigned char *filestatus;
  14. static uint32_t romoffset;
  15. #endif
  16. #else
  17. static uint32_t romoffset;
  18. #if ROMFILE_CACHE_DEF_SIZE
  19. #define ROMFILE_CACHE_LIFE_LIMIT 1000000
  20. static RomFileCache *romfilecache;
  21. #endif
  22. #endif
  23. int ReadRomFile(void)
  24. {
  25. uint32_t offset = get_upfile_offset(UPFILE_TYPE_ROM, 0);
  26. uint32_t size = get_upfile_size(UPFILE_TYPE_ROM);
  27. romfileMutex = xSemaphoreCreateMutex();
  28. xSemaphoreTake(romfileMutex, portMAX_DELAY);
  29. if (size > 0) {
  30. #ifndef ROMFILE_USE_SMALL_MEM
  31. void *rombuf = pvPortMalloc(size);
  32. if (rombuf) {
  33. #ifdef READ_ROMFILE_ONCE
  34. flash_read(offset, size, rombuf);
  35. #else
  36. flash_read(offset, sizeof(RomHeader), rombuf);
  37. romoffset = offset;
  38. #endif
  39. romheader = rombuf;
  40. if (romheader->magic != MKTAG('R', 'O', 'M', 'A')) {
  41. printf("Read rom file error!\n");
  42. vPortFree(rombuf);
  43. xSemaphoreGive(romfileMutex);
  44. return -1;
  45. }
  46. #ifdef READ_ROMFILE_ONCE
  47. CP15_clean_dcache_for_dma((uint32_t)rombuf, (uint32_t)rombuf + size);
  48. #else
  49. int files = romheader->filenum;
  50. flash_read(offset + sizeof(RomHeader), sizeof(RomFileInfo) * files,
  51. (unsigned char*)rombuf + sizeof(RomHeader));
  52. filestatus = pvPortMalloc(files * sizeof(*filestatus));
  53. if (!filestatus) {
  54. printf("filestatus malloc fail.\n");
  55. vPortFree(rombuf);
  56. xSemaphoreGive(romfileMutex);
  57. return -1;
  58. }
  59. memset(filestatus, 0, files * sizeof(*filestatus));
  60. CP15_clean_dcache_for_dma((uint32_t)rombuf, (uint32_t)rombuf + sizeof(RomHeader) +
  61. sizeof(RomFileInfo) * files);
  62. #endif
  63. } else {
  64. printf("Error! No enough memory for romfile.\n");
  65. xSemaphoreGive(romfileMutex);
  66. return -1;
  67. }
  68. #else
  69. RomHeader header;
  70. flash_read(offset, sizeof(RomHeader), (void*)&header);
  71. romoffset = offset;
  72. romheader = pvPortMalloc(sizeof(RomHeader) + sizeof(RomFileInfo) * header.filenum);
  73. if (romheader == NULL) {
  74. printf("Error! No enough memory for romheader.\n");
  75. xSemaphoreGive(romfileMutex);
  76. return -1;
  77. }
  78. memcpy(romheader, &header, sizeof(RomHeader));
  79. flash_read(offset + sizeof(RomHeader), sizeof(RomFileInfo) * header.filenum,
  80. (unsigned char*)romheader + sizeof(RomHeader));
  81. CP15_clean_dcache_for_dma((uint32_t)romheader, (uint32_t)romheader + sizeof(RomHeader) +
  82. sizeof(RomFileInfo) * header.filenum);
  83. #if ROMFILE_CACHE_DEF_SIZE
  84. romfilecache = pvPortMalloc(sizeof(RomFileCache) * ROMFILE_CACHE_DEF_SIZE);
  85. if (romfilecache == NULL) {
  86. printf("Error! No enough memory for romfile cache.\n");
  87. xSemaphoreGive(romfileMutex);
  88. return -1;
  89. }
  90. memset(romfilecache, 0, sizeof(RomFileCache) * ROMFILE_CACHE_DEF_SIZE);
  91. #endif
  92. #endif
  93. } else {
  94. printf("Warning! Not found romfile in update file.\n");
  95. xSemaphoreGive(romfileMutex);
  96. return -1;
  97. }
  98. xSemaphoreGive(romfileMutex);
  99. return 0;
  100. }
  101. RomFile *RomFileOpen(const char *name)
  102. {
  103. int i;
  104. xSemaphoreTake(romfileMutex, portMAX_DELAY);
  105. for (i = 0; i < romheader->filenum; i++) {
  106. if (!strcmp(romheader->files[i].name, name)) {
  107. RomFile *file = pvPortMalloc(sizeof(RomFile));
  108. if (!file) {
  109. xSemaphoreGive(romfileMutex);
  110. return NULL;
  111. }
  112. memset(file, 0, sizeof(RomFile));
  113. file->index = i;
  114. #ifndef ROMFILE_USE_SMALL_MEM
  115. file->buf = (void*)((uint32_t)romheader + romheader->files[i].offset);
  116. #endif
  117. file->size = romheader->files[i].size;
  118. xSemaphoreGive(romfileMutex);
  119. return file;
  120. }
  121. }
  122. xSemaphoreGive(romfileMutex);
  123. return NULL;
  124. }
  125. size_t RomFileRead(RomFile *file, void *buf, size_t size)
  126. {
  127. #if ROMFILE_CACHE_DEF_SIZE
  128. int i;
  129. #endif
  130. if (!file) return 0;
  131. if (size > file->size - file->pos)
  132. size = file->size - file->pos;
  133. if(size == 0)
  134. return 0;
  135. xSemaphoreTake(romfileMutex, portMAX_DELAY);
  136. #ifndef ROMFILE_USE_SMALL_MEM
  137. #ifndef READ_ROMFILE_ONCE
  138. if (!filestatus[file->index]) {
  139. flash_read(romoffset + romheader->files[file->index].offset, file->size, file->buf);
  140. CP15_clean_dcache_for_dma((uint32_t)file->buf, (uint32_t)file->buf + file->size);
  141. filestatus[file->index] = 1;
  142. }
  143. #endif
  144. #else
  145. #if ROMFILE_CACHE_DEF_SIZE
  146. if (!file->cache) {
  147. for (i = 0; i < ROMFILE_CACHE_DEF_SIZE; i++) {
  148. if(!strcmp(romfilecache[i].name, romheader->files[file->index].name)) {
  149. configASSERT(romfilecache[i].buf);
  150. file->buf = romfilecache[i].buf;
  151. file->cache = &romfilecache[i];
  152. romfilecache[i].cached_filenum++;
  153. romfilecache[i].life++;
  154. if (romfilecache[i].life > ROMFILE_CACHE_LIFE_LIMIT)
  155. romfilecache[i].life = ROMFILE_CACHE_LIFE_LIMIT;
  156. }
  157. }
  158. }
  159. for (i = 0; i < ROMFILE_CACHE_DEF_SIZE; i++) {
  160. if(romfilecache[i].life > INT32_MIN + 1)
  161. romfilecache[i].life -= 1;
  162. }
  163. #endif
  164. if (!file->cache) {
  165. #if ROMFILE_CACHE_DEF_SIZE
  166. RomFileCache *cachefile = NULL;
  167. uint32_t stime;
  168. int i;
  169. for (i = 0; i < ROMFILE_CACHE_DEF_SIZE; i++) {
  170. if (romfilecache[i].name[0] == 0) {
  171. cachefile = &romfilecache[i];
  172. break;
  173. }
  174. }
  175. if (!cachefile) {
  176. for (i = 0; i < ROMFILE_CACHE_DEF_SIZE; i++) {
  177. if (romfilecache[i].cached_filenum == 0) {
  178. cachefile = &romfilecache[i];
  179. break;
  180. }
  181. }
  182. if (cachefile) {
  183. for(i = i + 1; i < ROMFILE_CACHE_DEF_SIZE; i++) {
  184. if (romfilecache[i].cached_filenum == 0 &&
  185. romfilecache[i].life < cachefile->life)
  186. cachefile = &romfilecache[i];
  187. }
  188. }
  189. }
  190. if (cachefile) {
  191. int filelife;
  192. file->buf = pvPortMalloc(romheader->files[file->index].size);
  193. if (!file->buf) {
  194. printf("ERROR! No enough memory for opening romfile.\n");
  195. vPortFree(file);
  196. xSemaphoreGive(romfileMutex);
  197. return 0;
  198. }
  199. stime = get_timer(0);
  200. flash_read(romoffset + romheader->files[file->index].offset, file->size, file->buf);
  201. CP15_clean_dcache_for_dma((uint32_t)file->buf, (uint32_t)file->buf + file->size);
  202. filelife = get_timer(stime);
  203. if (cachefile->buf)
  204. vPortFree(cachefile->buf);
  205. strncpy(cachefile->name, romheader->files[file->index].name, ROMFILE_NAME_MAX_LEN);
  206. cachefile->buf = file->buf;
  207. cachefile->cached_filenum = 1;
  208. cachefile->life = filelife;
  209. if (cachefile->life > ROMFILE_CACHE_LIFE_LIMIT)
  210. cachefile->life = ROMFILE_CACHE_LIFE_LIMIT;
  211. file->cache = cachefile;
  212. } else
  213. #endif
  214. {
  215. file->buf = pvPortMalloc(size);
  216. if (!file->buf) {
  217. printf("ERROR! No enough memory for opening romfile.\n");
  218. vPortFree(file);
  219. xSemaphoreGive(romfileMutex);
  220. return 0;
  221. }
  222. flash_read(romoffset + romheader->files[file->index].offset + file->pos,
  223. size, file->buf);
  224. CP15_clean_dcache_for_dma((uint32_t)file->buf, (uint32_t)file->buf + size);
  225. }
  226. }
  227. #endif
  228. if (buf) {
  229. #ifdef ROMFILE_USE_SMALL_MEM
  230. if (!file->cache) {
  231. memcpy(buf, (char *)file->buf, size);
  232. vPortFree(file->buf);
  233. file->buf = NULL;
  234. } else {
  235. #endif
  236. memcpy(buf, (char *)file->buf + file->pos, size);
  237. #ifdef ROMFILE_USE_SMALL_MEM
  238. }
  239. #endif
  240. }
  241. file->pos += size;
  242. xSemaphoreGive(romfileMutex);
  243. return size;
  244. }
  245. int RomFileSeek(RomFile *file, int offset, int whence)
  246. {
  247. if (!file) return -1;
  248. xSemaphoreTake(romfileMutex, portMAX_DELAY);
  249. if (whence == SEEK_SET)
  250. file->pos = offset;
  251. else if (whence == SEEK_CUR)
  252. file->pos += offset;
  253. else if (whence == SEEK_END)
  254. file->pos = file->size - 1 + offset;
  255. if (file->pos >= file->size)
  256. file->pos = file->size - 1;
  257. else if (file->pos < 0)
  258. file->pos = 0;
  259. xSemaphoreGive(romfileMutex);
  260. return file->pos;
  261. }
  262. void RomFileClose(RomFile *file)
  263. {
  264. xSemaphoreTake(romfileMutex, portMAX_DELAY);
  265. if (file) {
  266. #ifdef ROMFILE_USE_SMALL_MEM
  267. #if ROMFILE_CACHE_DEF_SIZE
  268. if (file->cache) {
  269. file->cache->cached_filenum--;
  270. } else {
  271. #endif
  272. if (file->buf)
  273. vPortFree(file->buf);
  274. #if ROMFILE_CACHE_DEF_SIZE
  275. }
  276. #endif
  277. #endif
  278. vPortFree(file);
  279. }
  280. xSemaphoreGive(romfileMutex);
  281. }
  282. /**
  283. * Return with the extension of the filename
  284. * @param fn string with a filename
  285. * @return pointer to the beginning extension or empty string if no extension
  286. */
  287. const char * RomFileGetExt(const char * path)
  288. {
  289. size_t i;
  290. for(i = strlen(path); i > 0; i--) {
  291. if(path[i] == '.') {
  292. return &path[i + 1];
  293. }
  294. else if(path[i] == '/' || path[i] == '\\') {
  295. return ""; /*No extension if a '\' or '/' found*/
  296. }
  297. }
  298. return ""; /*Empty string if no '.' in the file name. */
  299. }
  300. int RomFileTell(RomFile *file)
  301. {
  302. return file->pos;
  303. }
  304. int RomFileGetSize(RomFile *file)
  305. {
  306. return file->size;
  307. }
  308. int RomFileExist(const char *name)
  309. {
  310. int i;
  311. for (i = 0; i < romheader->filenum; i++) {
  312. if (!strcmp(romheader->files[i].name, name)) {
  313. return 1;
  314. }
  315. }
  316. return 0;
  317. }
  318. int RomFileDirExist(const char *name)
  319. {
  320. int i;
  321. int len = strlen(name);
  322. for (i = 0; i < romheader->filenum; i++) {
  323. if (!strncmp(romheader->files[i].name, name, len) &&
  324. romheader->files[i].name[len] == '/') {
  325. return 1;
  326. }
  327. }
  328. return 0;
  329. }