一种比较简单的在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 \r\n");
}
}
//带缓冲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盘的例子来看,能降低写文件的时候的擦除次数
一种比较简单的在USB U盘中访问nandflash的方法的更多相关文章
- 一种基于自定义代码的asp.net网站访问IP过滤方法!
对于一些企业内部核心系统,特别是外网访问的时候,为了信息安全,可能需要对外部访问的IP地址作限制,虽然IIS中也提供了根据IP地址或IP地址段进行限制或允许,但并没有提供根据IP地址所在的城市进行限制 ...
- CSharpGL(40)一种极其简单的半透明渲染方法
CSharpGL(40)一种极其简单的半透明渲染方法 开始 这里介绍一个实现半透明渲染效果的方法.此方法极其简单,不拖累渲染速度,但是不能适用所有的情况. 如下图所示,可以让包围盒显示为半透明效果. ...
- I.MX6 简单电路模拟USB设备的插入
/**************************************************************************** * I.MX6 简单电路模拟USB设备的插入 ...
- 用 Java 技术创建 RESTful Web (服务 JAX-RS:一种更为简单、可移植性更好的替代方式)
作者: Dustin Amrhein, 软件工程师, IBM Nick Gallardo, 软件工程师, IBM 出处: http://www.ibm.com/developerworks/cn/we ...
- [1.6W字] 浏览器跨域请求限制的详细原理分析&寻找一种最简单的方式实现XHR跨域(9种方法, 附大招可以纯前端实现跨域!)
Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...
- 自己实现简单的AOP(二)引入Attribute 为方法指定增强对象
话续前文 : 自己实现简单的AOP(一)简介 在前一篇文章中,对AOP的实现方式做了一个简单介绍.接下来,引入Attribute 为方法指定增强对象,由此实现一个简单的AOP. 注意:指定的是增强对象 ...
- 一种面向云服务的UCON多义务访问控制方法及系统
)设置每一云服务的义务项:建立每一云服务所包含的义务图:2)根据用户所请求的云服务查找该云服务的所有强制义务图和可选义务图,并提取该用户对该云服务的历史完成情况:3)对每一强制义务图,监控其每一义务项 ...
- USB2.0协议学习笔记---USB工作过程(类的方法)
前面学习了那么多的概念,这里需要记住一点分层概念即设备 ---> 配置 ---> 接口 ---> 端点,这种分层的概念结构 . 也可以理解为端点构成接口,接口组成配置,配置组成设备. ...
- macbook pro的usb串口失效的的处理方法
macbook pro的usb串口失效的的处理方法 2011-08-24 12:14:32| 分类: mac|举报|字号 订阅 今天开电脑,无端端一个usb的串口失效了,接入鼠标 iphon ...
随机推荐
- sql/plus 常用操作
一.sys用户和system用户Oracle安装会自动的生成sys用户和system用户(1).sys用户是超级用户,具有最高权限,具有sysdba角色,有create database的权限,该用户 ...
- A New Change Problem
题目链接 /* 给定两个互质的数,a,b,求这两个数不能表示的数的最大值和个数. 最大值=a*b-a-b; 个数 =(a-1)*(b-1)/2; */ #include <set> #in ...
- OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰)
OpenCV4Android释疑: 透析Android以JNI调OpenCV的三种方式(让OpenCVManager永不困扰) 前文曾详细探讨了关于OpenCV的使用,原本以为天下已太平.但不断有人反 ...
- hdu 1535 Invitation Cards(SPFA)
Invitation Cards Time Limit : 10000/5000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other) T ...
- cocos2d-x 3.10 显示Box2d 调试视图
1.将cocos2d-x-3.10\tests\cpp-tests\Classes\Box2DTestBed目录下的GLES-Render.h和GLES-Render.cpp拷贝到当前项目的Class ...
- 使用libvirt做适配的kvm虚拟机window server 2008 磁盘性能的提升
实验室自己做了一个iaas的项目,当时是为了更方面的在kvm和xen下进行迁移,所以选择了libvirt作为适配层. 昨天简单的测试一了一下我们跟qingcloud的性能对比.我们的linux主机性能 ...
- [JAR包] android引入JAR包,打包成JAR包,打包成Library项目,导入Library项目
(1)项目导入JAR包:1.在项目目录里建立一个libs目录,将外部jar包拷贝在里面.2.右键点击项目,Bulid Path->Configure Build Path3.在设置Libraie ...
- USACO Section 1.4 Arithmetic Progressions 解题报告
题目 题目描述 现在给你一个数集,里面的数字都是由p^2+q^2这种形式构成的0 <= p,q <= M,我现在需要你在其中找出一个长为N的等差数列,数列中的第一个数字为a,公差为b,当你 ...
- 剑指offer 判断树是不是对称的
html, body { font-size: 15px; } body { font-family: Helvetica, "Hiragino Sans GB", 微软雅黑, & ...
- MySQL查询order by相减select相减的Sql语句
先看一张表 create_time是订单创建时间,pay_time是支付时间 现在我想按照订单完成耗时的时间进行排序,并且取出来的数据中直接算好了差值,怎么用Sql呢,请看 select id,tid ...