Skip to content

Commit b230ad4

Browse files
committed
fs: add file system folder and fs packed tool
1 parent 09e804d commit b230ad4

File tree

11 files changed

+330
-0
lines changed

11 files changed

+330
-0
lines changed

m5stack/fs/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
├── apps
2+
│ └── helloworld.py
3+
├── libs
4+
│ └── __init__.py
5+
├── res
6+
│ ├── font
7+
│ │ └── README.md
8+
│ └── img
9+
│ ├── README.md
10+
│ └── uiflow.png
11+
├── boot.py
12+
├── main.py
13+
└── README.md

m5stack/fs/apps/helloworld.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# apps/helloworld.py

m5stack/fs/boot.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# boot.py

m5stack/fs/libs/__init__.py

Whitespace-only changes.

m5stack/fs/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# main.py

m5stack/fs/res/font/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
You can put font files in this folder.

m5stack/fs/res/img/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
You can put images in this folder.

m5stack/fs/res/img/uiflow.png

1.63 KB
Loading

tools/littlefs/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
cmake_minimum_required (VERSION 3.16)
2+
3+
project(littlefs2)
4+
5+
include_directories(mbed-littlefs)
6+
aux_source_directory(mbed-littlefs/littlefs DIR_SRCS)
7+
8+
add_executable(littlefs2 littlefs2.c ${DIR_SRCS})

tools/littlefs/littlefs2.c

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <getopt.h>
4+
#include <dirent.h>
5+
#include <unistd.h>
6+
#include <sys/stat.h>
7+
#include <sys/types.h>
8+
#include "littlefs/lfs2.h"
9+
#include "littlefs/lfs2_util.h"
10+
11+
static struct lfs2_config cfg;
12+
static lfs2_t lfs2;
13+
static uint8_t *image;
14+
static int verbose = 0;
15+
16+
/* input hex string, format: 0xAA111 or AA111 or abc11 */
17+
int ahextoi(char *p) {
18+
int n = 0;
19+
char *q = p;
20+
21+
/* reach its tail */
22+
while (*q) {
23+
q++;
24+
}
25+
26+
if (*p == '0' && *(p + 1) != 0) { /* skip "0x" or "0X" */
27+
p += 2;
28+
}
29+
30+
while (*p) {
31+
int c;
32+
if (*p >= '0' && *p <= '9') {
33+
c = *p - '0';
34+
} else if (*p >= 'A' && *p <= 'F') {
35+
c = *p - 'A' + 0xA;
36+
} else if (*p >= 'a' && *p <= 'f') {
37+
c = *p - 'a' + 0xA;
38+
} else {
39+
/* invalid char */
40+
return 0;
41+
}
42+
43+
n += c << ((int)(q - p - 1) * 4);
44+
p++;
45+
}
46+
return n;
47+
}
48+
49+
static int lfs2_read(const struct lfs2_config *c, lfs2_block_t block,
50+
lfs2_off_t off, void *buffer, lfs2_size_t size) {
51+
memcpy(buffer, image + (block * c->block_size) + off, size);
52+
return 0;
53+
}
54+
55+
static int lfs2_prog(const struct lfs2_config *c, lfs2_block_t block,
56+
lfs2_off_t off, const void *buffer, lfs2_size_t size) {
57+
memcpy(image + (block * c->block_size) + off, buffer, size);
58+
return 0;
59+
}
60+
61+
static int lfs2_erase(const struct lfs2_config *c, lfs2_block_t block) {
62+
memset(image + (block * c->block_size), 0, c->block_size);
63+
return 0;
64+
}
65+
66+
static int lfs2_sync(const struct lfs2_config *c) {
67+
return 0;
68+
}
69+
70+
static void image_initialize(uint32_t fs_size) {
71+
cfg.read = lfs2_read;
72+
cfg.prog = lfs2_prog;
73+
cfg.erase = lfs2_erase;
74+
cfg.sync = lfs2_sync;
75+
76+
cfg.block_size = 4096U;
77+
cfg.read_size = 128U;
78+
cfg.prog_size = 128U;
79+
cfg.block_count = fs_size / cfg.block_size;
80+
cfg.lookahead_size = 256;
81+
cfg.cache_size = 4 * 128;
82+
cfg.block_cycles = 100;
83+
84+
image = (uint8_t *)calloc(sizeof(uint8_t), fs_size);
85+
memset(image, 0xff, fs_size);
86+
lfs2_format(&lfs2, &cfg);
87+
}
88+
89+
int cpt_scan_files(const char *basePath, char (*file_path)[257],
90+
uint16_t *file_count) {
91+
DIR *dir;
92+
struct dirent *ptr;
93+
94+
if ((dir = opendir(basePath)) == NULL) {
95+
printf("[ Cpt Scan ] Open dir '%s' failed... \r\n", basePath);
96+
exit(1);
97+
}
98+
99+
while ((ptr = readdir(dir)) != NULL) {
100+
if (strcmp(ptr->d_name, ".") == 0 ||
101+
strcmp(ptr->d_name, "..") == 0) { /// current dir OR parrent dir
102+
continue;
103+
} else if (ptr->d_type == 8) { /// file
104+
sprintf(&file_path[*file_count][0], "%s/%s", basePath, ptr->d_name);
105+
*file_count += 1;
106+
if (*file_count == 255) {
107+
printf("[ Cpt Scan ] File count than %d, failed \r\n", 255);
108+
}
109+
} else if (ptr->d_type == 4) {
110+
char path_new[300] = {0x00};
111+
sprintf(path_new, "%s/%s", basePath, ptr->d_name);
112+
sprintf(&file_path[*file_count][0], "%s/.", path_new);
113+
*file_count += 1;
114+
cpt_scan_files(path_new, file_path, file_count);
115+
}
116+
}
117+
118+
closedir(dir);
119+
return 1;
120+
}
121+
122+
int16_t write_file(lfs2_t *fs, const char *path, const char *data,
123+
uint32_t len) {
124+
int16_t res;
125+
126+
lfs2_file_t dstf;
127+
lfs2_dir_t lfs_dir;
128+
129+
char *split_ptr = NULL;
130+
uint16_t split_pos = 0;
131+
char path_dir[256] = {0x00};
132+
sprintf(path_dir, "%s", path);
133+
134+
for (;;) {
135+
split_ptr = strchr(&path_dir[split_pos + 1], '/');
136+
if (split_ptr == NULL) {
137+
break;
138+
}
139+
split_pos = split_ptr - path_dir;
140+
*split_ptr = '\0';
141+
142+
if (lfs2_dir_open(fs, &lfs_dir, path_dir) != LFS2_ERR_OK) {
143+
res = lfs2_mkdir(fs, path_dir);
144+
if (res != LFS2_ERR_OK) {
145+
return res;
146+
}
147+
} else {
148+
lfs2_dir_close(fs, &lfs_dir);
149+
}
150+
*split_ptr = '/';
151+
}
152+
if (path[strlen(path) - 1] == '.') {
153+
return LFS2_ERR_OK;
154+
}
155+
lfs2_file_open(&lfs2, &dstf, path, LFS2_O_WRONLY | LFS2_O_CREAT);
156+
if (lfs2_file_write(&lfs2, &dstf, data, len) != len) {
157+
printf("[ LFS2 Pack ] File(%s) write error\r\n", path);
158+
return LFS2_ERR_NOMEM;
159+
}
160+
lfs2_file_close(&lfs2, &dstf);
161+
return LFS2_ERR_OK;
162+
}
163+
164+
void save_fs_image(const char *path, const uint32_t image_size) {
165+
FILE *fp = NULL;
166+
char file_path[200];
167+
fp = fopen(path, "w+");
168+
if (fp == NULL) {
169+
printf("[ FS Image ] Save path '%s' failed \r\n", path);
170+
exit(1);
171+
}
172+
fwrite(image, sizeof(uint8_t), image_size, fp);
173+
fclose(fp);
174+
}
175+
176+
int create_fs_image(const char *path, const uint32_t size,
177+
const char *image_path) {
178+
int32_t file_size = 0;
179+
int64_t total_size = 0;
180+
uint8_t *read_buff;
181+
FILE *ff;
182+
183+
if (size % 4096) {
184+
printf("[ LFS2 Pack ] image size must multiple sector size\r\n");
185+
exit(1);
186+
}
187+
188+
image_initialize(size);
189+
190+
if (lfs2_mount(&lfs2, &cfg) != LFS2_ERR_OK) {
191+
printf("[ LFS2 Pack ] file system mount failed\r\n");
192+
exit(1);
193+
}
194+
195+
char file_path[255][257];
196+
int16_t file_count = 0;
197+
cpt_scan_files(path, file_path, &file_count);
198+
199+
for (size_t i = 0; i < file_count; i++) {
200+
if (file_path[i][strlen(file_path[i]) - 1] == '.') {
201+
if (write_file(&lfs2, &file_path[i][strlen(path) + 1], read_buff,
202+
file_size) != LFS2_ERR_OK) {
203+
printf("[ LFS2 Pack ] file too large, pack failed \r\n");
204+
exit(1);
205+
}
206+
continue;
207+
}
208+
209+
ff = fopen(&file_path[i][0], "r");
210+
fseek(ff, 0, SEEK_END);
211+
file_size = ftell(ff);
212+
rewind(ff);
213+
read_buff = (uint8_t *)calloc(file_size, sizeof(uint8_t));
214+
if (fread(read_buff, sizeof(uint8_t), file_size, ff) != file_size) {
215+
printf("[ LFS2 Pack ] file '%s' read failed\r\n", &file_path[i][0]);
216+
exit(1);
217+
}
218+
if (write_file(&lfs2, &file_path[i][strlen(path) + 1], read_buff,
219+
file_size) != LFS2_ERR_OK) {
220+
printf("[ LFS2 Pack ] file too large, pack failed \r\n");
221+
exit(1);
222+
}
223+
total_size += file_size;
224+
if (verbose) {
225+
printf("[ LFS2 Pack ] Add -> %s\r\n", &file_path[i][strlen(path) + 1]);
226+
}
227+
free(read_buff);
228+
}
229+
lfs2_unmount(&lfs2);
230+
save_fs_image(image_path, size);
231+
232+
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n");
233+
printf("[ LFS2 Pack ] vfs size: 0x%x bytes\r\n", size);
234+
printf("[ LFS2 Pack ] vfs used: 0x%06lx bytes %f%%\r\n", total_size, (double)((double)total_size / (double)size) * 100.0);
235+
printf("[ LFS2 Pack ] save path: %s\r\n", image_path);
236+
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
237+
}
238+
239+
uint8_t is_int_string(char *str) {
240+
for (uint16_t i = 0; i < strlen(str); i++) {
241+
if (str[i] < '0' || str[i] > '9') {
242+
return 0;
243+
}
244+
}
245+
return 1;
246+
}
247+
248+
int main(int argc, char *argv[]) {
249+
static int lopt = -1;
250+
static const struct option param_option[] = {
251+
{"create", no_argument, &lopt, 0},
252+
{"unpack", no_argument, &lopt, 1},
253+
{"verbose", no_argument, &verbose, 0},
254+
{"input", required_argument, NULL, 'i'},
255+
{"size", required_argument, NULL, 's'},
256+
{"output", required_argument, NULL, 'o'},
257+
};
258+
259+
static int opt = 0;
260+
static uint32_t size = 0;
261+
static char *input = NULL;
262+
static char *output = NULL;
263+
264+
while ((opt = getopt_long(argc, argv, "cuvi:s:o:", param_option, NULL)) !=
265+
-1) {
266+
switch (opt) {
267+
case 'i':
268+
input = optarg;
269+
// printf("input: %s\r\n", input);
270+
break;
271+
case 's':
272+
size = ahextoi(optarg);
273+
// printf("size: %d\r\n", size);
274+
break;
275+
case 'o':
276+
output = optarg;
277+
// printf("output: %s\r\n", output);
278+
break;
279+
case 'c':
280+
lopt = 0;
281+
break;
282+
case 'u':
283+
lopt = 1;
284+
break;
285+
case 'v':
286+
verbose = 1;
287+
break;
288+
}
289+
}
290+
291+
if (lopt == 0) {
292+
assert(size != 0);
293+
assert(input != NULL);
294+
assert(output != NULL);
295+
create_fs_image(input, size, output);
296+
} else if (lopt == 1) {
297+
assert(input != NULL);
298+
assert(output != NULL);
299+
if (input != NULL && output != NULL) {
300+
}
301+
}
302+
303+
return 0;
304+
}

0 commit comments

Comments
 (0)