⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 u-boot代码记录.c

📁 本人移植 uboot后代码注释 注释很详细的
💻 C
📖 第 1 页 / 共 5 页
字号:
					chip = ERR;

			} while (!chip);

			MEM_FLASH_ADDR1 = CMD_READ_ARRAY;

			if (chip == ERR) 
			{
				rc = ERR_PROG_ERROR;
				goto outahere;
			}
			if (chip == TMO) 
			{
				rc = ERR_TIMOUT;
				goto outahere;
			}

			printf ("ok.\n");
		} 
		else 
		{	/* it was protected */

			printf ("protected!\n");
		}
	}

	if (ctrlc ())
		printf ("User Interrupt!\n");

      outahere:
	/* allow flash to settle - wait 10 ms */
	udelay_masked (10000);

	if (iflag)
		enable_interrupts ();

	if (cflag)
		icache_enable ();

	return rc;
}





int do_flinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong bank;

#ifdef CONFIG_HAS_DATAFLASH
	dataflash_print_info();
#endif

	if (argc == 1) {	/* print info for all FLASH banks */
		for (bank=0; bank <CFG_MAX_FLASH_BANKS; ++bank) 
		{
			printf ("\nBank # %ld: ", bank+1);

			flash_print_info (&flash_info[bank]);
		}
		return 0;
	}

	bank = simple_strtoul(argv[1], NULL, 16);
	if ((bank < 1) || (bank > CFG_MAX_FLASH_BANKS)) 
	{
		printf ("Only FLASH Banks # 1 ... # %d supported\n",
			CFG_MAX_FLASH_BANKS);
		return 1;
	}
	printf ("\nBank # %ld: ", bank);
	flash_print_info (&flash_info[bank-1]);
	return 0;
}




void flash_print_info (flash_info_t * info)
{
	int i;

	switch (info->flash_id & FLASH_VENDMASK) 
	{
	case (AMD_MANUFACT & FLASH_VENDMASK):
		printf ("AMD: ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) 
	{
	case (AMD_ID_LV400B & FLASH_TYPEMASK):
		printf ("1x Amd29LV400BB (4Mbit)\n");
		break;
	case (AMD_ID_LV800B & FLASH_TYPEMASK):
		printf ("1x Amd29LV800BB (8Mbit)\n");
		break;
	default:
		printf ("Unknown Chip Type\n");
		goto Done;
		break;
	}

	printf ("  Size: %ld MB in %d Sectors\n",info->size >> 20, info->sector_count);

	printf ("  Sector Start Addresses:");
	for (i = 0; i < info->sector_count; i++) 
	{
		if ((i % 5) == 0) 
		{
			printf ("\n   ");
		}
		printf (" %08lX%s", info->start[i],
			info->protect[i] ? " (RO)" : "     ");
	}
	printf ("\n");

      Done:;
}








volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
{
	vu_short *addr = (vu_short *) dest;
	ushort result;
	int rc = ERR_OK;
	int cflag, iflag;
	int chip;

	/*
	 * Check if Flash is (sufficiently) erased
	 */
	result = *addr;
	if ((result & data) != data)
		return ERR_NOT_ERASED;


	/*
	 * Disable interrupts which might cause a timeout
	 * here. Remember that our exception vectors are
	 * at address 0 in the flash, and we don't want a
	 * (ticker) exception to happen while the flash
	 * chip is in programming mode.
	 */
	cflag = icache_status ();
	icache_disable ();
	iflag = disable_interrupts ();

	MEM_FLASH_ADDR1 = CMD_UNLOCK1;
	MEM_FLASH_ADDR2 = CMD_UNLOCK2;
	MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
	*addr = CMD_PROGRAM;
	*addr = data;

	/* arm simple, non interrupt dependent timer */
	reset_timer_masked ();

	/* wait until flash is ready */
	chip = 0;
	do {
		result = *addr;

		/* check timeout */
		if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) 
		{
			chip = ERR | TMO;
			break;
		}
		if (!chip && ((result & 0x80) == (data & 0x80)))
			chip = READY;

		if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) 
		{
			result = *addr;

			if ((result & 0x80) == (data & 0x80))
				chip = READY;
			else
				chip = ERR;
		}

	} while (!chip);

	*addr = CMD_READ_ARRAY;

	if (chip == ERR || *addr != data)
		rc = ERR_PROG_ERROR;

	if (iflag)
		enable_interrupts ();

	if (cflag)
		icache_enable ();

	return rc;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash.
 */

int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	ulong cp, wp;
	int l;
	int i, rc;
	ushort data;

	wp = (addr & ~1);	/* get lower word aligned address */  //把最低位清0,保持字对其,addr是目的地址

	/*
	 * handle unaligned start bytes
	 */
	 //处理addr为非字对其的情况
	if ((l = addr - wp) != 0) 
	{
		data = 0;
		for (i = 0, cp = wp; i < l; ++i, ++cp) 
		{
			data = (data >> 8) | (*(uchar *) cp << 8);
		}
		for (; i < 2 && cnt > 0; ++i) 
		{
			data = (data >> 8) | (*src++ << 8);
			--cnt;
			++cp;
		}
		for (; cnt == 0 && i < 2; ++i, ++cp) 
		{
			data = (data >> 8) | (*(uchar *) cp << 8);
		}

		if ((rc = write_hword (info, wp, data)) != 0) 
		{
			return (rc);
		}
		wp += 2;
	}

	/*
	 * handle word aligned part
	 */
	 //处理字对其的情况
	while (cnt >= 2) {
		data = *((vu_short *) src);//从源地址读出2字节的数据,wp为目的地址且为字对其
		if ((rc = write_hword (info, wp, data)) != 0) 
		{
			return (rc);
		}
		src += 2;
		wp += 2;
		cnt -= 2;
	}

	if (cnt == 0) 
	{
		return ERR_OK;
	}

	/*
	 * handle unaligned tail bytes
	 */
	data = 0;
	for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) 
	{
		data = (data >> 8) | (*src++ << 8);
		--cnt;
	}
	for (; i < 2; ++i, ++cp) {
		data = (data >> 8) | (*(uchar *) cp << 8);
	}

	return write_hword (info, wp, data);
}




int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong	addr, dest, count;
	int	size;

	if (argc != 4)             //如果参数个数不为4个
	{
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	/* Check for size specification.
	*/
	if ((size = cmd_get_data_size(argv[0], 4)) < 0)   //zize为4
		return 1;

	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");
		return 1;
	}
//copy to flash
#ifndef CFG_NO_FLASH
	/* check if we are copying to Flash */
	if ( (addr2info(dest) != NULL))    //判断是不是目的地址
	{
		int rc;

		puts ("Copy to Flash... ");

		rc = flash_write ((char *)addr, dest, count*size);//count*size为总的字节数
		if (rc != 0) 
		{
			flash_perror (rc);
			return (1);
		}
		//只有rc返回0才会输出下面语句 
		puts ("done\n");
		return 0;
	}
#endif


//copy to ram


	while (count-- > 0) {
		if (size == 4)
			*((ulong  *)dest) = *((ulong  *)addr);
		else if (size == 2)
			*((ushort *)dest) = *((ushort *)addr);
		else
			*((u_char *)dest) = *((u_char *)addr);
		addr += size;
		dest += size;
	}
	return 0;
}





flash_info_t * addr2info (ulong addr)
{

	flash_info_t *info;
	int i;

	for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) 
	{
		if (info->flash_id != FLASH_UNKNOWN &&addr >= info->start[0] &&addr <= info->start[0] + info->size - 1) 
		  
		    {
			    return (info);
		    }
	}


	return (NULL);
}




/*-----------------------------------------------------------------------
 * 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 includes protected sectors
 * ERR_INVAL       8 - target address not in Flash memory
 * ERR_ALIGN       16 - target address not aligned on boundary
 *			(only some targets require alignment)
 */
//rc = flash_write ((char *)addr, dest, count*size);//count*size为总的字节数
int flash_write (char *src, ulong addr, ulong cnt)
{

	int i;
	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) 
	{
		ulong b_end = info->start[0] + info->size;	/* bank end addr */   //flash的物理结束地址
		short s_end = info->sector_count - 1;    //最后一个扇区的索引
		for (i=0; i<info->sector_count; ++i) 
		{
			ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];  //e_addr 表示的是扇区的结束地址

			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;   //addr是dest目的地址,计算出从flash结束地址到当前地址的有多少空间
		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);//ERR_OK=0
}

//if ((size = cmd_get_data_size(argv[0], 4)) < 0)//
int cmd_get_data_size(char* arg, int default_size)
{
	/* Check for a size specification .b, .w or .l.
	 */
	int len = strlen(arg);
	if (len > 2 && arg[len-2] == '.') 
	{
		switch(arg[len-1]) {
		case 'b':
			return 1;
		case 'w':
			return 2;
		case 'l':
			return 4;
		case 's':
			return -2;
		default:
			return -1;
		}
	}
	return default_size;
}

int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong	addr, length;
	ulong	i, nbytes, linebytes;
	u_char	*cp;
	int	size;
	int rc = 0;

	/* We use the last specified parameters, unless new ones are
	 * entered.
	 */
	addr = dp_last_addr;
	size = dp_last_size;
	length = dp_last_length;

	if (argc < 2)                   //如果参数下于2
	{
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if ((flag & CMD_FLAG_REPEAT) == 0) //#define CMD_FLAG_REPEAT		0x0001	/* repeat last command		*/
	{
		/* New command specified.  Check for a size specification.
		 * Defaults to long if no or incorrect specification.
		 */
		if ((size = cmd_get_data_size(argv[0], 4)) < 0)
			return 1;

		/* Address is specified since argc > 1
		*/
		addr = simple_strtoul(argv[1], NULL, 16);
		addr += base_address;  //base_address=0;

		/* If another parameter, it is the length to display.
		 * Length is the number of objects, not number of bytes.
		 */
		if (argc > 2)
			length = simple_strtoul(argv[2], NULL, 16);
	}

	/* Print the lines.
	 *
	 * We buffer all read data, so we can make sure data is read only
	 * once, and all accesses are with the specified bus width.
	 */
	nbytes = length * size;     //要读出的直接数
	do 
	{
		char	linebuf[DISP_LINE_LEN];
		uint	*uip = (uint   *)linebuf;
		ushort	*usp = (ushort *)linebuf;
		u_char	*ucp = (u_char *)linebuf;

		printf("%08lx:", addr);
		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;  //如果mbytes大于16则去16


		for (i=0; i<linebytes; i+= size) //打印出一行
		{
			if (size == 4) 
			{
				printf(" %08x", (*uip++ = *((uint *)addr)));  //取出地址的内容
			} 
			else if (size == 2) 
			{
				printf(" %04x", (*usp++ = *((ushort *)addr)));
			} 
			else 
			{
				printf(" %02x", (*ucp++ = *((u_char *)addr)));
			}
			addr += size;
		}

		puts ("    ");
		cp = (u_char *)linebuf; 
		for (i=0; i<linebytes; i++) 
		{
			if ((*cp < 0x20) || (*cp > 0x7e))
				putc ('.');
			else
				printf("%c", *cp);
			cp++;
		}
		putc ('\n');

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -