在源码中搜索Flash not Erased,在common/flash.c中flash_perror()函数为错误打印函数
void flash_perror (int err)
{
switch(err) {
caseERR_OK:
break;
caseERR_TIMOUT:
puts("Timeout writing to Flash\n");
break;
caseERR_NOT_ERASED:
puts("Flash not Erased\n");
break;
caseERR_PROTECTED:
puts("Can't write to protected Flash sectors\n");
break;
caseERR_INVAL:
puts("Outside available Flash\n");
break;
caseERR_ALIGN:
puts("Start and/or end address not on sector boundary\n");
break;
caseERR_UNKNOWN_FLASH_VENDOR:
puts("Unknown Vendor of Flash\n");
break;
caseERR_UNKNOWN_FLASH_TYPE:
puts("Unknown Type of Flash\n");
break;
caseERR_PROG_ERROR:
puts("General Flash Programming Error\n");
break;
default:
printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
break;
}
}
在common/cmd_mem.c文件中查找cp命令,锁定do_mem_cp函数
int do_mem_cp ( cmd_tbl_t *cmdtp, int flag,int argc, char * const argv[])
{
ulong addr, dest, count;
int size;
if(argc != 4)
returnCMD_RET_USAGE;
/*Check for size specification.
*/
if((size = cmd_get_data_size(argv[0], 4)) < 0)
return1;
addr= simple_strtoul(argv[1], NULL, 16);
addr+= base_address;
dest= simple_strtoul(argv[2], NULL, 16);
dest+= base_address;
count= simple_strtoul(argv[3], NULL, 16);
if(count == 0) {
puts("Zero length ???\n");
return1;
}
#ifndef CONFIG_SYS_NO_FLASH
/*check if we are copying to Flash */
if( (addr2info(dest) != NULL)
#ifdef CONFIG_HAS_DATAFLASH
&& (!addr_dataflash(dest))
#endif
) {
intrc;
puts("Copy to Flash... ");
rc = flash_write ((char *)addr,dest, count*size);
if (rc != 0) {
flash_perror(rc);
return(1);
}
puts("done\n");
return 0;
}
#endif
#ifdef CONFIG_HAS_DATAFLASH
/*Check if we are copying from RAM or Flash to DataFlash */
if(addr_dataflash(dest) && !addr_dataflash(addr)){
intrc;
puts("Copy to DataFlash... ");
rc= write_dataflash (dest, addr, count*size);
if(rc != 1) {
dataflash_perror(rc);
return(1);
}
puts("done\n");
return0;
}
/*Check if we are copying from DataFlash to RAM */
if(addr_dataflash(addr) && !addr_dataflash(dest)
#ifndef CONFIG_SYS_NO_FLASH
&& (addr2info(dest) == NULL)
#endif
){
intrc;
rc= read_dataflash(addr, count * size, (char *) dest);
if(rc != 1) {
dataflash_perror(rc);
return(1);
}
return0;
}
if(addr_dataflash(addr) && addr_dataflash(dest)){
puts("Unsupported combination of source/destination.\n\r");
return1;
}
#endif
#ifdef CONFIG_BLACKFIN
/*See if we're copying to/from L1 inst */
if(addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) {
memcpy((void*)dest, (void *)addr, count * size);
return0;
}
#endif
while(count-- > 0) {
if(size == 4)
*((ulong *)dest) = *((ulong *)addr);
elseif (size == 2)
*((ushort*)dest) = *((ushort *)addr);
else
*((u_char*)dest) = *((u_char *)addr);
addr+= size;
dest+= size;
/*reset watchdog from time to time */
if((count % (64 << 10)) == 0)
WATCHDOG_RESET();
}
return0;
}
从该函数
rc = flash_write ((char *)addr,dest, count*size);
if (rc != 0) {
flash_perror(rc);
return(1);
}
puts("done\n");
return 0;
部分可以得知flash_write函数返回值不为0,继续查找flash_write()函数。
在common/flash.c中查找到了flash_write()函数
/*-----------------------------------------------------------------------
*Copy memory to flash.
*Make sure all target addresses are within Flash bounds,
*and no protected sectors are hit.
*Returns:
*ERR_OK 0 - OK
*ERR_TIMOUT 1 - write timeout
*ERR_NOT_ERASED 2 - Flash not erased
*ERR_PROTECTED 4 - target range includesprotected sectors
*ERR_INVAL 8 - target address not inFlash memory
*ERR_ALIGN 16 - target address notaligned on boundary
* (only some targetsrequire alignment)
*/
int
flash_write (char *src, ulong addr, ulongcnt)
{
#ifdef CONFIG_SPD823TS
return(ERR_TIMOUT); /* any other error codesare possible as well */
#else
inti;
ulong end = addr + cnt - 1;
flash_info_t*info_first = addr2info (addr);
flash_info_t*info_last = addr2info (end );
flash_info_t*info;
if(cnt == 0) {
return(ERR_OK);
}
if(!info_first || !info_last) {
return(ERR_INVAL);
}
for(info = info_first; info <= info_last; ++info) {
ulongb_end = info->start[0] + info->size; /*bank end addr */
shorts_end = info->sector_count - 1;
for(i=0; i
ulonge_addr = (i == s_end) ? b_end : info->start[i + 1];
if((end >= info->start[i]) && (addr < e_addr) &&
(info->protect[i] != 0) ) {
return(ERR_PROTECTED);
}
}
}
/*finally write data to flash */
for (info = info_first; info<= info_last && cnt>0; ++info) {
ulong len;
len =info->start[0] + info->size - addr;
if (len >cnt)
len =cnt;
if ((i =write_buff(info, (uchar *)src, addr, len)) != 0) {
return(i);
}
cnt -= len;
addr += len;
src += len;
}
return(ERR_OK);
#endif /* CONFIG_SPD823TS */
}
/*-----------------------------------------------------------------------
*/
从return可知
for (info = info_first; info <= info_last && cnt>0;++info) {
ulong len;
len =info->start[0] + info->size - addr;
if (len >cnt)
len =cnt;
if ((i =write_buff(info, (uchar *)src, addr, len)) != 0) {
return(i);
}
write_buff()函数的返回值应该为2,继续看write_buff()
在driver/mtd/cfi_flash.c中找到了该函数。
* 1 - write timeout
1277 * 2 - Flash not erased
1278 */
1279 int write_buff (flash_info_t * info,uchar * src, ulong addr, ulong cnt)
1280 {
1281 ulong wp;
1282 uchar *p;
1283 int aln;
1284 cfiword_t cword;
1285 int i, rc;
1286 #ifdefCONFIG_SYS_FLASH_USE_BUFFER_WRITE
1287 int buffered_size;
1288 #endif
1289 #ifdef CONFIG_FLASH_SHOW_PROGRESS
1290 int digit = CONFIG_FLASH_SHOW_PROGRESS;
1291 int scale = 0;
1292 int dots = 0;
1293
1294 /*
1295 * Suppress if there are fewer thanCONFIG_FLASH_SHOW_PROGRESS writ es.
1296 */
1297 if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) {
1298 scale = (int)((cnt +CONFIG_FLASH_SHOW_PROGRESS - 1) /
1299 CONFIG_FLASH_SHOW_PROGRESS);
1300 }
1301 #endif
1302
1303 /* get lower aligned address */
1304 wp = (addr & ~(info->portwidth - 1));
1305
1306 /* handle unaligned start */
1307 if ((aln = addr - wp) != 0) {
1308 cword.l = 0;
1309 p = (uchar *)wp;
1310 for (i = 0; i < aln; ++i)
1311 flash_add_byte (info,&cword, flash_read8(p + i));
1312
1313 for (; (i
1314 flash_add_byte (info,&cword, *src++);
1315 cnt--;
1316 }
1317 for (; (cnt == 0) &&(i < info->portwidth); ++i)
1318 flash_add_byte (info,&cword, flash_read8(p + i));
1319
1320 rc = flash_write_cfiword(info, wp, cword);
1321 printf("rc=%d cfi_flash.c(line:1321)\n",rc);
1322 if (rc != 0)
1323 return rc;
1324
1325 wp += i;
1326 FLASH_SHOW_PROGRESS(scale,dots, digit, i);
1327 }
1328
1329 /* handle the aligned part */
1330 #ifdefCONFIG_SYS_FLASH_USE_BUFFER_WRITE
1331 buffered_size = (info->portwidth / info->chipwidth);
1332 buffered_size *= info->buffer_size;
1333 while (cnt >= info->portwidth) {
1334 /* prohibit buffer write whenbuffer_size is 1 */
1335 if (info->buffer_size == 1){
1336 cword.l = 0;
1337 for (i = 0; i
1338 flash_add_byte(info, &cword, *src++);
1339 if ((rc =flash_write_cfiword (info, wp, cword)) != 0)
1340 return rc;
1341 wp +=info->portwidth;
1342 cnt -=info->portwidth;
1343 continue;
1344 }
1345
1346 /* write buffer until nextbuffered_size aligned boundary * /
1347 i = buffered_size - (wp %buffered_size);
1348 if (i > cnt)
1349 i = cnt;
1350 if ((rc =flash_write_cfibuffer (info, wp, src, i)) != ERR_ OK)
1351 return rc;
1352 i -= i &(info->portwidth - 1);
1353 wp += i;
1354 src += i;
1355 cnt -= i;
1356 FLASH_SHOW_PROGRESS(scale,dots, digit, i);
1357 }
1358 #else
1359 while (cnt >= info->portwidth) {
1360 cword.l = 0;
1361 for (i = 0; i
1362 flash_add_byte (info,&cword, *src++);
1363 }
1364 if ((rc = flash_write_cfiword(info, wp, cword)) != 0)
1365 {
1366 printf("rc=%d cfi_flash.c(line:1366)\n",rc);
1367 return rc;
1368 }
1369 wp += info->portwidth;
1370 cnt -= info->portwidth;
1371 FLASH_SHOW_PROGRESS(scale,dots, digit, info->portwidth);
1372 }
1373 #endif /*CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
1374
1375 if (cnt == 0) {
1376 return (0);
1377 }
1378
1379 /*
1380 * handle unaligned tail bytes
1381 */
1382 cword.l = 0;
1383 p = (uchar *)wp;
1384 for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
1385 flash_add_byte (info, &cword,*src++);
1386 --cnt;
1387 }
1388 for (; i < info->portwidth; ++i)
1389 flash_add_byte (info,&cword, flash_read8(p + i));
1390
1391 rc= flash_write_cfiword (info, wp, cword);
1392 printf("rc=%d\ncfi_flash.c(line:1392)\n",rc);
1393 return rc;
1394 }
暂时不能找到rc=2,是在那一部分产生的,通过插入printf()函数查找。可以确定为1366行产生的。
1364 if ((rc = flash_write_cfiword(info, wp, cword)) != 0)
1365 {
1366 printf("rc=%d cfi_flash.c(line:1366)\n",rc);
1367 return rc;
1368 }
继续查看flash_write_cfiword()函数,driver/mtd/cfi_flash.c内779行,
static int flash_write_cfiword(flash_info_t * info, ulong dest,
cfiword_tcword)
{
void*dstaddr = (void *)dest;
intflag;
flash_sect_tsect = 0;
charsect_found = 0;
/* Check if Flash is(sufficiently) erased */
switch(info->portwidth) {
case FLASH_CFI_8BIT:
flag =((flash_read8(dstaddr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
flag =((flash_read16(dstaddr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
flag =((flash_read32(dstaddr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
flag =((flash_read64(dstaddr) & cword.ll) == cword.ll);
break;
default:
flag = 0;
break;
}
if (!flag)
returnERR_NOT_ERASED;
/*Disable interrupts which might cause a timeout here */
flag= disable_interrupts ();
switch(info->vendor) {
caseCFI_CMDSET_INTEL_PROG_REGIONS:
caseCFI_CMDSET_INTEL_EXTENDED:
caseCFI_CMDSET_INTEL_STANDARD:
flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);
break;
caseCFI_CMDSET_AMD_EXTENDED:
caseCFI_CMDSET_AMD_STANDARD:
sect= find_sector(info, dest);
flash_unlock_seq(info, sect);
flash_write_cmd(info, sect, info->addr_unlock1, AMD_CMD_WRITE);
sect_found= 1;
break;
#ifdef CONFIG_FLASH_CFI_LEGACY
caseCFI_CMDSET_AMD_LEGACY:
sect= find_sector(info, dest);
flash_unlock_seq(info, 0);
flash_write_cmd(info, 0, info->addr_unlock1, AMD_CMD_WRITE);
sect_found= 1;
break;
#endif
}
switch(info->portwidth) {
caseFLASH_CFI_8BIT:
flash_write8(cword.c,dstaddr);
break;
caseFLASH_CFI_16BIT:
flash_write16(cword.w,dstaddr);
break;
caseFLASH_CFI_32BIT:
flash_write32(cword.l,dstaddr);
break;
caseFLASH_CFI_64BIT:
flash_write64(cword.ll,dstaddr);
break;
}
/*re-enable interrupts if necessary */
if(flag)
enable_interrupts();
if(!sect_found)
sect= find_sector (info, dest);
if(use_flash_status_poll(info))
returnflash_status_poll(info, &cword, dstaddr,
info->write_tout, "write");
else
returnflash_full_status_check(info, sect,
info->write_tout, "write");
}
重点注意
/* Check if Flash is(sufficiently) erased */
switch(info->portwidth) {
case FLASH_CFI_8BIT:
flag =((flash_read8(dstaddr) & cword.c) == cword.c);
break;
case FLASH_CFI_16BIT:
flag =((flash_read16(dstaddr) & cword.w) == cword.w);
break;
case FLASH_CFI_32BIT:
flag =((flash_read32(dstaddr) & cword.l) == cword.l);
break;
case FLASH_CFI_64BIT:
flag =((flash_read64(dstaddr) & cword.ll) == cword.ll);
break;
default:
flag = 0;
break;
}
if (!flag)
returnERR_NOT_ERASED;
这部分可以判断flag=0,info->portwidth的设置有问题,添加printf函数:
/* Check if Flash is (sufficiently) erased*/
printf("info->portwidth =%d cfi_flash.c(line:787)\n",info->portwidth);
switch (info->portwidth) {
caseFLASH_CFI_8BIT:
flag= ((flash_read8(dstaddr) & cword.c) == cword.c);
break;
caseFLASH_CFI_16BIT:
flag= ((flash_read16(dstaddr) & cword.w) == cword.w);
break;
caseFLASH_CFI_32BIT:
flag= ((flash_read32(dstaddr) & cword.l) == cword.l);
break;
caseFLASH_CFI_64BIT:
flag= ((flash_read64(dstaddr) & cword.ll) == cword.ll);
break;
default:
flag= 0;
break;
}
if(!flag)
returnERR_NOT_ERASED;
编译运行结果:
说明info->portwidth=2,与include/flash.h文件中设置一致
case FLASH_CFI_16BIT:
flag= ((flash_read16(dstaddr) & cword.w) == cword.w);
break;
说明flash_read16函数的返回值为2,继续查找,发现flash_read16分别在两个函数中定义:board/micronas/vct/ebi_nor_flash.c和board/freescale/p1022ds/diu.c两个文件。
查看两个文件夹发现没有.o文件生成,说明这个程序编译过程没有执行flash_read16函数,
查看board/micronas/vct/Makefile文件:
需要打开CONFIG_VCT_NOR的宏定义,于是在smdk2440.h中添加:
#define ONFIG_VCT_NOR
编译下载后,cp.b能正常执行。