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

📄 mdr.c

📁 新一代基于事件的嵌入式操作系统dyos在三星的s3c44b0的arm芯片上的完整移植代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        return false;
    }
    if( ! __DFFSD_allocate_DBX(chip,size,&DBX_start))   //分配存储空间
        return false;
    strcpy(MDR_DBX->DBX_format_flag,"unready"); //格式化标志
    __fill_little_32bit(MDR_DBX->DBX_start_block,0,DBX_start);  //起始块号
    __fill_little_32bit(MDR_DBX->DBX_blocks_sum,0,size);    //文件柜尺寸(块数)
    __DFFSD_fill_ECC_MDR_DBX((uint8_t *)MDR_DBX);                 //填充ECC码
    if( ! __DFFSD_write_MDR_DBX(chip,DBX_no,MDR_DBX_buf))
        return false;

    chip->MDR.DBX_created[DBX_no] = true;
    //打开文件系统设备的右手接口
    if((fs_handle_right = dev_open_right("fs",0)) == NULL)
        return false;

    //分配文件柜设备专用数据结构内存,该结构将嵌入到反设备结构中
    DBX_device_tag = (struct st_DBX_device_tag*)
                m_malloc_gbl(sizeof(struct st_DBX_device_tag),0);
    if(DBX_device_tag == NULL)
        goto goto_exit_install_chip;
    //分配flash文件系统专用数据结构内存,该结构将嵌入到文件柜设备中
    DBX_flash_tag = (struct st_DBX_flash_tag*)
                m_malloc_gbl(sizeof(struct st_DBX_flash_tag),0);
    if(DBX_flash_tag == NULL)
        goto goto_exit_install_chip;
    DBX_flash_tag->ART_position = NULL;
    DBX_flash_tag->ART_block_no = NULL;
    DBX_flash_tag->ART_times = NULL;
    DBX_flash_tag->writed_DDR_main = NULL;
    DBX_flash_tag->writed_DDR_bak = NULL;
    DBX_flash_tag->chip = chip;         //flash文件柜存储器所属芯片
    DBX_flash_tag->DBX_no = DBX_no;     //本文件柜在芯片中的序号
    DBX_flash_tag->PCRB_no = cn_limit_uint32;   //未格式化
    DBX_flash_tag->DDR_main = cn_limit_uint32;  //未格式化
    DBX_flash_tag->DDR_bak = cn_limit_uint32;   //未格式化
    DBX_flash_tag->start_block = DBX_start;
    DBX_flash_tag->block_sum = size;
    DBX_flash_tag->nand_ecc = nand_ecc;

    table_size = DBX_flash_tag->block_sum * (4+4+2);
    //为磨损位置表分配内存
    DBX_flash_tag->ART_position = (uint32_t*)m_malloc_gbl(table_size,0);
    if(DBX_flash_tag->ART_position == NULL)
        goto goto_exit_install_chip;
    //为磨损块号表分配内存
    DBX_flash_tag->ART_block_no = DBX_flash_tag->ART_position
                                  + DBX_flash_tag->block_sum;
    //为磨损次数表分配内存
    DBX_flash_tag->ART_times = (uint16_t*)(DBX_flash_tag->ART_block_no
                                  + DBX_flash_tag->block_sum);

    //计算DDR表尺寸
    DBX_flash_tag->DDR_size = __DFFSD_calculate_DDR_size(DBX_flash_tag);
    //1份DDR表占用的块数
    DDR_blocks = (DBX_flash_tag->DDR_size
                        +chip->block_size-1)/chip->block_size;
    //申请两份DBL表所需内存
    DBX_flash_tag->DDR_DBL =(uint32_t*)m_malloc_gbl(DDR_blocks*8,0);
    if(DBX_flash_tag->DDR_DBL == NULL)
        goto goto_exit_install_chip;
    //申请MAT表所需内存
    DBX_flash_tag->DDR_MAT = (struct MAT_table *)m_malloc_gbl(
                        DBX_flash_tag->block_sum*sizeof(struct MAT_table),0);
    if(DBX_flash_tag->DDR_MAT == NULL)
        goto goto_exit_install_chip;
    //两份写入标志
    DBX_flash_tag->writed_DDR_main = (bool_t*)m_malloc_gbl(
                                        DDR_blocks*sizeof(bool_t)*2,0);
    if(DBX_flash_tag->writed_DDR_main == NULL)
        goto goto_exit_install_chip;
    DBX_flash_tag->writed_DDR_bak=DBX_flash_tag->writed_DDR_main+DDR_blocks;

    //填充函数指针和文件柜名
    __DFFSD_fill_DBX_device_tag(DBX_device_tag,name);
    //文件柜设备的存储媒体指向flash文件柜存储器
    DBX_device_tag->DBX_medium_tag = (ptu32_t)DBX_flash_tag;
    DBX_device_tag->formatted =false;
    semp_dbx.left = chip->left_semaphore;   //芯片的左手信号量
    semp_dbx.right = chip->right_semaphore; //芯片的右手信号量
    if(dev_ctrl(fs_handle_right,enum_fs_add_DBX,
                        (ptu32_t)DBX_device_tag,(ptu32_t)&semp_dbx)
                        != enum_fs_no_error)
    {
        goto goto_exit_install_chip;
    }
    //这是正常出口
    dev_close_right(fs_handle_right);     //关闭文件系统设备
    return true;
goto_exit_install_chip:
    dev_close_right(fs_handle_right);     //关闭文件系统设备
    if(DBX_flash_tag !=NULL)
    {
        if(DBX_flash_tag->writed_DDR_main != NULL)
            m_free(DBX_flash_tag->writed_DDR_main);
        if(DBX_flash_tag->DDR_MAT != NULL)
            m_free(DBX_flash_tag->DDR_MAT);
        if(DBX_flash_tag->DDR_DBL != NULL)
            m_free(DBX_flash_tag->DDR_DBL);
        if(DBX_flash_tag->DDR_DBL != NULL)
            m_free(DBX_flash_tag->DDR_DBL);
        if(DBX_flash_tag->ART_position != NULL)
            m_free(DBX_flash_tag->ART_position);
        m_free(DBX_flash_tag);
    }
    if(DBX_device_tag !=NULL)   m_free(DBX_device_tag);
    return false;      //文件柜加入到设备树失败
}

//----查找MDR_bak的块号--------------------------------------------------------
//功能: 在读MDR_main失败,无法从中获取MDR_bak的块号时,根据芯片的块尺寸计算
//      MDR_bak可能的存放位置。当用本函数确定块号时,应该从该块号开始连续查找
//      5块,直到找到合法的MDR_bak块为止,如果5块都未能找到合法的MDR_bak,则认为
//      本flash没有按照djyosfs初始化过。
//参数: chip,目标芯片
//返回: 块号,0表示没有找到
//-----------------------------------------------------------------------------
uint32_t __DFFSD_probe_MDR_bak(struct flash_chip *chip)
{
    //db 没有考虑坏块,以后补充。
    return (cn_MDR_size+chip->block_size-1) / chip->block_size;
}
//----校验MDR_CDR--------------------------------------------------------------
//功能: 校验MDR_CDR,并改正的数据,如果不能改正,返回错误
//参数: buf,保存有未校验的MDR_CDR数据的缓冲区
//返回: true=无错或者被修正,false=有错并且不能改正。
//-----------------------------------------------------------------------------
bool_t __DFFSD_verify_MDR_CDR(uint8_t *buf)
{
    return true;
}
//----校验MDR_DBX--------------------------------------------------------------
//功能: 校验MDR_DBX,并改正的数据,如果不能改正,返回错误
//参数: buf,保存有未校验的MDR_DBX数据的缓冲区
//返回: true=无错或者被修正,false=有错并且不能改正。
//-----------------------------------------------------------------------------
bool_t __DFFSD_verify_MDR_DBX(uint8_t *buf)
{
    return true;
}

//----校验MDR结束标志----------------------------------------------------------
//功能: 1.校验MDR表的最后4个字节是否AA5555AA,最多只允许一位不符。
//      2.校验CDR和DBX表的ECC
//参数: buf,字节缓冲区
//返回: true=校验正确,false=错误
//-----------------------------------------------------------------------------
//特别注意,对齐问题/大小端问题/最小寻址单元大于8位问题,这些问题使得不能把
//AA5555AA组成32位整数来比较
bool_t __DFFSD_verify_end_flag(uint8_t *buf)
{
    uint8_t temp[4] = {0xAA,0x55,0x55,0xAA};
    uint8_t xor;
    ufast_t loop4,loop8,error_bit = 0;
    for(loop4 = 0; loop4 < 4; loop4++)
    {
        if(buf[loop4] != temp[loop4])
        {
            xor = buf[loop4] ^ temp[loop4];
            for(loop8 = 0; loop8 < 8; loop8++)
            {
                if(xor & (1<<loop8))
                    error_bit ++;
                if(error_bit > 1)
                    return false;
            }
        }else
            continue;
    }
    if(! __DFFSD_verify_MDR_CDR(buf))
        return false;
    if(! __DFFSD_verify_MDR_DBX(buf))
        return false;
    return true;
}

//----MDR滚动记录ECC校验-------------------------------------------------------
//功能: MDR中滚动存储的记录进行ECC校验,并改正数据。
//参数: buf,记录指针
//返回: 0=无错,1=有错但被修正,2=无法修正
//-----------------------------------------------------------------------------
uint32_t __DFFSD_verify_MDR_record(uint8_t *buf)
{
    return 0;
}

//----扫描滚动存储区-----------------------------------------------------------
//功能: 扫描滚动存储缓冲区,读取已经格式化的文件柜的DDR_main块号、DDR_bak块号、
//      PCRB块号。
//参数: chip,被操作的芯片
//      MDR_buf,缓冲区
//      MDR_record,返回扫描到的数据的指针
//      end_offset,最后一条有效记录位置
//返回: 无
//-----------------------------------------------------------------------------
void __DFFSD_uasm_roll(struct flash_chip *chip,uint8_t *MDR_buf,
                       struct MDR_temp_record *MDR_record,uint32_t end_offset)
{
    uint8_t *record;
    uint32_t loop,loop3,item_sum=0;
    bool_t got_DDR_main[cn_DBX_sum_max];//各文件柜DDR_main块号是否找到标志
    bool_t got_DDR_bak[cn_DBX_sum_max]; //各文件柜DDR_bak块号是否找到标志
    bool_t got_PCRB[cn_DBX_sum_max];    //各文件柜PCRB块号是否找到标志

    for(loop3 = 0; loop3 < cn_DBX_sum_max; loop3++)
    {
        got_DDR_main[loop3] = false;
        got_DDR_bak[loop3] = false;
        got_PCRB[loop3] = false;
        if(MDR_record->formatted[loop3])
        {
            item_sum +=3;   //每个已经格式化的文件柜都有3条滚动记录
        }
    }
    //循环扫描所有滚动存储区的有效条目。
    for(loop = end_offset-8;loop >= cn_roll_offset; loop-=8)
    {
        record = MDR_buf + loop;
        for(loop3 = 0; loop3 < cn_DBX_sum_max; loop3++)
        {
            if(! MDR_record->formatted)     //文件柜未格式化
                continue;
            __DFFSD_verify_MDR_record(record); //校验该记录---db,校验错误怎么办?
            if(!got_DDR_main[loop3])        //DDR_main滚动记录还未找到
            {
                //检查本项目是不是第loop个文件柜的DDR_main块号
                if((record[0] == cn_MDR_DDR_main) && (record[1] == loop3))
                {
                    item_sum--;                 //找到,剩余项目数减量
                    got_DDR_main[loop3] = true;  //标记该DDR_main块号项已找到
                    //将结果写入返回的结构指针中
                    MDR_record->DDR_main_block_no[loop3]
                            = __pick_little_32bit(&record[2],0);
                    break;
                }
            }
            if(!got_DDR_bak[loop3])         //DDR_bak滚动记录还未找到
            {
                //检查本项目是不是第loop个文件柜的DDR_bak块号
                if((record[0] == cn_MDR_DDR_bak) && (record[1] == loop3))
                {
                    item_sum--;                 //找到,剩余项目数减量
                    got_DDR_bak[loop3] = true;  //标记该DDR_bak块号项已找到
                    //将结果写入返回的结构指针中
                    MDR_record->DDR_bak_block_no[loop3]
                                    = __pick_little_32bit(&record[2],0);
                    break;
                }
            }
            if(!got_PCRB[loop3])                //PCRB滚动记录还未找到
            {
                //检查本项目是不是第loop个文件柜的PCRB块号
                if((record[0] == cn_MDR_PCRB) && (record[1] == loop3))
                {
                    item_sum--;                 //找到,剩余项目数减量
                    got_PCRB[loop3] = true;  //标记该PCRB块号项已找到
                    //将结果写入返回的结构指针中
                    MDR_record->PCRB_block_no[loop3] =
                                __pick_little_32bit(&record[2],0);
                    break;
                }
            }
        }
        if(item_sum == 0)   //剩余项目为0,表明需要找的项目已经全部找到
            break;
    }
}

//----检查MDR_bak的完整性------------------------------------------------------
//功能: 检查MDR_bak是否完整,是否因上次掉电时正在写入而导致不完整,方法是检查
//      尾部的AA5555AA,以及最后一条滚动记录的校验码
//参数: chip,目标芯片
//返回: true=完整,false=不完整
//-----------------------------------------------------------------------------
bool_t __DFFSD_check_MDR_bak(struct flash_chip *chip)
{
    uint8_t MDR_buf[cn_MDR_size];
    __DFFSD_read_MDR_bak(chip,MDR_buf);
    return (__DFFSD_verify_end_flag(MDR_buf));
}

//----检测滚动区结束位置-------------------------------------------------------
//功能: 检测滚动存储区第一个空闲记录的偏移量,用折半查找方法
//参数: chip,目标芯片
//      MDR_buf,MDR表缓冲区
//返回: 偏移量
//-----------------------------------------------------------------------------
uint32_t __DFFSD_find_roll_next(struct flash_chip *chip,uint8_t *MDR_buf)
{
    uint32_t busy_endian,free_endian,middle,result;
    uint32_t block_offset;
    busy_endian = cn_roll_offset/8;
    free_endian = cn_MDR_size /8 -1;   //最后一项用于完整性标记
    while(1)
    {
        middle = (busy_endian+free_endian)/2; //计算中间项
        block_offset = 8*middle;
        //测试第block_no块偏移block_offset开始的8字节是否擦除后未使用过。
        //虽然至今所知的flash都可以用是否等于0xff来判断是否擦除,但datasheet
        //上并没有这样说,难保哪天不会出来一个不是这样的,故把判断交给芯片
        //driver才可确保可移植性。
        if(chip->query_ready_with_data(NULL,MDR_buf+block_offset,8))
        {//第middle单元是空闲的
            if(middle == busy_endian)
            {
                result = middle*8;
                break;
            }else
                free_endian = middle;
        }else
        {//第middle单元是已经使用了的

⌨️ 快捷键说明

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