加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

关于uboot下cp.b如果两个地址同为flash地时,buffer无法正常写的

发布时间:2020-12-15 17:43:14 所属栏目:百科 来源:网络整理
导读:第一、cp.b命令说明 cp [.b,.w,.l] source target count ?????? - copy memory cp命令可以在内存中复制数据块,包括对Flash的读写操作。 第1个参数source是要复制的数据块起始地址。 第2个参数target是数据块要复制到的地址。这个地 址如果在Flash中, 那么

第一、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,FLASH_CMD_CLEAR_STATUS);
flash_write_cmd (info,FLASH_CMD_READ_STATUS);
flash_write_cmd (info,write_cmd);
retcode = flash_status_check (info,
? ? ?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,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,
FLASH_CMD_WRITE_BUFFER_CONFIRM);
retcode = flash_full_status_check (
info,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,offset,AMD_CMD_WRITE_TO_BUFFER);//发送 write buffer command
cnt = len >> shift;
flash_write_cmd(info,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,AMD_CMD_WRITE_BUFFER_CONFIRM); printf("****send command 0x29 end!****nr");//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,?info->buffer_write_tout,?"buffer write"); break; default: debug ("Unknown Command Setn"); retcode = ERR_INVAL; break; } out_unmap: return retcode; }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读