Библиотеки FAT16 на LPC2148 встроены. Не удается обновить положение кластера (хитро!) - PullRequest
0 голосов
/ 09 апреля 2011

Мой код использует бесплатную библиотеку 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
}

Я застрял, пытаясь разобраться в этом лабиринте ... любая помощь приветствуется. Если вам нужно больше кода, дайте мне знать. Надеюсь, этого достаточно?

Ответы [ 2 ]

0 голосов
/ 09 апреля 2011

Глядя на функцию open, она устанавливает позицию файла в 0:

fd->pos = 0;
fd->pos_cluster = dir_entry->cluster;

В вашей функции open_file_in_dir_append вы обновляете позицию, но используете тот же кластер, что и для позиции 0:

result = fat16_open_file(fs, &file_entry);
result->pos = result->dir_entry.file_size;

result->dir_entry.cluster = result->pos_cluster; // <<-Help here

Глядя на документацию , есть также функция fat16_seek_file, вы хотите искать в конце файла, так что вы должны просто вызвать эту функцию, я думаю, это будет выглядеть так:

result = fat16_open_file(fs, &file_entry);
int32_t offset=result->dir_entry.file_size;
fat16_seek_file(result, &offset, FAT16_SEEK_SET);

Вы также можете взглянуть на код fat16_seek_file, что именно там делается.

0 голосов
/ 09 апреля 2011

Я ничего не знаю об этой библиотеке, и, скорее всего, вам понадобятся точки останова отладчика и множество отдельных шагов, чтобы понять, что не так, но я скажу, что у меня есть efsl (встроенная библиотека файловой системы) 0.2.x - стабильная ветвь - работает нормально на другом маленьком микроконтроллере.Так что вам, возможно, повезет больше.

...