控制台:嵌入式设备提供给开发者的用于控制嵌入式设备的输入输出平台
控制台类型:
菜单型控制台:提供选项,用户根据选项来做出相应操作
解析型控制台:用户输入命令,控制台对该命令进行解析并调用相应函数
菜单型控制台的建立
while(1)
{
printf("\n***************************************\n\r");
printf("\n*****************GBOOT*****************\n\r");
printf("1:Download Linux Kernel from TFTP Server!\n\r");
printf("2:Boot Linux from RAM!\n\r");
printf("3:Boor Linux from Nand Flash!\n\r");
printf("\n Plese Select:");
scanf("%d",&num);
switch (num)
{
case 1:
//tftp_load();
break;
case 2:
//boot_linux_ram();
break;
case 3:
//boot_linux_nand();
break;
default:
printf("Error: wrong selection!\n\r");
break;
}
}
重点是printf和scanf函数的建立
printf函数的建立
通过Linux指令 man 3 printf可得到printf原型为int printf(const char* fmt, …),该函数参数中“…”表明该函数是变参函数,即参数的个数不恒定,具体个数由前面的参数决定。函数实现为:
#include "vsprintf.h"
unsigned char outbuf[1024];
unsigned char inbuf[1024];
int printf(const char* fmt, ...)
{
va_list args;
int i;
//1.将变参转化为字符串
va_start(args,fmt); //根据fmt得到参数列表,并将变参列表存放在args
vsprintf((char *)outbuf, fmt, args); //将变参转化为字符串
va_end(); //结束转化
//2. 打印字符串到串口
for(i=0;i< strlen((char *)outbuf); i++)
{
putc(outbuf[i]);
}
return i;
}
va_start,vsprintf,va_end这三个函数可通过Linux内核移植实现,将Linux内核中这三个函数集成到我们的bootloader。往我们的程序所在的文件夹添加lib和include文件夹,里面要有相应的程序文件,然后修改makefile。
scanf函数的建立
scanf函数的原型是int scanf(const char* fmt, …),代码实现为:
int scanf(const char* fmt, ...)
{
unsigned char c;
int i = 0;
va_list args;
//1. 获取输入的字符串
while (1)
{
c = getc();
if ((c==0x0d) || (c==0x0a))
{
inbuf[i] = '\n';
break;
}
else
{
inbuf[i++] = c;
}
}
//2. 格式转化
va_start(args, fmt);
vsscanf((char *)inbuf,fmt,args);
va_end(args);
return i;
}
ps:当用以上方法对S5PV210编程时,打印出来的是一串乱码,经过排除,得知问题出现在打印字符串到串口。打印字符串到串口的问题在于数据段的内容。原始的gboot.bin没有问题,加头后的gboot.210.bin的内容就遭到破坏了。打开加头文件程序,可以看到该程序文件限制了gboot.bin的大小。修改了限制的大小后,还需要修改checksum(210在运行程序前会检测bootloader前16k中1的个数是否与bootloader头信息中提供的1的个数是否相等)