Read Me
一、功能
1.硬件初始化
2.延时判断加载操作系统,按任意键Bootloader Shell
3.加载操作系统
4.shell
二、进入Shell 支持的命令
1.led_test 测试所有led灯,跑马灯1次
2.beep_test 测试蜂鸣器,蜂鸣器响3声同时七段数码管1——F亮1次
3.xmodem 下载文件到开发板的内存,默认到0x32000000
4.go 跳到某地址执行
5.flash_load 显示指定内存地址中的内容
6.help 帮助,显示所有支持的命令,及命令格式
三、文件结构
1.LED_S.S 程序入口,负责硬件初始化,Bootloader自搬移
2.uart0.c uart.h 串口驱动的实现
3.main.c 进入bootload延时选择加载操作系统还是进入Shell
4.my_printf.c my_printf.h 封装printf函数的实现
5.my_stdio.h my_stdio.c 标准输入输出函数的实现
6.my_shell.c my_shell.h shell命令的实现
7.copy_myself.c bootloader自拷贝函数
8.led.c led.h led灯的测试函数
9.beep.s 测试蜂鸣器及七段数码管函数
10.xmodem.h xmodem.c xmodem协议实现
11.beep_os.s 模拟操作系统
12.Makefile
四、流程及设计思想
1.硬件初始化
2.Bootloader自搬移
3.延时,判断是否有输入
4.(1)无输入则加载操作系统,操作系统烧写于Nand Flash的第0块
(2)有输入则进入shell命令模式
5.解释命令,使用自己实现的标准库函数来匹配输入的命令
6.匹配函数,定义了一个包含字符指针以及函数指针的结构体,可以通过对应关系迅速调用命令对应的函数
五、测试条件及结果
1. 打开超级终端,给开发板上电,超级终端上打印提示信息
2. 超级终端上开始5秒倒计时,5秒内不动键盘,提示加载操作系统
3. 重启开发板,3秒内按下任意键,可看到有welcome#提示符,程序进入Shell模式
4. 输入help,可看到5条命令的使用方法
5. 输入led_test 可看到跑马灯
6. 输入beep_test 可听到蜂鸣器响3次
7. 输入xmodem,发送文件 测试xmodem/interrupt.BIN
8. 输入flash_load 0x32000000 可看到内存地址中的数据
9. 输入go 0x32000000 可观察到七段数码管1——F循环显示及蜂鸣器响
六、函数及功能
1.uart0.h
int uart0_init(void); 初始化串口
char uart0_getchar(void); 从键盘接收一个字符
void uart0_putchar(char ch); 打印一个字符从终端输出
int uart0_test(void); 在终端现在键盘输入
2.my_stdio.h
void my_gets(char *str); 接收一个字符串,并设置退格及回退后的字符不赋值给字符串
char my_getchar(void); 重写uart0_getchar
int my_putchar(char ch); 重写uart0_putchar
3.command.h
void command(char *str,char *s2); 命令解析,将命令和参数分开。
4.go.h
void go(char *s2); 将得到的参数转化成十六进制,并在些函数下调用go(temp)给pc赋值
以实现调转go 命令
5.flash_load.h
void flash_load(char *s2); 将得到的参数转化成十六进制,
my_printf("%x/n",*(unsigned int *)temp);得到内存地址中的数据
6.my_shell.h
void my_shell(void); 所有的shell命令 调用,都在这里来调用。
7.led.h 跑马灯的实现
8.help.h 在help.c中调用my_printf 来输入字符串
9.协议xmodem.h 及 输出my_printf.h 均是移植的
七.分析代码
1.LED_S.S程序的入口。 实现初始化硬件:关看门狗,关中断,初始化时钟频率,初始化SDRAM
初始化NANDFLASH,将bootloader自拷贝到SDRAM,程序执行流的切换(
SRAM——SDRAM).及关蜂鸣器。
标号start还实现了七段数码管 最后跳转b c_entry (main.c)
该文件最后插入的 go.c文件的调用汇编 (EXPORT gocmd)
2.main.c int c_entry(void)进入 判断分支,是进入 loop()(beep_os.S蜂鸣器的
一个死循环);还是进入shell()(my_shell.c)
3.my_shell.c 进入一个死循环,首先打印提示符Weclome# 然后my_gets(str)(my_stdio.c)获取字符
串,command(str,s2);(command.c)进行命令解析,命令和参数分开
命令传入str,参数给了s2。n=stringcompare(str);(stringcompare.c)
字符串比较,实现了六个命令,比较str是否与六个字符匹配,内嵌汇编相应传入
一个1——6的数字n。
最后实现6个命令 分别调用各自的函数。如果传的数字不是1——6则输入 命令错误信息。
命令的实现:1.led_test()(led.c)实现跑马灯
2.beep_test();(beep.x)调用汇编。蜂鸣器和七段数码管
3.xmodem_receive();my_printf("/n完成/n");下载命令。xmodem协议。若下载到开发板完成。终端输出“完成”
4.go(s2);(go.c)将传回的字符指针s2,转换成十进制整型。并调用gocmd(temp);汇编(LED_S.S最后几行。)实现程序跳转。
5.flash_load(s2);内存显示。将传回的字符指针s2,转换成十进制整型(和go文件类似)。my_printf("%x/n",*(unsigned int *)temp);
用此命令直接输出内存地址中的数据
6.help() (my_help.c)直接调用my_printf函数 输出帮助信息。
还有很多不足的地方。还有一些小bug.例如输入命令时,若加上空格后。就能输出对的。