zoukankan      html  css  js  c++  java
  • 一种比较简单的在USB U盘中访问nandflash的方法

     

     

    u8 nandflash_write_buffer[NAND_SERECT_FULL_SIZE];

    static int currentBlock = -1;

    static int currentPage = -1;

     

    //带缓冲的nand读取,不支持跨扇区

    void NAND_Read_Addr_Mal(u32 addr,u8* buffer,u32 length)

    {

        u32 i = 0;

        u32 readBlock = ((addr/NAND_SERECT_SIZE)/NAND_PAGE_NUM);//获取要写入的块

        u32 readPage = ((addr/NAND_SERECT_SIZE)%NAND_PAGE_NUM);//获取要写入的页面

        u32 readoffset = (addr%NAND_SERECT_SIZE);//写入位置偏移

       

        u32 readPageCount = ((length + readoffset)/NAND_SERECT_SIZE);//获取一共需要写入的页

        if(((length + readoffset)%NAND_SERECT_SIZE) != 0)readPageCount++;//比如刚好2048的时候,就还是在一页

       

        if(readPageCount == 1)//仅读取一个快

        {

            //先检查当前需要读取的数据是不是在缓冲区中

            if(currentBlock >= 0 && currentPage >= 0)

            {

                if(readBlock == currentBlock && readPage == currentPage)

                {

                    //在缓冲区中读取数据

                    for(i = 0; i < length; i++)

                    {

                        buffer[i] = nandflash_write_buffer[readoffset+i];

                    }

                }

                else

                {

                    //在物理设备中读取数据

                    NAND_Read_Random_Page(readBlock,readPage,readoffset,buffer,length);

                }

            }

            else if(currentBlock == -1 && currentPage == -1)

            {

                //缓冲区为空,直接进行物理读取

                NAND_Read_Random_Page(readBlock,readPage,readoffset,buffer,length);

            }

        }

        else

        {

    //      printf("2 or up sector not vailed ");

        }

    }

     

    //带缓冲nand写入,不支持跨扇区

    void NAND_Write_Addr_Mal(u32 addr,u8* buffer,u32 length)

    {

        u32 writeBlock = (addr/NAND_SERECT_SIZE)/NAND_PAGE_NUM; //获取要写入的块

        u32 writePage = (addr/NAND_SERECT_SIZE)%NAND_PAGE_NUM;  //获取要写入的页面

        u32 writeoffset = (addr%NAND_SERECT_SIZE);              //写入位置偏移

        u32 i = 0;

        u32 copy;

       

        if(currentBlock >= 0 && currentPage >= 0)

        {

            if(currentBlock == writeBlock && currentPage == writePage)//没有切换页面,那么数据更新依旧在缓存中

            {

                for(i = writeoffset; i < writeoffset+length ;i++)

                {

                    nandflash_write_buffer[i] = buffer[i-writeoffset];

                }

            }

            else

            {

                //更新了页面的写入,先将缓存中数据写入物理设备,进行新的一轮缓存操作

                copy = (currentBlock/42)+NAND_COPYBACL_BLOCK_START;

                //擦除交换分区

                NAND_Erase_Block(copy);

                for(i = 0; i < NAND_PAGE_NUM;i++)//拷贝数据到交换分区

                {

                    if(i != currentPage)

                    {

                        NAND_Copy_Back_Page(currentBlock,i,copy,i);

                    }

                }

                //擦除源分区

                NAND_Erase_Block(currentBlock);

                //将原来数据拷贝回去

                for(i = 0; i < NAND_PAGE_NUM;i++)//拷贝数据到交换分区

                {

                    if(i != currentPage)

                    {

                        NAND_Copy_Back_Page(copy,i,currentBlock,i);

                    }

                }

                //将缓存数据拷贝到目的分区

                NAND_Write_Page_full(currentBlock,currentPage,NAND_SERECT_FULL_SIZE,nandflash_write_buffer);

                //到这里缓存的写入物理设备完成,接下来开始新一轮缓存

                NAND_Read_Full_Page(writeBlock,writePage,nandflash_write_buffer,NAND_SERECT_FULL_SIZE);

                currentBlock = writeBlock;

                currentPage = writePage;//更新标记

                //接下来更新数据,数据更新在缓存中进行,切换的时候写入

                for(i = writeoffset; i < writeoffset+length ;i++)

                {

                    nandflash_write_buffer[i] = buffer[i-writeoffset];

                }

            }

        }

        else if(currentBlock == -1 && currentPage == -1)//当前缓存包里面没有数据

        {

            //从nand中读出来

            NAND_Read_Full_Page(writeBlock,writePage,nandflash_write_buffer,NAND_SERECT_FULL_SIZE);

            currentBlock = writeBlock;

            currentPage = writePage;//更新标记

            //接下来更新数据,数据更新在缓存中进行,切换的时候写入

            for(i = writeoffset; i < writeoffset+length ;i++)

            {

                nandflash_write_buffer[i] = buffer[i-writeoffset];

            }

           

        }

    }

     

    void Nand_Flush(void)   //nand缓冲区刷入设备

    {

        u32 copy;

        u32 i = 0;

        //将还没有写入的数据刷新到nand中,标记归零

        if(currentBlock >= 0 && currentPage >= 0)

        {

            //更新了页面的写入,先将缓存中数据写入物理设备,进行新的一轮缓存操作

            copy = (currentBlock/42)+NAND_COPYBACL_BLOCK_START;

            //擦除交换分区

            NAND_Erase_Block(copy);

            for(i = 0; i < NAND_PAGE_NUM;i++)//拷贝数据到交换分区

            {

                if(i != currentPage)

                {

                    NAND_Copy_Back_Page(currentBlock,i,copy,i);

                }

            }

            //擦除源分区

            NAND_Erase_Block(currentBlock);

            //将原来数据拷贝回去

            for(i = 0; i < NAND_PAGE_NUM;i++)//拷贝数据到交换分区

            {

                if(i != currentPage)

                {

                    NAND_Copy_Back_Page(copy,i,currentBlock,i);

                }

            }

            //将缓存数据拷贝到目的分区

            NAND_Write_Page_full(currentBlock,currentPage,NAND_SERECT_FULL_SIZE,nandflash_write_buffer);

           

            currentBlock = -1;

            currentPage = -1;

        }

    }

    结合之前写的USB做U盘的例子来看,能降低写文件的时候的擦除次数

  • 相关阅读:
    Python爬虫框架Scrapy
    继承
    c/c++面试题(7)零碎知识总结
    Linux网络编程(多人在线聊天系统)
    第一章 计算机系统漫游
    Linux网络编程(简单的时间获取服务器)
    虚函数(1)
    c/c++面试题(9)linux方向
    Linux网络编程的一般步骤(1)
    进程/线程介绍
  • 原文地址:https://www.cnblogs.com/dengxiaojun/p/4338718.html
Copyright © 2011-2022 走看看