我需要将 8 字节数据(uint64_t 计数器)重复写入大小为 256 MB 的 ubifs 分区。我担心由于重复写入而导致闪存磨损。
查看分区上的
ubinfo -a
输出,最小 I/O 单元大小为 2048 字节。所以我的第一次尝试是对大小为 2048 字节的文件进行循环写入。 IE。写入 256 次(乘以 8 字节),然后无限地返回到开头。
我已经建立了一个程序来测试这个理论,两周后我注意到
Current maximum erase counter value
又名 max_ec
计数器在大约 18 亿次写入后上升到大约 20,000。这远远超出了我对所有擦除块的完美均匀磨损的预期。我的下一个方法是尝试接近 124KB 的文件大小,即逻辑擦除块的大小,看看是否有任何区别。
我看到三个选项:
有更好的方法吗?
这是重复写入的小 C 程序:
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/stat.h>
int main(int argc, char *argv[]){
int fd;
char *ptr;
uint64_t writeops, filesize, index=0, i;
if (argc!=3){
printf("Usage: %s filesize(uint64_t) writeops(uint64_t)\n");
return 1;
}
// Sanitise args
filesize = strtoul(argv[1], &ptr, 10);
writeops = strtoul(argv[2], &ptr, 10);
if (filesize%8 !=0){
printf("Filesize must be a multiple of 8\n");
return 2;
}
// Open a file to write
fd = open("/mnt/user/magicnumber", O_CREAT|O_RDWR|O_DSYNC|O_LARGEFILE, S_IRUSR|S_IWUSR);
// Get file size to be as big as the filesize arg
lseek(fd, filesize-1, SEEK_SET);
write(fd, '\0', 1);
// Begin actual testing
for(i=1,index=0; i<=writeops; i++,index+=8){
if (index == filesize){
index = 0;
}
lseek(fd, index, SEEK_SET);
write(fd, (char *)&i, sizeof(i));
}
close(fd);
return 0;
}
查看分区上的 ubinfo -a 输出,最小 I/O 单元大小为 2048 字节。所以我的第一次尝试是对大小为 2048 字节的文件进行循环写入。
看来您误解了最小I/O单元大小和文件大小之间的关系。最小I/O单元大小主要是NAND闪存芯片的页大小,但这并不意味着相同大小(最小I/O单元大小)的文件只是使用了最小I/O单元的空间,因为任何ubifs 文件将使用额外的空间用于 ubi + ubifs 管理负载。
在大多数情况下执行如此极端频率的写入操作是没有意义的。为什么不直接将数据存储到缓冲区中,然后偶尔将缓冲区写回 NAND?