关于uboot下cp.b如果两个地址同为flash地时,buffer无法正常写的原因
来源:互联网 发布:网络诈骗的种类有哪些 编辑:程序博客网 时间:2024/05/01 03:58
第一、cp.b命令说明
cp [.b, .w, .l] source target count
- copy memory
cp命令可以在内存中复制数据块,包括对Flash的读写操作。
第1个参数source是要复制的数据块起始地址。
第2个参数target是数据块要复制到的地址。这个地 址如果在Flash中, 那么会直接调用写Flash的函数操作。所以U-Boot写Flash就使用这个命令,当然需要先把对应Flash区域擦干净。
第3个参数count是要复制的数目,根据cp.b cp.w cp.l分别以字节、字、长字为单位。
第二、一般我们在用这个命令时第一个参数一般为sdram的地址空间,这时我们调用这个命令是可以正常操作的,但是如果第一个参数如果是片外norflash的地址,钱对不同的norflash就有问题了,会发现如果count大于1时,写入norflash的数据是不对的。这是为什么呢?根本的原因要看一下这个flash的底层写函数如下:static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp, int len)
{
flash_sect_t sector;
int cnt;
int retcode;
void *src = cp;
void *dst = (void *)dest;
void *dst2 = dst;
int flag = 1;
uint offset = 0;
unsigned int shift;
uchar write_cmd;
switch (info->portwidth) {
case FLASH_CFI_8BIT:
shift = 0;
break;
case FLASH_CFI_16BIT:
shift = 1;
break;
case FLASH_CFI_32BIT:
shift = 2;
break;
case FLASH_CFI_64BIT:
shift = 3;
break;
default:
retcode = ERR_INVAL;
goto out_unmap;
}
cnt = len >> shift;
while ((cnt-- > 0) && (flag == 1)) {
switch (info->portwidth) {
case FLASH_CFI_8BIT:
flag = ((flash_read8(dst2) & flash_read8(src)) ==
flash_read8(src));
src += 1, dst2 += 1;
break;
case FLASH_CFI_16BIT:
flag = ((flash_read16(dst2) & flash_read16(src)) ==
flash_read16(src));
src += 2, dst2 += 2;
break;
case FLASH_CFI_32BIT:
flag = ((flash_read32(dst2) & flash_read32(src)) ==
flash_read32(src));
src += 4, dst2 += 4;
break;
case FLASH_CFI_64BIT:
flag = ((flash_read64(dst2) & flash_read64(src)) ==
flash_read64(src));
src += 8, dst2 += 8;
break;
}
}
if (!flag) {
retcode = ERR_NOT_ERASED;
goto out_unmap;
}
src = cp;
sector = find_sector (info, dest);
switch (info->vendor) {
case CFI_CMDSET_INTEL_PROG_REGIONS:
case CFI_CMDSET_INTEL_STANDARD:
case CFI_CMDSET_INTEL_EXTENDED:
write_cmd = (info->vendor == CFI_CMDSET_INTEL_PROG_REGIONS) ?
FLASH_CMD_WRITE_BUFFER_PROG : FLASH_CMD_WRITE_TO_BUFFER;
flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd (info, sector, 0, FLASH_CMD_READ_STATUS);
flash_write_cmd (info, sector, 0, write_cmd);
retcode = flash_status_check (info, sector,
info->buffer_write_tout,
"write to buffer");
if (retcode == ERR_OK) {
/* reduce the number of loops by the width of
* the port */
cnt = len >> shift;
flash_write_cmd (info, sector, 0, cnt - 1);
while (cnt-- > 0) {
switch (info->portwidth) {
case FLASH_CFI_8BIT:
flash_write8(flash_read8(src), dst);
src += 1, dst += 1;
break;
case FLASH_CFI_16BIT:
flash_write16(flash_read16(src), dst);
src += 2, dst += 2;
break;
case FLASH_CFI_32BIT:
flash_write32(flash_read32(src), dst);
src += 4, dst += 4;
break;
case FLASH_CFI_64BIT:
flash_write64(flash_read64(src), dst);
src += 8, dst += 8;
break;
default:
retcode = ERR_INVAL;
goto out_unmap;
}
}
flash_write_cmd (info, sector, 0,
FLASH_CMD_WRITE_BUFFER_CONFIRM);
retcode = flash_full_status_check (
info, sector, info->buffer_write_tout,
"buffer write");
}
break;
case CFI_CMDSET_AMD_STANDARD:
case CFI_CMDSET_AMD_EXTENDED:
flash_unlock_seq(info,0);//发送unlock
#ifdef CONFIG_FLASH_SPANSION_S29WS_N
offset = ((unsigned long)dst - info->start[sector]) >> shift;
#endif
flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);//发送 write buffer command
cnt = len >> shift;
flash_write_cmd(info, sector, offset, cnt - 1);
switch (info->portwidth) {
case FLASH_CFI_8BIT:
while (cnt-- > 0) {
flash_write8(flash_read8(src), dst);//在这里是在写命令发完后又去从norflash中去读,如果src是一个sdram的地址,这样是没有问题,但如果是同一个norflash的内部地址,有时是读不出来正确值的,因为在发送完write buffer command后,这时norflash已经进入了write buffer 状态,不是read状态,这时去读是读不正确值,如果这完成这个操作,我们必须在这之前把flash中的数 先读到一个buffer中,再去调用整个write buffer的操作流程。
src += 1, dst += 1;
}
break;
case FLASH_CFI_16BIT:
while (cnt-- > 0) {
flash_write16(flash_read16(src), dst);
src += 2, dst += 2;
}
break;
case FLASH_CFI_32BIT:
while (cnt-- > 0) {
flash_write32(flash_read32(src), dst);
src += 4, dst += 4;
}
break;
case FLASH_CFI_64BIT:
while (cnt-- > 0) {
flash_write64(flash_read64(src), dst);
src += 8, dst += 8;
}
break;
default:
retcode = ERR_INVAL;
goto out_unmap;
}
flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
printf("****send command 0x29 end!****\n\r");//jackyard
if (use_flash_status_poll(info))
retcode = flash_status_poll(info, src - (1 << shift),
dst - (1 << shift),
info->buffer_write_tout,
"buffer write");
else
retcode = flash_full_status_check(info, sector,
info->buffer_write_tout,
"buffer write");
break;
default:
debug ("Unknown Command Set\n");
retcode = ERR_INVAL;
break;
}
out_unmap:
return retcode;
}
- 关于uboot下cp.b如果两个地址同为flash地时,buffer无法正常写的原因
- 关于Flash无法正常加载的解决方案
- thinkphp框架写的项目在nginx下无法正常访问报错的原因以及解决方法
- IE下无法显示图片,其它浏览器正常的原因。
- 关于两个DIV各占50%时无法在同一行显示的问题
- 关于《安装visual studio 2008下subversion插件ankhsvn2.4导致vs无法正常启动的原因以及解决办法》
- Android 调百度地图搜索API时 出现的打包后手机端无法正常获取地址信息原因
- 图片在ie下无法正常显示,在firefox或chrome正常显示的原因
- 如何从uboot中推算路由器flash烧写地址
- APPScan配置URL连接后无法正常访问地址原因
- 关于tomcat7下shutdown无法正常关闭服务的解决方案
- tomcat无法正常启动的原因分析
- tomcat无法正常启动的原因分析
- IEreport无法正常开启的原因
- tomcat无法正常启动的原因
- tomcat无法正常启动的原因
- 关于最新版Chrome浏览器使用swfobject.swf, uploadify等无法正常播放Flash的问题
- 偶然发现关于网页JavaScript脚本无法正常执行的原因
- note : duilib tips
- 微软面试100题学习笔记(1-5)
- 代码高亮
- 归并排序C语言
- GO语言尝鲜(Beego)
- 关于uboot下cp.b如果两个地址同为flash地时,buffer无法正常写的原因
- c++面向对象设计的SOLID原则
- 调试工具BTrace 的使用--例子
- OpenGL4.x学习之使用绘制三角形
- 关于MFC下检查和消除内存泄露的技巧
- Making a Kite
- this.class.getClassLoader().getResourceAsStream
- Linux Shell高级技巧(一)
- C++类总结