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

📄 flashfile.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 5 页
字号:
//功能:查询一个文件内有多少可读数据,对于固态文件(如flash文件)来说,就是文件
//      长度-当前指针,但流的标准定义并非一定如此,比如通信端子。而且,文件读写
//      指针如何表示与具体文件系统驱动的实现有关,文件系统的核心程序不应该做任何
//      假设。
//参数:fp,被操作的文件指针
//返回:文件可读数据的字节数
//-----------------------------------------------------------------------------
sint64_t DFFSD_query_file_stocks(struct file_rsc *fp)
{
    struct st_DBX_device_tag *DBX_device_tag;
    struct st_DBX_flash_tag *DBX_flash_tag;
    struct fdt_info FDT_item;
    if(fp == NULL)
        return 0;
    DBX_device_tag = (struct st_DBX_device_tag *)(fp->home_DBX->private_tag);
    DBX_flash_tag = (struct st_DBX_flash_tag*)DBX_device_tag->DBX_medium_tag;
    __DFFSD_read_FDT_item(DBX_flash_tag,
                          (uint32_t)fp->file_medium_tag,&FDT_item);
    if(FDT_item.mattr & cn_FS_ATTR_DIRECTORY)
        return 0;       //目录不能读
    return fp->file_size - fp->read_ptr;
}


//----查询文件可写数据量-------------------------------------------------------
//功能:查询一个文件还能写入多少数据,对于固态文件(如flash文件),可能就是文件
//      柜的剩余空间,但流的标准定义并非一定如此,比如通信端子。而且,文件柜剩余
//      空间如何表示与具体文件系统驱动的实现有关,文件系统的核心程序不应该做任何
//      假设。不能认为DBX_flash_tag->free_sum就是文件仍可写入的数据量。
//      flash文件系统的计算方式是:
//      1、文件已分配的块的容量-文件尺寸。
//      2、加上文件柜剩余空间DBX_flash_tag->free_sum。
//      3、减去文件缓冲区中已有的数据量
//参数:fp,被操作的文件指针
//返回:文件还能写入的字节数
//-----------------------------------------------------------------------------
sint64_t DFFSD_query_file_cubage(struct file_rsc *fp)
{
    struct st_DBX_device_tag *DBX_device_tag;
    struct st_DBX_flash_tag *DBX_flash_tag;
    struct flash_chip *chip;
    struct fdt_info FDT_item;
    if(fp == NULL)
        return 0;
    DBX_device_tag = (struct st_DBX_device_tag *)(fp->home_DBX->private_tag);
    DBX_flash_tag = (struct st_DBX_flash_tag*)DBX_device_tag->DBX_medium_tag;
    chip = DBX_flash_tag->chip;
    __DFFSD_read_FDT_item(DBX_flash_tag,
                          (uint32_t)fp->file_medium_tag,&FDT_item);
    if((FDT_item.mattr & cn_FS_ATTR_READ_ONLY)
                || (FDT_item.mattr & cn_FS_ATTR_DIRECTORY))
        return 0;       //只读文件或目录不能写入
/*
    //取文件尺寸
    size = __pick_little_32bit(FDT_item.file_size,0)
            +((uint64_t)__pick_little_32bit(FDT_item.file_size,1)<<32);
    if(size == 0)   //根据文件至少占用一块的原则,0尺寸文件也已经分配了一块
        size = chip->block_size;
    else
    {
        //文件必须占用整数块,下面计算已经分配但未使用的空间
        size = chip->block_size - size % chip->block_size;
        if(size == chip->block_size)
            size = 0;
    }
    buffed_size = ring_check(fp->p_write_buf);
*/      //本段为什么会被注释掉,当初漏了注释,先别删吧。

    return DBX_flash_tag->free_sum * chip->block_size;  // - buffed_size + size;
}

//----设置文件长度-------------------------------------------------------------
//功能:设置文件长度,短于实际长度将截尾,长于实际长度将追加空间。本函数的主要
//      作用在于在正式写入数据之前,预先分配存储器。
//参数:fp,被操作的文件指针
//      new_size,新的文件长度。
//返回:新的文件长度,若与new_size参数不等,一般是因为文件柜没有足够的容量导致
//-----------------------------------------------------------------------------
sint64_t __DFFSD_set_file_size(struct file_rsc *fp,sint64_t new_size)
{
    struct st_DBX_device_tag *DBX_device_tag;
    sint64_t result,temp;
    uint32_t origin_blocks,new_blocks,last_block_no,next_block_no;
    uint32_t loop;
    struct st_DBX_flash_tag *DBX_flash_tag;
    struct flash_chip *chip;
    struct fdt_info FDT_item;
    //读父目录的FDT_item
    if(fp == NULL)
        return 0;
    if(new_size == fp->file_size)
        return new_size;    //新的文件长度与原长度相等,直接返回。
    DBX_device_tag = (struct st_DBX_device_tag *)(fp->home_DBX->private_tag);
    DBX_flash_tag = (struct st_DBX_flash_tag*)DBX_device_tag->DBX_medium_tag;
    chip = DBX_flash_tag->chip;
    __DFFSD_read_FDT_item(DBX_flash_tag,
                          (uint32_t)fp->file_medium_tag,&FDT_item);
    if((FDT_item.mattr & cn_FS_ATTR_READ_ONLY)
                || (FDT_item.mattr & cn_FS_ATTR_DIRECTORY))
        return 0;       //只读文件或目录不能执行设置长度的操作
    //下面两个if用于确定原文件占用的块数和新文件长度所需的块数
    if(fp->file_size == 0)
        origin_blocks = 1;
    else
        origin_blocks = (fp->file_size + chip->block_size -1)/chip->block_size;
    if(new_size < 0)
        new_size = 0;
    if(new_size == 0)
        new_blocks = 1;
    else
        new_blocks = (new_size + chip->block_size -1)/chip->block_size;
    last_block_no = __DFFSD_last_block(DBX_flash_tag,fp);
    if(origin_blocks < new_blocks)     //文件占用块数需增加
    {
        for(loop = origin_blocks; loop < new_blocks; loop++)
        {
            next_block_no = __DFFSD_allocate_block(DBX_flash_tag);
            if(next_block_no != cn_limit_uint32)
            {
                __DFFSD_add_MAT_item(DBX_flash_tag,last_block_no,next_block_no);
                last_block_no = next_block_no;
            }else
                break;
        }
        if(loop == new_blocks)
            result = new_size;
        else
            result = (sint64_t)loop * chip->block_size;
    }else if(origin_blocks > new_blocks)     //文件占用块数需减少
    {
        result = new_size;
        for(loop = origin_blocks; loop > new_blocks; loop--)
        {
            next_block_no = last_block_no;
            last_block_no = DBX_flash_tag->DDR_MAT[next_block_no].previous;
            __DFFSD_free_block(DBX_flash_tag,next_block_no);
        }
        //最后一块的向后指针指向自己
        DBX_flash_tag->DDR_MAT[last_block_no].next = last_block_no;
    }else           //占用块数不变
        result = new_size;
    fp->file_size = result;
    //以下处理读写缓冲区,但并不处理读写指针,仅把非法指针(因文件缩短而超出文件
    //长度的指针位置)移到合法位置。
    if(fp->p_read_buf != NULL)      //读缓冲区指针非空,说明有读缓冲区
    {
        if(fp->read_ptr > result)   //读指针在文件尺寸后面
        {
            ring_flush(fp->p_read_buf); //清空读缓冲区
            fp->read_ptr = result;      //读指针回到文件末
        }else
        {
            temp = fp->read_ptr + ring_check(fp->p_read_buf);
            //读指针未超出文件长度但读缓冲区中数据超出文件长度,将超出部分砍掉
            if(temp > result)
            {
                ring_skip_tail(fp->p_read_buf,temp-result);
            }
        }
    }
    if(fp->p_write_buf != NULL)     //写缓冲区指针非空,说明有写缓冲区
    {
        if(fp->write_ptr > result)  //写指针超出文件长度
        {
            temp = result - fp->write_ptr;  //计算超出数量
            ring_skip_tail(fp->p_write_buf,temp);   //砍掉超出文件长度的并且可能
                                                    //还在缓冲区中的数据。
            fp->write_ptr = result; //写指针回到文件末
        }else
        {
            //写指针没有超出文件长度,无需处理
        }
    }
   __DFFSD_update_FDT_file_size(DBX_flash_tag,fp,result);
   __DFFSD_write_DDR(DBX_flash_tag);   //可能修改DDR,写入flash
    return result;
}

//----设置文件指针-------------------------------------------------------------
//功能:把文件指针设置到指定的位置,并相应地同步读写缓冲区。
//参数:fp,被操作的文件指针
//      offset,移动的位置
//      whence,从何处开始计算移动长度,参见SEEK_CUR等的定义
//返回:0=成功,1=失败
//-----------------------------------------------------------------------------
uint32_t DFFSD_seek_file(struct file_rsc *fp,struct seek_para *position)
{
    struct st_DBX_device_tag *DBX_device_tag;
    struct st_DBX_flash_tag *DBX_flash_tag;
    sint64_t new_position,temp;
    uint32_t buffed_size;
    uint8_t  whence;
    if((position == NULL) ||(fp == NULL))
        return 1;
    DBX_device_tag = (struct st_DBX_device_tag *)(fp->home_DBX->private_tag);
    whence = position->whence;
    DBX_flash_tag = (struct st_DBX_flash_tag*)DBX_device_tag->DBX_medium_tag;
    switch (fp->open_mode)
    {
        case enum_r_rb:           //只读文件,需移动读指针和读缓冲区
        case enum_a_ab_plus:      //写追加方式,写指针不能变,读指针的方式与
                                //只读文件一致
        {
            if(whence == SEEK_SET)
                new_position = position->offset;
            else if(whence == SEEK_CUR)
                new_position = position->offset + fp->read_ptr;
            else if(whence == SEEK_END)
                new_position = fp->file_size + position->offset;
            temp = new_position - fp->read_ptr;
            buffed_size = ring_check(fp->p_read_buf);
            if((temp > 0) && (temp < buffed_size))
                //往后移且移动量比缓冲区中的数据少
                ring_dumb_read(fp->p_read_buf,(ptu32_t)temp);
            else
                ring_flush(fp->p_read_buf);//往前移或者移动量大于缓冲区中数据量
            if(new_position > fp->file_size)
                fp->read_ptr = fp->file_size;
            else if(new_position < 0)
                fp->read_ptr = 0;
            else
                fp->read_ptr = new_position;
        }break;
        case enum_w_wb:   //只写文件,需移动写指针
        {
            __DFFSD_write_buf_to_flash(DBX_flash_tag,fp);
            if(whence == SEEK_SET)
                new_position = position->offset;
            else if(whence == SEEK_CUR)
                new_position = position->offset + fp->write_ptr;
            else if(whence == SEEK_END)
                new_position = fp->file_size - position->offset;
            if(new_position > fp->file_size)
            {
                //延长文件,分配更多存储器,但不填充新增加的存储器
                if(__DFFSD_set_file_size(fp,new_position) != new_position)
                    return 1;
                else
                {
                    fp->write_ptr = new_position;   //设置写指针
                }
            }else if(new_position < 0)
                fp->write_ptr = 0;
            else
                fp->write_ptr = new_position;
        }break;
        case enum_a_ab:   //追加写方式,seek操作无效
        {
        }break;
        case enum_r_rb_plus:  //这两者都是可读写方式,读写指针重合,处理方式相同
        case enum_w_wb_plus:
        {
            if(whence == SEEK_SET)
                new_position = position->offset;
            else if(whence == SEEK_CUR)
                new_position = position->offset + fp->read_ptr;
            else if(whence == SEEK_END)
                new_position = fp->file_size + position->offset;
            __DFFSD_write_buf_to_flash(DBX_flash_tag,fp);//写缓冲区数据必须写入

            if(new_position > fp->file_size)    //新位置超出文件长度
            {
                //延长文件,分配更多存储器,但不初始化新增加的存储器
                if(__DFFSD_set_file_size(fp,new_position) != new_position)
                    return 1;
                else
                {
                    fp->write_ptr = new_position;   //设置写指针
                    fp->read_ptr = new_position;    //设置读指针
                }
            }else if(new_position < 0)  //新位置小于0,设为0
     

⌨️ 快捷键说明

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