📄 fdt.c
字号:
//根目录项的向前指针均指向目标项
__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 + -