Мой код использует бесплатную библиотеку Roland Riegel для FAT16,
Функция добавления может найти позицию файла или позицию в (кластер 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
}
Я застрял, пытаясь разобраться в этом лабиринте ... любая помощь приветствуется. Если вам нужно больше кода, дайте мне знать. Надеюсь, этого достаточно?