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

📄 fdt.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        //根目录项的向前指针均指向目标项
        __fill_little_32bit(FDT_item.next,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,free_first);
        //被释放项后指针指向根目录项
        __fill_little_32bit(FDT_item.next,0,0);
        //被释放项写入flash中
        __DFFSD_write_FDT_item(DBX_flash_tag,FDT_item_no,&FDT_item);
        //读出原第一个空闲项
        __DFFSD_read_FDT_item(DBX_flash_tag,free_first,&FDT_item);
        //原第一个空闲项的后指针指向被释放项
        __fill_little_32bit(FDT_item.previous,0,FDT_item_no);
        //原最后一个空闲项写回flash
        __DFFSD_write_FDT_item(DBX_flash_tag,free_first,&FDT_item);
    }
}

//----孤立一个忙FDT_item-------------------------------------------------------
//功能: 把一个FDT_item从其原来的FDT链中孤立出来,这是删除文件/目录的第一步。
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//      FDT_item_no,被孤立的条目号
//返回: true = 成功,false = 失败,一般是应为FDT_item_no有子目录/文件
//-----------------------------------------------------------------------------
bool_t __DFFSD_acnode_FDT_item(struct st_DBX_flash_tag *DBX_flash_tag,
                         uint32_t FDT_item_no)
{
    uint32_t parent,elder,less,eldest;     //被释放项的父、兄、弟、长兄项目号
    struct fdt_info FDT_item;
    __DFFSD_read_FDT_item(DBX_flash_tag,FDT_item_no,&FDT_item); //读出目标项
    if((FDT_item.mattr & cn_FS_ATTR_DELETED) != 0)
        return false;   //目标FDT_item是一个空闲项/被删除项
    if((((FDT_item.mattr & cn_FS_ATTR_DIRECTORY) == 1) &&
          (__pick_little_32bit(FDT_item.fstart_dson,0)) != cn_limit_uint32))
        return false;   //目标FDT_item有子文件/目录的目录
    parent = __pick_little_32bit(FDT_item.parent,0);    //取父FDT项目号
    elder = __pick_little_32bit(FDT_item.previous,0);   //取兄FDT项目号
    less = __pick_little_32bit(FDT_item.next,0);        //取弟FDT项目号
    if(elder == less)       //兄、弟FDT项目号相等
    {
        if(elder == FDT_item_no)    //FDT_item_no是父目录下唯一的文件/目录
        {
            __DFFSD_read_FDT_item(DBX_flash_tag,parent,&FDT_item);//读父项
            //把子项号设置为没有子项
            __fill_little_32bit(FDT_item.fstart_dson,0,cn_limit_uint32);
            __DFFSD_write_FDT_item(DBX_flash_tag,parent,&FDT_item); //写父项
        }else                   //父目录下有两个文件/目录
        {
            //读出兄(弟)FDT项
            __DFFSD_read_FDT_item(DBX_flash_tag,elder,&FDT_item);
            __fill_little_32bit(FDT_item.previous,0,elder); //前指针指向自己
            __fill_little_32bit(FDT_item.next,0,elder);     //后指针指向自己
            __DFFSD_write_FDT_item(DBX_flash_tag,elder,&FDT_item);  //写回flash
            __DFFSD_read_FDT_item(DBX_flash_tag,parent,&FDT_item);  //读父项
            eldest = __pick_little_32bit(FDT_item.fstart_dson,0); //取长兄项目号
            if(eldest != elder)     //被孤立的恰好就是长兄
            {
                //设置父项的子项号
                __fill_little_32bit(FDT_item.fstart_dson,0,elder);
                __DFFSD_write_FDT_item(DBX_flash_tag,parent,&FDT_item);//写父项
            }
        }
    }else       //兄、弟项目号不相等,说明被孤立项的同级目录项至少有3个
    {
        __DFFSD_read_FDT_item(DBX_flash_tag,parent,&FDT_item);  //读父项
        eldest = __pick_little_32bit(FDT_item.fstart_dson,0);   //取长兄项号
        if(eldest == FDT_item_no)   //被孤立的恰好就是长兄
        {
            //设置父项的子项号
            __fill_little_32bit(FDT_item.fstart_dson,0,less);
            __DFFSD_write_FDT_item(DBX_flash_tag,parent,&FDT_item); //写父项
        }
        __DFFSD_read_FDT_item(DBX_flash_tag,elder,&FDT_item);   //读兄结点
        __fill_little_32bit(FDT_item.next,0,less); //兄结点的向后指针指向弟结点
        __DFFSD_write_FDT_item(DBX_flash_tag,elder,&FDT_item);  //写兄结点
        __DFFSD_read_FDT_item(DBX_flash_tag,less,&FDT_item);    //读弟结点
        //弟结点的向前指针指向弟结点
        __fill_little_32bit(FDT_item.previous,0,elder);
        __DFFSD_write_FDT_item(DBX_flash_tag,less,&FDT_item);   //写弟结点
    }
    //注意,为最大限度保留数据恢复信息,不对被孤立项做任何修改
    return true;
}

//----释放FDT_item-------------------------------------------------------------
//功能: 释放一个FDT_item到FDT表中,把它加入空闲项链表
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//      FDT_item_no,被释放的条目号
//返回: 无
//-----------------------------------------------------------------------------
void __DFFSD_free_FDT_item(struct st_DBX_flash_tag *DBX_flash_tag,
                         uint32_t FDT_item_no)
{
    struct flash_chip *chip = DBX_flash_tag->chip;
    //从目录链表中取出被操作的FDT项
    if(__DFFSD_acnode_FDT_item(DBX_flash_tag,FDT_item_no))
    {
        //把刚才取出的FDT项加入到空闲FDT链表中去
        __DFFSD_add_FDT_free_item(DBX_flash_tag,FDT_item_no);
    }
    chip->erase_block(DBX_flash_tag->PCRB_no + DBX_flash_tag->start_block);
}


//----分配FDT_item-------------------------------------------------------------
//功能:从FDT表中分配一个FDT_item,把它从空闲链表中取出。如果没有空闲FDT_item,
//      则调用DFFSD_add_FDT_block函数分配一块。
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//返回:新分配的FDT_item项号,出错则返回cn_limit_uint32
//-----------------------------------------------------------------------------
uint32_t __DFFSD_allocate_FDT_item(struct st_DBX_flash_tag *DBX_flash_tag)
{
    uint32_t next_free,next_next_free;
    struct fdt_info FDT_root,FDT_free_item;
    struct flash_chip *chip = DBX_flash_tag->chip;
    __DFFSD_read_FDT_item(DBX_flash_tag,0,&FDT_root);
    next_free = __pick_little_32bit(FDT_root.next,0);
    if(next_free >= DBX_flash_tag->FDT_capacity)
        return cn_limit_uint32;   //条目号大于FDT容量,肯定出错
    if(DBX_flash_tag->FDT_free_num == 0)
    {
        if(!__DFFSD_add_FDT_block(DBX_flash_tag))     //延长FDT表失败
            return cn_limit_uint32;
        __DFFSD_read_FDT_item(DBX_flash_tag,0,&FDT_root);   //重新读根目录项
        next_free = __pick_little_32bit(FDT_root.next,0); //重读根目录项next指针
    }
    //读取下一个空闲项,也就是即将返回给调用者的项
    __DFFSD_read_FDT_item(DBX_flash_tag,next_free,&FDT_free_item);
    //读取下下一个空闲项的编号
    next_next_free = __pick_little_32bit(FDT_free_item.next,0);
    DBX_flash_tag->FDT_free_num--;
    //FDT表根目录项的file_size指针特殊用途:前4字节记录空闲FDT表项数
    __fill_little_32bit(FDT_root.file_size,0,DBX_flash_tag->FDT_free_num);
    if(next_next_free == 0) //next_next_free指针指向第0项,这是最后一个空闲项
    {
        __fill_little_32bit(FDT_root.next,0,0);
        __fill_little_32bit(FDT_root.previous,0,0);
        if(! __DFFSD_write_FDT_item(DBX_flash_tag,0,&FDT_root))
            return cn_limit_uint32;
    }else
    {
        //读取下下一个空闲项的内容
        __DFFSD_read_FDT_item(DBX_flash_tag,next_next_free,&FDT_free_item);
        //根目录项的next指针指向下下一个空闲项的项号
        __fill_little_32bit(FDT_root.next,0,next_next_free);
        //下下一个空闲项的previous指针指向根目录项
        __fill_little_32bit(FDT_free_item.previous,0,0);
        //根目录项写入flash
        if(! __DFFSD_write_FDT_item(DBX_flash_tag,0,&FDT_root))
            return cn_limit_uint32;
        //下下一个空闲项写入flash
        if(!__DFFSD_write_FDT_item(DBX_flash_tag,next_next_free,&FDT_free_item))
            return cn_limit_uint32;
    }
    if(!__DFFSD_write_DDR(DBX_flash_tag))
        return false;
    chip->erase_block(DBX_flash_tag->PCRB_no + DBX_flash_tag->start_block);
    return next_free;
}
//----压缩FDT表----------------------------------------------------------------
//功能:当FDT表中空闲表项所占的存储器容量超过1个block时,可以调用本函数压缩之。
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//返回:无
// db 待增加
//-----------------------------------------------------------------------------
void __DFFSD_compress_FDT(struct st_DBX_flash_tag *DBX_flash_tag)
{
}

//----写一个FDT表项------------------------------------------------------------
//功能: 把一个FDT表项写入flash的FDT表中
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//      FDT_item_no,条目号
//      FDT_item,FDT表项指针
//返回: true=成功写入,false=失败,一般是遇到坏块且没有空闲块可替换。
//-----------------------------------------------------------------------------
bool_t __DFFSD_write_FDT_item(struct st_DBX_flash_tag *DBX_flash_tag,
                           uint32_t FDT_item_no,struct fdt_info *FDT_item)
{
    uint32_t true_block;
    struct flash_chip *chip;
    uint32_t block_offset,FDT_block_no,loop,FDT_block_serial;
    chip = DBX_flash_tag->chip;
    //计算FDT_item_no在fdt表中的块序号
    FDT_block_serial = FDT_item_no * sizeof(struct fdt_info) / chip->block_size;
    block_offset = FDT_item_no * sizeof(struct fdt_info) % chip->block_size;
    //读取FDT首块的块号
    FDT_block_no = DBX_flash_tag->DDR_FDSB;
    //从首块开始,沿MAT表搜索,找到第FDT_block_serial个FDT块的块号
    for(loop = 0; loop < FDT_block_serial; loop++)
        FDT_block_no = DBX_flash_tag->DDR_MAT[FDT_block_no].next;

    memcpy(chip->block_buf+block_offset,FDT_item,256);
    //写入目标块
    true_block = __DFFSD_write_update_block(DBX_flash_tag,FDT_block_no,
                                    block_offset,256);
    if(true_block != cn_limit_uint32)
    {//正确写入
        if(true_block != FDT_block_no)   //写入时发生了块替换
        {
            __DFFSD_update_MAT_item(DBX_flash_tag,FDT_block_no,true_block);
            if(! __DFFSD_write_DDR(DBX_flash_tag))
                return false;
        }
    }else       //写入错误
        return false;
    chip->erase_block(DBX_flash_tag->PCRB_no + DBX_flash_tag->start_block);
    return true;
}

//----读一个FDT表项------------------------------------------------------------
//功能: 从FDT表中读取一个表项
//参数: DBX_flash_tag,被操作的flash文件柜的存储媒体标签
//      FDT_item_no,条目号
//      FDT_item,返回数据的指针
//返回: 无
//-----------------------------------------------------------------------------
void __DFFSD_read_FDT_item(struct st_DBX_flash_tag *DBX_flash_tag,
                           uint32_t FDT_item_no,struct fdt_info *FDT_item)
{
    struct flash_chip *chip;
    uint32_t block_offset,FDT_block_abs,FDT_block_no,loop,FDT_block_serial;
    chip = DBX_flash_tag->chip;
    //计算FDT_item_no在fdt表中的块序号
    FDT_block_serial = FDT_item_no * sizeof(struct fdt_info) / chip->block_size;
    block_offset = FDT_item_no * sizeof(struct fdt_info) % chip->block_size;
    //读取FDT首块的块号
    FDT_block_no = DBX_flash_tag->DDR_FDSB;
    //从首块开始,沿MAT表搜索,找到第FDT_block_serial个FDT块的块号
    for(loop = 0; loop < FDT_block_serial; loop++)
        FDT_block_no = DBX_flash_tag->DDR_MAT[FDT_block_no].next;
    //计算FDT_block在芯片中的绝对块号
    FDT_block_abs = FDT_block_no + DBX_flash_tag->start_block;
    chip->read_data_with_ecc(FDT_block_abs,block_offset,(uint8_t*)FDT_item,256);
}

//----构造一个FDT_item---------------------------------------------------------
//功能:构造一个FDT_item的内存影像,但是没有处理构成链表的4个指针。
//参数: FDT_item,待构造的FDT条目指针
//      attr,条目属性
//      name,条目名称

⌨️ 快捷键说明

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