⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fdt.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//----------------------------------------------------
//Copyright (C), 2004-2009,  lst.
//版权所有 (C), 2004-2009,   lst.
//所属模块:flash文件系统
//作者:lst
//版本:V1.0.0
//文件描述:flash文件系统中FDR表部分
//其他说明:
//修订历史:
//    2. ...
//    1. 日期:
//       作者:
//       新版本号:
//       修改说明:
//------------------------------------------------------
#include "inc_os.h"
#include "flashfile.h"
#include "fdt.h"
#include "ddr.h"
#include <string.h>

//----初始化FDT表--------------------------------------------------------------
//功能:初始化FDT表,把存储块划分为一个个FDT_item,并用双向链表连接起来。FDT
//      表的第一个FDT_item始终是根目录项。本函数只会在文件柜格式化时调用
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//返回:true=成功,false=失败
//-----------------------------------------------------------------------------
bool_t __DFFSD_init_FDT(struct st_DBX_flash_tag *DBX_flash_tag)
{
    uint8_t *FDT_buf;
    struct fdt_info *pl_FDT_item;
    struct flash_chip *chip;
    uint32_t true_block,FDT_block_no;
    uint32_t block_capacity,loop;
    chip = DBX_flash_tag->chip;
    FDT_block_no = DBX_flash_tag->DDR_FDSB;
    block_capacity = chip->block_size / 256;
    DBX_flash_tag->FDT_capacity = block_capacity;
    DBX_flash_tag->FDT_free_num= block_capacity - 1;
    FDT_buf = chip->block_buf;
    for(loop=0; loop < block_capacity; loop++)
    {
        pl_FDT_item = (struct fdt_info*)(FDT_buf + loop * 256);
        pl_FDT_item->name_buf_len = cn_flash_file_name_limit +1;
        pl_FDT_item->mattr = 0xff;  //表示空闲FDT_item
        //以下把所有FDT_item的修改和创建日期时间均改为2009-01-04-12-00-00,
        //那是djyos的生日。
        pl_FDT_item->second_create  = 0x00;
        pl_FDT_item->minute_create  = 0x00;
        pl_FDT_item->hour_create    = 0x12;
        pl_FDT_item->date_create    = 0x04;
        pl_FDT_item->month_create   = 0x01;
        pl_FDT_item->year_low_create= 0x09;
        pl_FDT_item->year_high_create=0x20;
        pl_FDT_item->second_modify  = 0x00;
        pl_FDT_item->minute_modify  = 0x00;
        pl_FDT_item->hour_modify    = 0x12;
        pl_FDT_item->date_modify    = 0x04;
        pl_FDT_item->month_modify   = 0x01;
        pl_FDT_item->year_low_modify =0x09;
        pl_FDT_item->year_high_modify=0x20;
        strcpy(pl_FDT_item->name,"free item");
        __fill_little_32bit(pl_FDT_item->file_size,0,0);
        __fill_little_32bit(pl_FDT_item->file_size,1,0);

        if(loop == 0)   //这是根目录项
        {
            //根目录项的next和previous指针用于把空闲块串起来。
            //根目录项的previous指针指向FDT末项
            __fill_little_32bit(pl_FDT_item->previous,0,block_capacity-1);
            //根目录项的next指针指向第一个空闲项
            __fill_little_32bit(pl_FDT_item->next,0,1);
            //根目录项的file_size指针用途特殊,前4字节记录着空闲FDT表项数
            __fill_little_32bit(pl_FDT_item->file_size,0,block_capacity-1);
            //根目录项的file_size指针用途特殊,后4字节记录着总FDT表项数
            __fill_little_32bit(pl_FDT_item->file_size,1,block_capacity);
            //根目录项的父目录指针parent空着
            __fill_little_32bit(pl_FDT_item->parent,0,cn_limit_uint32);
            //根目录项的子目录指针fstart_dson空着
            __fill_little_32bit(pl_FDT_item->fstart_dson,0,cn_limit_uint32);
            //根目录是个只读目录
            pl_FDT_item->mattr = cn_FS_ATTR_DIRECTORY + cn_FS_ATTR_READ_ONLY;
            strcpy(pl_FDT_item->name,"root folder");
        }else if(loop == block_capacity-1)  //空闲的最后一项
        {
            //previous指针前一项
            __fill_little_32bit(pl_FDT_item->previous,0,block_capacity-2);
            //最后一项的next指针指向根目录项
            __fill_little_32bit(pl_FDT_item->next,0,0);
            __fill_little_32bit(pl_FDT_item->parent,0,cn_limit_uint32);
            __fill_little_32bit(pl_FDT_item->fstart_dson,0,cn_limit_uint32);
        }else
        {
            //previous指针指向前一项
            __fill_little_32bit(pl_FDT_item->previous,0,loop - 1);
            //next指针指向后一项
            __fill_little_32bit(pl_FDT_item->next,0,loop + 1);
            __fill_little_32bit(pl_FDT_item->parent,0,cn_limit_uint32);
            __fill_little_32bit(pl_FDT_item->fstart_dson,0,cn_limit_uint32);
        }
    }
    //把缓冲区写入flash块内
    true_block = __DFFSD_write_new_block(DBX_flash_tag,
                                            FDT_block_no,0,chip->block_size);
    if(true_block == cn_limit_uint32)   //如果写入错误
        return false;
    if(true_block != FDT_block_no)      //如果发生了块交换
        __DFFSD_update_MAT_item(DBX_flash_tag,FDT_block_no,true_block);
    return true;
}

//----FDT表增加1块-------------------------------------------------------------
//功能:当FDT表项用完后,调用本函数增加1块存储器,并把新增加的存储器划分为一个
//      个FDT_item块,然后用双向链表连接起来,并连接到空闲表中去。
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//返回:true=成功,false=失败,一般是因为没有空闲块
//-----------------------------------------------------------------------------
bool_t __DFFSD_add_FDT_block(struct st_DBX_flash_tag *DBX_flash_tag)
{
    uint8_t *FDT_buf;
    struct fdt_info *pl_FDT_item,FDT_item;
    struct flash_chip *chip;
    uint32_t FDT_item_new_start,free_item,new_block_no,true_block;
    uint32_t block_capacity,last_block_no;
    uint32_t loop;
    if(DBX_flash_tag->valid_sum <= 2)
        return false;   //剩余可用块数小于等于2时,分配一块给FDT表是毫无意义的
    chip = DBX_flash_tag->chip;
    FDT_item_new_start = DBX_flash_tag->FDT_capacity;
    block_capacity = chip->block_size / 256;
    __DFFSD_read_FDT_item(DBX_flash_tag,0,&FDT_item);
    new_block_no = __DFFSD_allocate_block(DBX_flash_tag); //申请一个flash块
    if(new_block_no == cn_limit_uint32)
        return false;
    FDT_buf = chip->block_buf;
    pl_FDT_item = (struct fdt_info*)FDT_buf;
    //新申请块的第一项previous指针指向根目录项
    __fill_little_32bit(pl_FDT_item->previous,0,0);
    //新申请块的next指针指向新申请块的第二项
    __fill_little_32bit(pl_FDT_item->next,0,FDT_item_new_start + 1);

    pl_FDT_item = (struct fdt_info*)(FDT_buf + (block_capacity-1) * 256);
    //新申请块的最后一项的previous指针指向倒数第二项
    __fill_little_32bit(pl_FDT_item->previous,0,
                        FDT_item_new_start + loop -1);
    if(0 == DBX_flash_tag->FDT_free_num)    //已经没有空闲FDT_item
    {
        //根目录项的previous指针指向新申请块的末项
        __fill_little_32bit(FDT_item.previous,0,
                            FDT_item_new_start + block_capacity-1);
        //根目录项的next指针指向新申请块的首项
        __fill_little_32bit(FDT_item.next,0,FDT_item_new_start);
        //根目录项写入flash中
        if(! __DFFSD_write_FDT_item(DBX_flash_tag,0,&FDT_item))
            return false;
        //新申请块的最后一项的next指针指向根目录项
        __fill_little_32bit(pl_FDT_item->next,0,0);
    }else       //还剩余少许空闲FDT_item
    {
        //读第一个空闲FDT_item的条目号
        free_item = __pick_little_32bit(FDT_item.next,0);
        //根目录项的next指针指向新申请块的首项
        __fill_little_32bit(FDT_item.next,0,FDT_item_new_start);
        //根目录项写入flash
        if(! __DFFSD_write_FDT_item(DBX_flash_tag,0,&FDT_item))
            return false;
        //读第一个空闲FDT项到缓冲区中
        __DFFSD_read_FDT_item(DBX_flash_tag,free_item,&FDT_item);
        //原第一个空闲项的向前指针指向新申请块的最后一项
        __fill_little_32bit(FDT_item.previous,0,
                            FDT_item_new_start + block_capacity-1);
        //原第一个空闲项写入flash
        if(! __DFFSD_write_FDT_item(DBX_flash_tag,free_item,&FDT_item))
            return false;

        //新申请块的最后一项的next指针指向原第一个空闲项
        __fill_little_32bit(pl_FDT_item->next,0,free_item);
    }
    for(loop=1; loop < block_capacity-1; loop++)
    {//把新申请块除首末FDT条目以外的其他FDT条目连接起来
        pl_FDT_item = (struct fdt_info*)(FDT_buf + loop * 256);
        __fill_little_32bit(pl_FDT_item->previous,0,
                            FDT_item_new_start + loop - 1);
        __fill_little_32bit(pl_FDT_item->next,0,
                            FDT_item_new_start + loop + 1);
    }
    true_block = __DFFSD_write_new_block(DBX_flash_tag,
                                            new_block_no,0,chip->block_size);
    if(true_block == cn_limit_uint32)
        return false;  //此时,FDT根目录项的指针已经改变并写入flash,但新块缓冲
                       //区却没有写入flash,将造成FDT的free项链断裂,错误可以在
                       //启动时查出,那时将会看到根目录项中第一个空闲项的号码大
                       //于MAT中FDT块的容量。---db,启动检查此项
    //loop保存FDT首块的块号,用于定位MAT表中的FDT链
    loop = DBX_flash_tag->DDR_FDSB;
    do  //本循环用于找到MAT表中FDT链的最后一块
    {
        last_block_no = loop;
        loop = DBX_flash_tag->DDR_MAT[last_block_no].next;
    }while(loop != last_block_no);
    //把新申请块的实际写入的块号加入到MAT表中的FDT块号链中
    __DFFSD_add_MAT_item(DBX_flash_tag,last_block_no,true_block);
    DBX_flash_tag->FDT_capacity += block_capacity;
    DBX_flash_tag->FDT_free_num += block_capacity;
    if(!__DFFSD_write_DDR(DBX_flash_tag))
        return false;
    chip->erase_block(DBX_flash_tag->PCRB_no + DBX_flash_tag->start_block);
    return true;
}

//----把一个FDT_item添加到空闲-------------------------------------------------
//功能: 把一个已经被孤立的FDT_item加入到空闲项链表中,成为第一个结点。
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//      FDT_item_no,被释放的条目号
//返回: 无
//-----------------------------------------------------------------------------
void __DFFSD_add_FDT_free_item(struct st_DBX_flash_tag *DBX_flash_tag,
                         uint32_t FDT_item_no)
{
    uint32_t free_first;     
    struct fdt_info FDT_item;
    __DFFSD_read_FDT_item(DBX_flash_tag,0,&FDT_item);   //读出根目录项
    DBX_flash_tag->FDT_free_num++;
    //FDT表根目录项的file_size指针特殊用途:前4字节记录空闲FDT表项数
    __fill_little_32bit(FDT_item.file_size,0,DBX_flash_tag->FDT_free_num);
    free_first = __pick_little_32bit(FDT_item.next,0);
    if(DBX_flash_tag->FDT_free_num == 1)      //原空闲链表是空的
    {
        //根目录项的向前向后指针均指向目标项
        __fill_little_32bit(FDT_item.next,0,FDT_item_no);
        __fill_little_32bit(FDT_item.previous,0,FDT_item_no);
        __DFFSD_write_FDT_item(DBX_flash_tag,0,&FDT_item);  //写入根目录项
        //读出被释放项
        __DFFSD_read_FDT_item(DBX_flash_tag,FDT_item_no,&FDT_item);
        //目标块的向前向后指针均指向根目录项
        __fill_little_32bit(FDT_item.next,0,0);
        __fill_little_32bit(FDT_item.previous,0,0);
        FDT_item.mattr |= cn_FS_ATTR_DELETED;
        //被修改项写入flash。
        __DFFSD_write_FDT_item(DBX_flash_tag,FDT_item_no,&FDT_item);
        //为最大限度保留数据恢复信息,不修改除链表以外的其他数据
    }else               //空闲链表非空
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -