• Home
Name Date Size #Lines LOC

..--

figures/12-May-2024-

BUILD.gnD12-May-2024927 2320

README_zh.mdD12-May-20245.6 KiB241185

fs_test.cD12-May-20243.3 KiB123102

README_zh.md

1
2
3# littlefs使用说明
4
5# 简述
6
7LittleFS主要用在微控制器和flash上,是一种嵌入式文件系统,具有如下3个特点:
8
91. 掉电恢复
10
11   在写入时即使复位或者掉电也可以恢复到上一个正确的状态。
12
132. 擦写均衡
14
15   有效延长flash的使用寿命。
16
173. 有限的RAM/ROM
18
19   节省ROM和RAM空间。
20
21niobe407模组外接16M flash,在外挂flash的后8M挂载littlefs文件系统,默认挂载点为talkweb,默认创建存储数据的目录data,目录如下:
22
23```
24OHOS # ls
25Directory /talkweb:
26.                    <DIR>
27..                   <DIR>
28data                 <DIR>
29talkweb0             8
30talkweb1             7
31wifi.cfg             28
32```
33
34
35
36# littlefs使用说明
37
38littlefs需要通过内核配置进行选配,操作如下:
39
401. 切换到kernel/liteos_m/目录
41
42   ```
43   cd kernel/liteos_m/
44   ```
45
462. 输入make menuconfig 打开内核配置界面
47
48   ```
49   make menuconfig
50   ```
51
523. 选择FileSystem,选上littlefs
53
54![image-20220215153205796](figures/1.png)
55
56OpenHarmony已经实现了vfs,注册了littlefs的相关接口,vfs向标准文件操作提供对应的接口,因此应用可以调用的newlibc标准文件操作接口进行测试。
57
58涉及的部分文件操作接口如下:
59
60| 接口名   | 描述             |
61| -------- | ---------------- |
62| _open    | 打开文件         |
63| _close   | 关闭文件         |
64| _write   | 写文件           |
65| _read    | 读文件           |
66| _lseek   | 设置文件偏移位置 |
67| mkdir    | 创建目录         |
68| opendir  | 打开目录         |
69| closedir | 关闭目录         |
70| rmdir    | 删除目录         |
71| mount    | 分区挂载         |
72| unmount  | 分区卸载         |
73
74## 测试
75
76niobe407的littlefs的测试可以通过内核核配置打开,操作如下:
77
781. 切换到kernel/liteos_m/目录
79
80   ```
81   cd kernel/liteos_m/
82   ```
83
842. 输入make menuconfig 打开内核配置界面
85
86   ```
87   make menuconfig
88   ```
89
90   弹出配置界面,选择Platform下的select board niobe407。
91
92   ![image-20220216150938794](figures/2.png)
93
943. 选配application中的fs store。
95
96   ![image-20220217141103858](figures/3.png)
97
98测例:
99
100```
101static void dir_test(const char *path)
102{
103    DIR *dir;
104    int ret ;
105    struct dirent *dp;
106    /*文件夹打开关闭测试*/
107    if ((dir = opendir(path)) == NULL) {
108        printf("opendir %s failed \n", path);
109        return;
110    }
111    while ((dp = readdir(dir)) != NULL) {
112        if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) {
113            continue;
114        }
115        struct stat st_buf = {0};
116        char realpath[260];
117        snprintf_s(realpath, sizeof(realpath), "%s/%s", path, dp->d_name);
118        if (stat(realpath, &st_buf) != 0) {
119            printf("can not access %s\n", realpath);
120            closedir(dir);
121            return;
122        }
123        if ((st_buf.st_mode & S_IFMT) == S_IFDIR) {
124            printf("DIR %s\n", realpath);
125        } else {
126            printf("FILE %s, %ld bytes\n", realpath, st_buf.st_size);
127        }
128    }
129    closedir(dir);
130
131    /*文件夹创建删除测试*/
132    ret = mkdir("/talkweb/fstestdir",S_IRUSR | S_IWUSR);
133    if(ret){
134       printf("mkdir failed \n");
135       return;
136    }
137    ret = rmdir("/talkweb/fstestdir");
138    if(ret){
139       printf("rmdir failed \n");
140       return;
141    }
142    printf("%s ok \n",__func__);
143}
144```
145
146该接口测试目录的开启和关闭,如果目录不存在直接返回。
147
148```
149static void write_test(const char *file, const char *data)
150{
151    int fd = _open(file, O_RDWR | O_CREAT);
152     if (fd < 0) {
153        printf("open file '%s' failed \r\n", file);
154        return;
155    }
156    int bytes = _write(fd,data,strlen(data));
157    _close(fd);
158    printf("write file '%s' total bytes: %d, %s\r\n", file, bytes, data);
159}
160```
161
162上述接口测试文件的写操作。
163
164```
165static void read_test(const char *file, bool print_str)
166{
167    int fd = _open(file, O_RDWR | O_CREAT);
168    if (fd < 0) {
169        printf("open file '%s' failed, \r\n", file);
170        return;
171    }
172    int bytes = 0;
173    char buf[513];
174    while (1) {
175        memset_s(buf, sizeof(buf), 0, sizeof(buf));
176        int rc = _read(fd, buf, sizeof(buf) - 1);
177        if (rc > 0)
178            bytes += rc;
179
180        if (print_str) {
181            buf[rc] = '\0';
182            printf("%s\r\n", buf);
183        }
184
185        if (rc < sizeof(buf) - 1)
186            break;
187    }
188    _close(fd);
189    printf("read file '%s' total bytes: %d\r\n", file, bytes);
190}
191```
192
193上述接口测试文件的读操作。
194
195注意:littlefs挂载的根目录为talkweb,所有创建的目录都应该是talkweb的子目录,例如/talkweb/data等。
196
197测试主程序:
198
199```
200void fs_test(void)
201{
202    /*文件夹打开创建测试*/
203    dir_test("/talkweb");
204    /*文件读写测试*/
205    read_test("/talkweb/wifi.cfg", true);
206    write_test("/talkweb/wifi.cfg", "ssid:talkweb password:123456");
207    read_test("/talkweb/wifi.cfg", true);
208}
209```
210
211BUILD.gn
212
213```
214import("//kernel/liteos_m/liteos.gni")
215
216module_name = get_path_info(rebase_path("."), "name")
217kernel_module(module_name) {
218    sources = [
219        "fs_test.c",
220    ]
221}
222```
223
224测试结果:
225
226```
227hiview init success.
228Initialize 0littlefs_test
229DIR /talkweb/data
230dir_test ok
231
232read file '/talkweb/wifi.cfg' total bytes: 0
233read_test ok
234write file '/talkweb/wifi.cfg' total bytes: 28, ssid:talkweb password:123456
235write_test ok
236ssid:talkweb password:123456
237read file '/talkweb/wifi.cfg' total bytes: 28
238read_test ok
239
240```
241