QT210 自制bootloader实现uboot command 和串口烧写bootloader

参考韦东山串口烧写binary和uboot命令,自制bootloader在QT210实现这些功能,方便调试:
串口烧写的速度大概8K左右,烧写几十k的bootloader还可以,不用总是插拔usb了,
log:



Printf enter to enter shell mode
SMDKV210 #uart load 0x20000000
 uartmem:uart
uart load 0x20000000 Download will start!press enter to start the timer
10
9
8
7
6

开始 xmodem 传输。  按 Ctrl+C 取消。
Transferring BL2.log...
  100%     275 KB    7 KB/s 00:00:35       0 Errors


complted:len:282368

SMDKV210 #

 uartmem:uart
uart 
SMDKV210 #
SMDKV210 #
SMDKV210 #flashbl2Download will start!press enter to start the timer
10
9
8
7
6

开始 xmodem 传输。  按 Ctrl+C 取消。
Transferring BL2.bin...
  100%      29 KB    7 KB/s 00:00:04       0 Errors


complted:len:30592

SMDKV210 #


BL2.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
	. = 0x30000000;
	.text      :
	{
	  out/start.o	(.text)
	  out/*(.text)
	}
	. = ALIGN(4);
	.rodata : { out/*(.rodata) }

	. = ALIGN(4);
	.data : {out/*(.data)}	

	. = ALIGN(4);
	.got : { out/*(.got) }

	
	__u_boot_cmd_start = .;
	.u_boot_cmd : { out/*(.u_boot_cmd) }
	__u_boot_cmd_end = .;
	
	. = ALIGN(4);
	bss_start = .;
	.bss : {out/*(.bss) out/*(COMMON) }
	bss_end = .;

}

//main.c

#include "stdio.h"
#include "includes.h"
void run_shell()
{
	char rx_buf[100]={'\0'};
	delay(1000);
	while(1)
	{
		printf("SMDKV210 #");
		gets(rx_buf);
		if((strlen(rx_buf) == 1 &&  strcmp(rx_buf, "q") == 0) || strcmp(rx_buf, "quit")==0)
			break;
		
		run_command(rx_buf,0);
		printf("\n");

	}

}
void main(void)
{
	int i = 5;
	char c;
	int timeout=0;
	led_init();
	lcd_init();
	uart_init();
	
	GUI_ClearScreen(0x00ffff00);

	GUI_Printf(100,100,0x00,0xffffffff,"BL2 BOOT...");
	
	while(1)
	{
		getc_nowait(&c);
		if(c=='\r')
		{
			timeout = 0;
			run_shell();
			c='\0';//resolve reset the c is s
			
		}

		delay(1000);
		printf("time out:%d\r",timeout);
		timeout++;
		
		if(timeout> 5)
			break;
		
	}
	printf("the system will be boot\n");
	while (1)
	{		
		i=i%4;
		led(i);
		delay(1000);
		i++;
		
	}
}
//commond.c
#include "command.h"
#include "stdio.h"
#include "string.h"
#include "includes.h"


/*
 * Use puts() instead of printf() to avoid printf buffer overflow
 * for long help messages
 */
int do_help (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	int i;
	int rcode = 0;

	if (argc == 1) {	/*show list of commands */

		int cmd_items = &__u_boot_cmd_end -
				&__u_boot_cmd_start;	/* pointer arith! */
		cmd_tbl_t *cmd_array[cmd_items];
		int i, j, swaps;

		/* Make array of commands from .uboot_cmd section */
		cmdtp = &__u_boot_cmd_start;
		for (i = 0; i < cmd_items; i++) {
			cmd_array[i] = cmdtp++;
		}

		/* Sort command list (trivial bubble sort) */
		for (i = cmd_items - 1; i > 0; --i) {
			swaps = 0;
			for (j = 0; j < i; ++j) {
				if (strcmp (cmd_array[j]->name,
					    cmd_array[j + 1]->name) > 0) {
					cmd_tbl_t *tmp;
					tmp = cmd_array[j];
					cmd_array[j] = cmd_array[j + 1];
					cmd_array[j + 1] = tmp;
					++swaps;
				}
			}
			if (!swaps)
				break;
		}

		/* print short help (usage) */
		for (i = 0; i < cmd_items; i++) {
			const char *usage = cmd_array[i]->usage;

			/* allow user abort */
			if (ctrlc ())
				return 1;
			if (usage == NULL)
				continue;
			puts (usage);
		}
		return 0;
	}
	/*
	 * command help (long version)
	 */
	for (i = 1; i < argc; ++i) {
		if ((cmdtp = find_cmd (argv[i])) != NULL) {
#ifdef	CFG_LONGHELP
			/* found - print (long) help info */
			puts (cmdtp->name);
			putc (' ');
			if (cmdtp->help) {
				puts (cmdtp->help);
			} else {
				puts ("- No help available.\n");
				rcode = 1;
			}
			putc ('\n');
#else	/* no long help available */
			if (cmdtp->usage)
				puts (cmdtp->usage);
#endif	/* CFG_LONGHELP */
		} else {
			printf ("Unknown command '%s' - try 'help'"
				" without arguments for list of all"
				" known commands\n\n", argv[i]
					);
			rcode = 1;
			return 0;
		}
	}
	return rcode;
}


U_BOOT_CMD(
	help,	CFG_MAXARGS,	1,	do_help,
	"help    - print online help\n",
	"[command ...]\n"
	"    - show help information (for 'command')\n"
	"'help' prints online help for the monitor commands.\n\n"
	"Without arguments, it prints a short usage message for all commands.\n\n"
	"To get detailed help information for specific commands you can type\n"
  "'help' with one or more command names as arguments.\n"
);

/* This do not ust the U_BOOT_CMD macro as ? can't be used in symbol names */
cmd_tbl_t __u_boot_cmd_question_mark Struct_Section = {
	"?",	CFG_MAXARGS,	1,	do_help,
	"?       - alias for 'help'\n",
	NULL
};


/***************************************************************************
 * find command table entry for a command
 */
cmd_tbl_t *find_cmd (const char *cmd)
{
	cmd_tbl_t *cmdtp;
	cmd_tbl_t *cmdtp_temp = &__u_boot_cmd_start;	/*Init value */
	const char *p;
	int len;
	int n_found = 0;

	/*
	 * Some commands allow length modifiers (like "cp.b");
	 * compare command name only until first dot.
	 */
	len = ((p = strchr(cmd, '.')) == NULL) ? strlen (cmd) : (p - cmd);

	for (cmdtp = &__u_boot_cmd_start;
	     cmdtp != &__u_boot_cmd_end;
	     cmdtp++) {
		if (strncmp (cmd, cmdtp->name, len) == 0) {
			if (len == strlen (cmdtp->name))
				return cmdtp;	/* full match */

			cmdtp_temp = cmdtp;	/* abbreviated command ? */
			n_found++;
		}
	}
	if (n_found == 1) {			/* exactly one match */
		return cmdtp_temp;
	}

	return NULL;	/* not found or ambiguous command */
}

int parse_line (char *line, char *argv[])
{
	int nargs = 0;

	while (nargs < CFG_MAXARGS )
	{

		/* skip any white space */
		while ((*line == ' ') || (*line == '\t')) 
		{
			++line;
		}

		if (*line == '\0') 
		{	/* end of line, no more args	*/
			argv[nargs] = NULL;
			return (nargs);
		}

		argv[nargs++] = line;	/* begin of argument string	*/

		/* find end of string */
		while (*line && (*line != ' ') && (*line != '\t'))
		{
			++line;
		}

		if (*line == '\0') 
		{	/* end of line, no more args	*/
			argv[nargs] = NULL;
			return (nargs);
		}

		*line++ = '\0';		/* terminate current arg	 */
	}

	printf ("** Too many args (max. %d) **\n", CFG_MAXARGS);

	return (nargs);
}

int run_command (char *cmd, int flag)
{
	cmd_tbl_t *cmdtp;
	//char cmdbuf[CFG_CBSIZE];	/* working copy of cmd		*/

	//char *str = cmdbuf;
	char *argv[CFG_MAXARGS + 1];	/* NULL terminated	*/
	int argc;
	int repeatable = 1;
	int rc = 0;


	clear_ctrlc();		/* forget any previous Control C */

	if (!cmd || !*cmd) {
		return -1;	/* empty command */
	}

	if (strlen(cmd) >= CFG_CBSIZE) {
		puts ("## Command too long!\n");
		return -1;
	}

	//strcpy (cmdbuf, cmd);

	/* Process separators and check for invalid
	 * repeatable commands
	 */

//	while (*str)
//	{

		
		/* Extract arguments */
		if ((argc = parse_line (cmd, argv)) == 0) 
		{
			rc = -1;	/* no command at all */
			//continue;
			return 0;
		}
		//printf("argc:%d,%s,%s\r\n",argc,argv[0],argv[1]);
		/* Look up command in command table */
		if ((cmdtp = find_cmd(argv[0])) == NULL) 
		{
			printf ("Unknown command '%s' - try 'help'\n", argv[0]);
			rc = -1;	/* give up after bad command */
			return 0;
			//continue;
		}
		if(strcmp(argv[1],"help")==0)
		{
			printf ("\nhelp:\n%s\n", cmdtp->help);
			return 0;


		}

		/* found - check max args */
		if (argc > cmdtp->maxargs) 
		{
			printf ("Usage:\n%s\n", cmdtp->usage);
			rc = -1;
			return 0;
			//continue;
		}

		/* OK - call function to do the command */
		if ((cmdtp->cmd) (cmdtp, flag, argc, argv) != 0) 
		{
			rc = -1;
			return 0;
		}

		repeatable &= cmdtp->repeatable;

		/* Did the user stop this? */
		if (had_ctrlc ())
			return -1;	/* if stopped then not repeatable */
		
//	}
	return 0;
//	return rc ? rc : repeatable;
}


cmd_load.c

#include "stdio.h"
#include "command.h"
#include "string.h"
#include "def.h"



extern U8 SDHC_WriteBlocks(U32 uStBlock, U16 uBlocks, U32* uBufAddr);
extern int getc_nowait(unsigned char *pChar);

#define SOH  0x01
#define STX  0x02
#define EOT  0x04//正常结束,通知接收方
#define ACK  0x06//接收正确
#define NAK  0x15//开始发第一个包、重发
#define CAN  0x18//无条件停止发送
#define CTRLZ 0x1A//不足部分填充
extern void delay(int ms);
int xmodem_recv(unsigned long addr)
{
	int i = 0;
	int cnt=addr;
	char buf[128 + 4];
	char c;
	puts("Download will start!press enter to start the timer\n");
	getc();
	for(i =10; i>0;i--)
	{
		printf("%d\n",i);
		delay(1500);
	}
	putc(NAK);
	while((buf[0] = getc()) != EOT)
	{

		
		for(i = 1; i < 128 + 4; i++)
		{
			if(i >= 3 && i <= 130)
				*(char *)(addr + i-3) = getc();
		}

		
	
		addr += 128;
		putc(ACK);

	}

	putc(ACK);

	printf("\ncomplted:len:%d\n",addr-cnt);
	return (addr-cnt);
	
}
int uart_load_mem(unsigned long addr)
{
	unsigned char *buf = (unsigned char *)addr;
	unsigned long len = 0;
	int have_begin = 0;
	int nodata_time = 0;
	int i=0;

	/* 读串口获得数据 */
	printf("\nuse terminal  to send file:0x%08x\n", (unsigned long)addr);
	while (1)
	{
		if (getc_nowait(&buf[len]) == 0)
		{
			have_begin = 1;
			nodata_time = 0;
			len++;
			
		}
		else
		{
			if (have_begin)
			{
				nodata_time++;

			}			
		}

		if (nodata_time == 1000000)
		{
			break;
		}
	}
	printf("\ncomplted:len:%d,timeout:%d\n",len,nodata_time);
	

	return len;

}


int do_uartmem (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	unsigned long load_addr=0;
	int len = 0;
	int i = 0;
	int isload = 0;
	int memsize = 0;
	int start_blk = 0;
	char ap[20]={'\0'};

	printf("\n uartmem:%s\n",argv[0]);
	for( i=0;i<5;i++)
	{
		if(argv[i])
		printf("%s ",argv[i]);
		else break;
	}
	 //(strcmp(ap[1], "-eq") == 0)
	 strcpy(ap,argv[1]);
	if(strcmp(ap,"load") == 0)
	{
		
		isload = 1;//load mem

		load_addr = simple_strtoul(argv[2], NULL, 16);
	}
	if(strcmp(ap,"sd") == 0)	
	{
		isload = 2; //write to sd
		load_addr = simple_strtoul(argv[2], NULL, 16);
		start_blk = simple_strtoul(argv[3], NULL, 10);
		memsize =  simple_strtoul(argv[4], NULL, 10);
			
	}
	
	switch(isload)
	{
		case 1:
			len = uart_load_mem(load_addr);
			//len = xmodem_recv(load_addr);
			break;
		case 2:
			printf("\n sd:start_blk:%d,memsize:%d,load_addr:0x%08x\n",start_blk,(memsize+511)/512,load_addr);
			SDHC_WriteBlocks(start_blk,(memsize+511)/512,(U32 *)load_addr);
			break;
		default:
			break;


	}
	

	return 0;
}

U_BOOT_CMD(
	uart,	5,		0,	do_uartmem,
	"uart 	- load into memory from uart\n",
	"uart load address\nuart sd addr(0xXXXXXXXX) blk size(bytes)\n"
);
int do_goaddr(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	unsigned long addr;
	addr = simple_strtoul(argv[1],NULL,16);
	printf("\nwill run to adress::%s,%s,0x%08x\n",argv[0],argv[1],addr);
	void (*theProgram)(void);
	theProgram = (void (*)(void))addr;

	theProgram();	
	return 0;

}
U_BOOT_CMD(
	go,	2,		0,	do_goaddr,
	"go	- go address\r\n",
	NULL
);
/* * reset the cpu by setting up the watchdog timer and let him time out */
int reset_cpu(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	printf("reset... \n\n\n");
	//SW_RST_REG = 0x1;
	*(volatile long *)0xe0102000 = 0x01;


	while (1)
	{
			if(getc())
			break;

	}
	return 0;
	/*NOTREACHED*/
}
U_BOOT_CMD(
	reset,	1,		0,	reset_cpu,
	"reset	- reset cpu\n",
	NULL
);
int flash_bl2(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int len=0;
	//len = xmodem_recv(0x20000000);
	len = uart_load_mem(0x20000000);
	SDHC_WriteBlocks(49,(len+511)/512,(U32 *)0x20000000);
	return 0;
}
U_BOOT_CMD(
	flashbl2,	1,		0,	flash_bl2,
	"flashbl2- down load bl2 to sd\n",
	NULL
);



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值