LPC2148 上嵌入了 FAT16 库。无法更新簇位置(棘手!)
我的代码使用FAT16的Roland Riegel免费库,
附加功能可以找到文件位置或(簇1)中的位置,并将新数据保存到簇中的正确位置。经过无数次文件打开和关闭;
文件中的数据从(集群 1)溢出到(集群 2)后,传入的新数据将被完美写入。但是,关闭并重新打开文件后,仅更新文件位置,而不更新簇。
因此,新数据被保存到(集群 1)中的正确位置,但是!!它应该位于(集群 2)中。
虽然我已经找了一段时间了,但我还是请教了专家。这就是我得到的!
抱歉,这条巨大的链条,但否则很难看到它......
string_printf(name, "MainLog.txt");
if(!root_file_exists(name)){
handle = root_open_new(name);
}
else{
handle = root_open_append(name);
}
struct fat16_file_struct * root_open_append(char* name)
{
return(open_file_in_dir_append(fs,dd,name));
}
//////////////////////////////////// // 追加结构 //////////////////////////////////////
struct fat16_file_struct* open_file_in_dir_append(struct fat16_fs_struct* fs, struct fat16_dir_struct* dd, const char* name)
{
struct fat16_file_struct* result;
struct fat16_dir_entry_struct file_entry;
if(!find_file_in_dir(fs, dd, name, &file_entry))
return 0;
result = fat16_open_file(fs, &file_entry);
result->pos = result->dir_entry.file_size;
result->dir_entry.cluster = result->pos_cluster; // <<-Help here
return result;
}
//////// //////////////////////// fat16_open_file 结构 ////////////////////////// ///////
struct fat16_file_struct* fat16_open_file(struct fat16_fs_struct* fs, const struct fat16_dir_entry_struct* dir_entry)
{
rprintf("\nF16OpenFile\n\n");
if(!fs || !dir_entry || (dir_entry->attributes & FAT16_ATTRIB_DIR))
return 0;
struct fat16_file_struct* fd = malloc(sizeof(*fd));
if(!fd)
return 0;
memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry));
fd->fs = fs;
fd->pos = 0;
fd->pos_cluster = dir_entry->cluster;
return fd;
}
///////////////////////////// 写入命令 //////////// ///////
这样调用...
if(fat16_write_file(handle,(unsigned char *)RX_array1, stringSize) < 0)
{
sd_raw_sync();
}
实际上结构在这里///
int16_t fat16_write_file(struct fat16_file_struct* fd, const uint8_t* buffer, uint16_t buffer_len)
{
#if FAT16_WRITE_SUPPORT
/* check arguments */
if(!fd || !buffer || buffer_len < 1)
return -1;
if(fd->pos > fd->dir_entry.file_size)
return -1;
uint16_t cluster_size = fd->fs->header.cluster_size;
uint16_t cluster_num = fd->pos_cluster;///////////////////////////
uint16_t buffer_left = buffer_len;
uint16_t first_cluster_offset = fd->pos % cluster_size;
//uint16_t cl = fat16_append_clusters(fd->fs, cluster_num, 1);
//rprintf("A0 %d\r", cl);
rprintf("N%d OS%d \r", cluster_num, first_cluster_offset);
//uint32_t pos = fd->pos;
//rprintf("Csiz %d\r", cluster_size);
//rprintf("Csiz %d\r", first_cluster_offset);
//rprintf("BLeft %d\r", buffer_left);
/* find cluster in which to start writing */
if(!cluster_num)
{
cluster_num = fd->dir_entry.cluster;
rprintf("C0 %d\r", cluster_num);
if(!cluster_num)
{
rprintf("C1 %d\r", cluster_num);
if(!fd->pos)
{
/* empty file */
fd->dir_entry.cluster = cluster_num = fat16_append_clusters(fd->fs, cluster_num, 1);
rprintf("C2 %d\r", cluster_num);
if(!cluster_num){
return -1;
}
}
else
{
return -1;
}
}
if(fd->pos)
{
uint32_t pos = fd->pos;
//rprintf("FDPOS %d\r", pos);
uint16_t cluster_num_next;
while(pos >= cluster_size)
{
//rprintf("FDPOS\r");
pos -= cluster_size;
cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num);
if(!cluster_num_next && pos == 0)
/* the file exactly ends on a cluster boundary, and we append to it */
cluster_num_next = fat16_append_clusters(fd->fs, cluster_num, 1);
if(!cluster_num_next)
return -1;
cluster_num = cluster_num_next;
}
}
}
/* write data */
do
{
/* calculate data size to write to cluster */
uint32_t cluster_offset = fd->fs->header.cluster_zero_offset +
(uint32_t) (cluster_num - 2) * cluster_size + first_cluster_offset;
uint16_t write_length = cluster_size - first_cluster_offset;
if(write_length > buffer_left)
write_length = buffer_left;
/* write data which fits into the current cluster */
if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length))
break;
/* calculate new file position */
buffer += write_length;
buffer_left -= write_length;
fd->pos += write_length;
if(first_cluster_offset + write_length >= cluster_size)
{
rprintf("TEST %d %d %d\r", first_cluster_offset, write_length, cluster_size);
/* we are on a cluster boundary, so get the next cluster */
uint16_t cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num);
if(!cluster_num_next && buffer_left > 0)
/* we reached the last cluster, append a new one */
cluster_num_next = fat16_append_clusters(fd->fs, cluster_num, 1);
rprintf("NewCluster %d\r", cluster_num_next);
if(!cluster_num_next)
{
rprintf("Zero\r");
fd->pos_cluster = 0;
break;
}
cluster_num = cluster_num_next;
first_cluster_offset = 0;
}
fd->pos_cluster = cluster_num;
}
while(buffer_left > 0); /* check if we are done */
/* update directory entry */
if(fd->pos > fd->dir_entry.file_size)
{
//rprintf("UpdateFilesize\r");
uint32_t size_old = fd->dir_entry.file_size;
/* update file size */
fd->dir_entry.file_size = fd->pos;
/* write directory entry */
if(!fat16_write_dir_entry(fd->fs, &fd->dir_entry))
{
/* We do not return an error here since we actually wrote
* some data to disk. So we calculate the amount of data
* we wrote to disk and which lies within the old file size.
*/
buffer_left = fd->pos - size_old;
fd->pos = size_old;
}
}
return buffer_len - buffer_left;
#else
return -1;
#endif
}
我完全陷入试图弄清楚这个迷宫....任何帮助表示赞赏。如果您需要更多代码,请告诉我。我希望这足够了?
My code is using the Roland Riegel free library for FAT16,
The append function can find the file position or position in (Cluster 1) and save the new data to the correct position in the cluster. After countless file open and closes;
After the data overflows in the file from (Cluster 1) into (Cluster 2) the new data coming in is written perfectly fine. However after the file is closed and reopened, only the file position is being updated and not the cluster.
So new data is being saved into the position in (Cluster 1) and in the correct position, BUT!! It should be in (Cluster 2).
Been searching for a while now though I'd ask the experts. Here's What I got!!
Sorry for the massive chain but its hard to see it otherwise....
string_printf(name, "MainLog.txt");
if(!root_file_exists(name)){
handle = root_open_new(name);
}
else{
handle = root_open_append(name);
}
struct fat16_file_struct * root_open_append(char* name)
{
return(open_file_in_dir_append(fs,dd,name));
}
//////////////////////////////////// Append Structure //////////////////////////////////////
struct fat16_file_struct* open_file_in_dir_append(struct fat16_fs_struct* fs, struct fat16_dir_struct* dd, const char* name)
{
struct fat16_file_struct* result;
struct fat16_dir_entry_struct file_entry;
if(!find_file_in_dir(fs, dd, name, &file_entry))
return 0;
result = fat16_open_file(fs, &file_entry);
result->pos = result->dir_entry.file_size;
result->dir_entry.cluster = result->pos_cluster; // <<-Help here
return result;
}
//////////////////////////////// fat16_open_file Structure ///////////////////////////////
struct fat16_file_struct* fat16_open_file(struct fat16_fs_struct* fs, const struct fat16_dir_entry_struct* dir_entry)
{
rprintf("\nF16OpenFile\n\n");
if(!fs || !dir_entry || (dir_entry->attributes & FAT16_ATTRIB_DIR))
return 0;
struct fat16_file_struct* fd = malloc(sizeof(*fd));
if(!fd)
return 0;
memcpy(&fd->dir_entry, dir_entry, sizeof(*dir_entry));
fd->fs = fs;
fd->pos = 0;
fd->pos_cluster = dir_entry->cluster;
return fd;
}
///////////////////////////// Write Command ///////////////////
Called this way...
if(fat16_write_file(handle,(unsigned char *)RX_array1, stringSize) < 0)
{
sd_raw_sync();
}
Actualy Structure here///
int16_t fat16_write_file(struct fat16_file_struct* fd, const uint8_t* buffer, uint16_t buffer_len)
{
#if FAT16_WRITE_SUPPORT
/* check arguments */
if(!fd || !buffer || buffer_len < 1)
return -1;
if(fd->pos > fd->dir_entry.file_size)
return -1;
uint16_t cluster_size = fd->fs->header.cluster_size;
uint16_t cluster_num = fd->pos_cluster;///////////////////////////
uint16_t buffer_left = buffer_len;
uint16_t first_cluster_offset = fd->pos % cluster_size;
//uint16_t cl = fat16_append_clusters(fd->fs, cluster_num, 1);
//rprintf("A0 %d\r", cl);
rprintf("N%d OS%d \r", cluster_num, first_cluster_offset);
//uint32_t pos = fd->pos;
//rprintf("Csiz %d\r", cluster_size);
//rprintf("Csiz %d\r", first_cluster_offset);
//rprintf("BLeft %d\r", buffer_left);
/* find cluster in which to start writing */
if(!cluster_num)
{
cluster_num = fd->dir_entry.cluster;
rprintf("C0 %d\r", cluster_num);
if(!cluster_num)
{
rprintf("C1 %d\r", cluster_num);
if(!fd->pos)
{
/* empty file */
fd->dir_entry.cluster = cluster_num = fat16_append_clusters(fd->fs, cluster_num, 1);
rprintf("C2 %d\r", cluster_num);
if(!cluster_num){
return -1;
}
}
else
{
return -1;
}
}
if(fd->pos)
{
uint32_t pos = fd->pos;
//rprintf("FDPOS %d\r", pos);
uint16_t cluster_num_next;
while(pos >= cluster_size)
{
//rprintf("FDPOS\r");
pos -= cluster_size;
cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num);
if(!cluster_num_next && pos == 0)
/* the file exactly ends on a cluster boundary, and we append to it */
cluster_num_next = fat16_append_clusters(fd->fs, cluster_num, 1);
if(!cluster_num_next)
return -1;
cluster_num = cluster_num_next;
}
}
}
/* write data */
do
{
/* calculate data size to write to cluster */
uint32_t cluster_offset = fd->fs->header.cluster_zero_offset +
(uint32_t) (cluster_num - 2) * cluster_size + first_cluster_offset;
uint16_t write_length = cluster_size - first_cluster_offset;
if(write_length > buffer_left)
write_length = buffer_left;
/* write data which fits into the current cluster */
if(!fd->fs->partition->device_write(cluster_offset, buffer, write_length))
break;
/* calculate new file position */
buffer += write_length;
buffer_left -= write_length;
fd->pos += write_length;
if(first_cluster_offset + write_length >= cluster_size)
{
rprintf("TEST %d %d %d\r", first_cluster_offset, write_length, cluster_size);
/* we are on a cluster boundary, so get the next cluster */
uint16_t cluster_num_next = fat16_get_next_cluster(fd->fs, cluster_num);
if(!cluster_num_next && buffer_left > 0)
/* we reached the last cluster, append a new one */
cluster_num_next = fat16_append_clusters(fd->fs, cluster_num, 1);
rprintf("NewCluster %d\r", cluster_num_next);
if(!cluster_num_next)
{
rprintf("Zero\r");
fd->pos_cluster = 0;
break;
}
cluster_num = cluster_num_next;
first_cluster_offset = 0;
}
fd->pos_cluster = cluster_num;
}
while(buffer_left > 0); /* check if we are done */
/* update directory entry */
if(fd->pos > fd->dir_entry.file_size)
{
//rprintf("UpdateFilesize\r");
uint32_t size_old = fd->dir_entry.file_size;
/* update file size */
fd->dir_entry.file_size = fd->pos;
/* write directory entry */
if(!fat16_write_dir_entry(fd->fs, &fd->dir_entry))
{
/* We do not return an error here since we actually wrote
* some data to disk. So we calculate the amount of data
* we wrote to disk and which lies within the old file size.
*/
buffer_left = fd->pos - size_old;
fd->pos = size_old;
}
}
return buffer_len - buffer_left;
#else
return -1;
#endif
}
I'm totally stuck trying to figure out this maze.... any helps is appreciated. If you need more code let me know. I hope this is enough?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我对这个库一无所知,很可能您需要调试器断点和大量单步执行来找出问题所在,但我会说我得到了 efsl(嵌入式文件系统库) 0.2.x - 稳定分支 - 在另一个小型微控制器上工作正常。所以你可能会更幸运。
I don't know anything about that library, and most likely you'll need debugger breakpoints and a lot of single stepping to figure out what's wrong, but I will say that I got efsl (embedded filesystem library) 0.2.x -- the stable branch -- working ok on another small microcontroller. So you might have more luck with that.
查看 open 函数,它将文件位置设置为 0:
在 open_file_in_dir_append 函数中,您更新位置,但使用与位置 0 相同的簇:
查看 文档,还有一个 fat16_seek_file 函数,你想查找到文件末尾,所以你应该调用该函数,我认为它会是这样的:
您还可以看一下 fat16_seek_file 的代码,那里到底做了什么。
Looking at the open function, it sets the file position to 0:
In your open_file_in_dir_append function, you update the position, but use the same cluster as used for position 0:
Looking at the Documentation, there is also a fat16_seek_file function, you want to seek to the end of the file, so you should just call that function, I think it will look like this:
You can also take a look at the code of fat16_seek_file what exactly is done there.