最小bootloader的实现,完整源代码
来源:互联网 发布:如何成为一名java讲师 编辑:程序博客网 时间:2024/05/18 01:20
我们整个ARM课程就分为三部分,这是第一部分,实现一个自己的最小bootloader
1.Read Me
一、实现功能
1.硬件初始化
2.延时判断加载操作系统还是进入Bootloader Shell
3.加载操作系统
4.Bootloadershell
二、Bootloader Shell 支持的命令
1.help 帮助,显示所有支持的命令,及命令格式
2.loadx 下载文件到开发板的内存,默认到0x32000000
3.led_on 点亮一个led灯
4.led_off 关闭一个led灯
5.led_test 测试所有led灯,全亮全灭循环3次
6.beep_test 测试蜂鸣器,响3声
7.seg7_test 测试7段数码管
8.dip4_test 测试4位拨码开关
9.flash_load 将NandFlash中的文件搬移到SDARAM中
10.flash_write 将SDRAM中的内容下载到NandFlash中
11.GO 跳到某地址执行,默认到0x32000000
三、文件结构
1.start.s 程序入口,负责硬件初始化,Bootloader自搬移
2.uart.c uart.h 串口驱动的实现
3.load.c 选择加载操作系统还是进入Shell
4.stdlib.h stdlib.c 标准库函数的实现
5.stdio.h stdio.c 标准输入输出函数的实现
6.shell.c shell.h shell命令的实现
7.dip4.h dip4.c 拨码开关相关底层函数
8.seg7.h seg7.c 7段数码管相关底层函数
9.copy_myself.c nan.h NandFlash底层函数
10.xmodem.h xmodem.c xmodem协议实现
11.Datatype.h 数据定义
12.os/os.c 模拟操作系统
13.Makefile
四、流程及设计思想
1.硬件初始化
2.Bootloader自搬移
3.延时,判断是否有输入
4.(1)无输入则加载操作系统,操作系统烧写于Nand Flash的第100块,即位于100*32*512 = 0x190000
操作系统加载到内存的Sdram中
(2)有输入则进入shell命令模式
5.解释命令,使用自己实现的标准库函数来匹配输入的命令
6.匹配函数,定义了一个包含字符指针以及函数指针的结构体,可以通过对应关系迅速调用命令对应的函数
所有函数为void fun(void *)形式。
五、测试条件及结果
1. 打开超级终端,给开发板上电,超级终端上打印提示信息
2. 超级终端上开始3秒倒计时,3秒内不动键盘,提示加载操作系统,模拟操作系统的闪灯程序运行,可观察到LED等一闪一灭
3. 重启开发板,3秒内按下任意键,可看到有T-Boot#提示符,程序进入Shell模式
4. 输入help,可看到10条命令的使用方法
5. 输入led_on 1可看到第一个led灯亮
6. 输入led_off 1可看到第一个led灯灭
7. 输入led_test 可看到所有led一闪一灭3次
8. 输入beep_test 可听到蜂鸣器响3声
9. 输入seg7_test 可看到7段数码管每个led循环点亮
10.输入dip4_test 拨动拨码开关可观察到7段数码管对应的LED亮
11.输入loadx,发送文件0x/0s.bin
12.输入go 0x32000000 可观察到led灯一亮一灭
13.输入flash_load 0x190000 0x32000000 0x1000 (0x190000模拟操作系统烧写位置)
14.go 0x32000000 可观察到led一亮一灭
16.输入flash_write 0x32000000 0x200000 0x1000
17.输入flash_load 0x200000 0x31500000 0x1000
18.输入go 0x31500000 可观察到led灯一亮一灭
六、函数接口及功能
1.底层接口函数
uart.h
void uart_init(void); 初始化串口
void uart_putc(char ch); 打印一个字符到终端
char uart_getc(void); 从终端接收一个字符
void uart_test(void); 串口测试
void sdram_test(void); sdram测试
nand.h
void reset_nand(void); 重置串口
void init_nand(void); 初始化串口
int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size);
读nand flash 第一个参数为需要存放书籍的内存首地址, 第二个参数为nand_flash的首地址,第三个参数为需要拷贝的大小
int nand_write_ll(unsigned char *buf, unsigned long start_addr, int size);
写nand flash 第一个参数为需要存放书籍的内存首地址, 第二个参数为nand_flash的首地址,第三个参数为需要拷贝的大小
dip.h
int dip_init(void); 初始化
int dip_num(void); 显示数字
int dip_test(void); 测试
seg7.h
int seg7_init(void); 初始化
int seg7_display_num(int num);显示数字
int seg7_test(void); 测试
2.库函数
stdio.h
char * uart_gets(char *buf); 打印字符串
void uart_puts(char *str); 接收字符串
void uart_printf(const char *str, ...);格式化输出
void uart_put_num(int num,int pow);打印数字
stdlib.h
int my_strcmp(char *src, char *dst);比较字符串,相等返回0
int my_atoi(char *str);转换字符串为数字
char * found_ch(char *str, char ch);在一个字符串中寻找一个字符
int my_strlen(char *str);计算字符串长度
int is_number(char ch);一个字符是否数字
int pow(int num, int power);计算num的power次方
int my_atox(char *str);将一个字符串按16进制转为数字
3.协议
xmodem.h
int xmodem_receive(int argc, char *argv);
int get_record(void);
4.其他
命令对应的解释函数,为方便调用参数均为void *
void help(void *argv);
void go(void *argv);
void loadx(void *argv);
void beep_test(void *argv);
void led_off(void *argv);
void led_on(void *argv);
void seg7_on(void *argv);
void dip4_on(void *argv);
void shell(void);
void led_test(void * argv);
void flash_load(void *argv);
void flash_write(void *argv);
void delay(int);
2.start.s
- ;s3c2440 bootloader
- ;author: tongxiaohua
- ;time : 2009.12.22
- AREA FIRST, CODE, READONLY
- ENTRY
- CODE32
- IMPORT uart_test
- IMPORT sdram_test
- START
- WatchDog
- ;Close WatchDog
- LDR R0, =0X53000000
- MOV R1, #0X0
- STR R1, [R0]
- Led_on
- ;Make a Led on
- LDR R2, =0x20800000
- MOV R4, #0X1
- STRB R4, [R2]
- ;BL DELAY
- Beep_off
- ;Close Beep
- ;Control GPB0 output
- LDR R0, =0x56000010
- MOV R1, #0X1
- STR R1, [R0]
- LDR R0, =0X56000014
- MOV R1, #0X0
- STR R1, [R0]
- Interrupt_off
- ;CLose Interrupt
- LDR R0, =0X4A000008
- LDR R1, =0XFFFFFFFF
- STR R1, [R0]
- Init_Clock
- ; Init Clock
- ; Set Mode
- MRC p15,0,R1,c1,c0,0
- ORR R1,R1,#0XC0000000
- MCR p15,0,R1,c1,c0,0
- ;CAMDIVN
- ;When Config the register CLKDIVN Nedd This Configre
- LDR R0,=0x4c000018
- MOV R1,#0x0
- STR R1,[r0]
- ;LOCKTIME PLL
- LDR R0,=0x4c000000
- LDR R1,=0x00ffffff
- STR R1,[r0]
- ;UPLLCON
- LDR R0,=0x4c000008
- LDR R1,=0x00038022
- STR R1,[R0]
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- NOP
- ;MPLLCON
- LDR R0,=0x4c000004
- LDR R1,=0x00044011
- STR R1,[r0]
- ;CLKCON
- ;Witch divice need Clock
- LDR R0,=0x4c00000c
- LDR R1,=0x00fffff0
- STR R1,[R0]
- ;CLKSLOW
- ;Low Clock
- LDR R0,=0x4c000010
- LDR R1,=0x00000004
- STR R1,[R0]
- ;CLKDIVN
- ;HCLK = FCLK/3 PCLK = HCLK/2
- LDR R0,=0x4c000014
- LDR R1,=0x00000007
- STR R1,[R0]
- ;Uart0
- ;Uart
- ;LDR SP, =0x1000
- ;LDR R2, =0x20800000
- ;MOV R4, #0X7
- ;STRB R4, [R2]
- ;BL uart_test
- Memsetup
- ;SDRAM Init
- ldr r1,=MEM_CTL_BASE
- adrl r2,mem_cfg_val
- add r3,r1,#52
- 1
- ldr r4,[r2],#4
- str r4,[r1],#4
- cmp r1,r3
- bne %1
- nop
- nop
- nop
- nop
- MEM_CTL_BASE EQU 0X48000000
- mem_cfg_val
- DCD 0x22111110
- DCD 0x00000700
- DCD 0x00000700
- DCD 0x00000700
- DCD 0x00000700
- DCD 0x00000700
- DCD 0x00000700
- DCD 0X00018005
- DCD 0X00018005
- DCD 0X008E0459
- DCD 0X000000B1
- DCD 0X00000030
- DCD 0X00000030
- Nandflash
- ;NandFlash,Bootloader CopyMyself
- ldr sp,=0x33ef0000
- IMPORT copy_myself
- ;nand_begin=0x0
- ;size=0x20000
- ;sdram_begin=0x33f00000
- BL copy_myself
- ldr r1,=on_the_ram
- add pc,r1,#0
- nop
- nop
- nop
- on_the_ram
- ;Select mode
- IMPORT load
- ldr sp,=0x33ef0000
- BL uart_test
- BL sdram_test
- BL load
- B .
- END
2.Copy_myself.c
- /* NAND Flash registers 2440*/
- #include "DataType.h"
- #include "stdio.h"
- #define NFCONF (*(volatile unsigned int *)0x4e000000)
- #define NFCONT (*(volatile unsigned int *)0x4e000004)
- #define NFCMD (*(volatile unsigned char *)0x4e000008)
- #define NFADDR (*(volatile unsigned char *)0x4e00000c)
- #define NFDATA (*(volatile unsigned char *)0x4e000010)
- #define NFSTAT (*(volatile unsigned char *)0x4e000020)
- #define NFMECC0 (*(volatile unsigned *)0x4E00002C)
- #define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))
- #define NAND_CHIP_DISABLE (NFCONT |= (1<<1))
- #define NAND_CLEAR_RB (NFSTAT |= (1<<2))
- #define NAND_DETECT_RB { while(! (NFSTAT&(1<<0)) );}
- /* 在第一次实用NAND Flash前,复位一下NAND Flash */
- #define BUSY 1
- #define InitEcc() (NFCONT |= (1<<4))
- #define MEccUnlock() (NFCONT &= ~(1<<5))
- #define MEccLock() (NFCONT |= (1<<5))
- #define SEccUnlock() (NFCONT &= ~(1<<6))
- #define SEccLock() (NFCONT |= (1<<6))
- /*for 8 bit nand flash, only use NFMECC0*/
- #define RdNFMEcc() (NFMECC0)
- #define NAND_SECTOR_SIZE 512
- #define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
- /*
- inline void wait_idle(void)
- {
- while(!(NFSTAT & BUSY));
- NFSTAT |= BUSY;
- }
- */
- void reset_nand(void)
- {
- //int i=0;
- // NFCONF &= ~0x800;
- // for(; i<10; i++);
- NFCONF = 0x1400;
- NFCONT = 0x73;
- NAND_CHIP_ENABLE;
- NFCMD = 0xff; //reset command
- while(!(NFSTAT & BUSY));
- NFSTAT |= BUSY;
- }
- /* 初始化NAND Flash */
- void init_nand(void)
- {
- NFCONT = 0x73;
- NAND_CHIP_DISABLE;
- reset_nand();
- }
- /* low level nand read function */
- int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
- {
- int i, j;
- if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
- return -1; /* invalid alignment */
- }
- NAND_CHIP_ENABLE;
- for(i=start_addr; i < (start_addr + size);) {
- /* READ0 */
- NAND_CLEAR_RB;
- NFCMD = 0;
- /* Write Address */
- NFADDR = i & 0xff;
- NFADDR = (i >> 9) & 0xff;
- NFADDR = (i >> 17) & 0xff;
- NFADDR = (i >> 25) & 0xff;
- NAND_DETECT_RB;
- for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
- *buf = (NFDATA & 0xff);
- buf++;
- }
- }
- NAND_CHIP_DISABLE;
- return 0;
- }
- int NandErase(unsigned long start_addr)
- {
- if (start_addr & NAND_BLOCK_MASK) {
- return -1; /* invalid alignment */
- }
- NAND_CHIP_ENABLE;
- NAND_CLEAR_RB;
- NFCMD = 0x60;
- NFADDR = (start_addr>> 9) & 0xff;
- NFADDR = (start_addr>> 17) & 0xff;
- NFADDR = (start_addr>> 25) & 0xff;
- NFCMD = 0xd0;
- NAND_DETECT_RB;
- uart_printf("Erase 0x%x/r",start_addr);
- NAND_CHIP_DISABLE;
- return 0;
- }
- int nand_write_ll(unsigned char *buf, unsigned long start_addr, int size)
- {
- int i, j, k;
- if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
- return -1; /* invalid alignment */
- }
- for(k = 0; k <= size / (16 * 1024); k++)
- NandErase(start_addr + (k * 16 * 1024));
- NAND_CHIP_ENABLE;
- for(i=start_addr; i < (start_addr + size);) {
- /* READ0 */
- // if(k % 32 == 0) NandErase(start_addr);
- NAND_CLEAR_RB;
- NFCMD = 0x80;
- /* Write Address */
- NFADDR = i & 0xff;
- NFADDR = (i >> 9) & 0xff;
- NFADDR = (i >> 17) & 0xff;
- NFADDR = (i >> 25) & 0xff;
- for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
- NFDATA = *buf;
- buf++;
- }
- NFCMD = 0x10;
- NAND_DETECT_RB;
- }
- NAND_CHIP_DISABLE;
- return 0;
- }
- void copy_myself(void)
- {
- unsigned char *buf = ((unsigned char *)0x33f00000);
- unsigned long start_addr = 0;
- int size = 0x20000;
- reset_nand();
- init_nand();
- nand_read_ll(buf,start_addr,size);
- }
3.dip.c
- /*
- * dip.c - dip api & driver
- *
- * Board: akae2440
- * environment: bootloader & ADS
- * Author: akaedu
- * Date: 2009-5-26
- * web: www.akaedu.org
- *
- *
- * GPIO address_MAP
- *
- * CPLD_MAP_BASE physical address is 0x20800000
- * CPLD_LED physical address is 0x20800000
- * CPLD_SEG physical address is 0x20800080
- * CPLD_DIP physical address is 0x208000a0
- *
- * GPIO port_MAP
- *
- * GPA_PORT~GPB_PORT(130 multi-functional input port pins)
- * GPIO_BASE : GPACON : 0x56000000
- *
- * NAME GPIO CPLD_IN CPLD_OUT GPIO_CON MODE_bit_CON GPIO_DAT MODE_bit_DAT
- * BEEP GPB0 TOUT0 BEEP 0x56000010 [1:0] 0x56000014 [0]
- *
- * GPIO key_scn_MAP
- *
- * NAME PORT_OUT PORT_IN
- * KEY(sw1) KBOUT1 : GPB8 KBIN1 : ENT0 : GPF0
- * KEY(sw2) KBOUT0 : GPB9 KBIN1 : ENT0 : GPF0
- * KEY(sw3) KBOUT1 : GPB8 KBIN0 : ENT2 : GPF2
- * KEY(sw4) KBOUT1 : GPB8 KBIN1 : ENT2 : GPF2
- *
- * GPIO_CON GPIO_DAT GPIO MODE_bit_CON MODE_bit_DAT
- * GPBCON : 0x56000010 GPBDAT : 0x56000014 GPB8 [17:16] [8]
- * GPBCON : 0x56000010 GPBDAT : 0x56000014 GPB9 [19:18] [9]
- * GPFCON : 0x56000050 GPBDAT : 0x56000054 GPF0 [1:0] [0]
- * GPFCON : 0x56000050 GPBDAT : 0x56000054 GPF2 [5:4] [2]
- *
- */
- #include "dip.h"
- #include "seg7.h"
- #define CPLD_DIP *((volatile unsigned char *)0x208000a0)
- int dip_init(void)
- {
- return 0;
- }
- int dip_num(void)
- {
- return CPLD_DIP;
- }
- int dip_test(void)
- {
- int dip_input;
- int i = 5000000;
- seg7_init();
- dip_init();
- while(i--)
- {
- dip_input = dip_num();
- seg7_display_num(dip_input);
- }
- return 0;
- }
4.load.c
- #include "uart.h"
- #include "shell.h"
- #include "stdlib.h"
- #include "stdio.h"
- #include "nand.h"
- #define SEC 3
- #define LOAD_OS 0
- #define LOAD_SHELL 1
- #define OS_MEM_ADDR 0x31000000
- #define OS_ADDR (100 * 32 * 512) /*OS address*/
- #define OS_SIZE 0x20000
- /*Move OS to Sdram From NandFlash*/
- void os_test(void)
- {
- unsigned char *buf = (unsigned char *)OS_MEM_ADDR;
- unsigned long start = OS_ADDR;
- int size = OS_SIZE;
- uart_printf("/rcopy opration system to the sdrm from nanflash.../r");
- reset_nand();
- init_nand();
- nand_read_ll(buf, start, size);
- }
- /*Wait for User Enter Any Key to Login in the Shell of Bootloader*/
- int delay_p(int sec)
- {
- int osec = 500000, i, j;
- uart_printf("Enter any key to load in the shell of bootloader:%d", sec);
- for(i = 0; i < sec; i++)
- {
- for(j = 0; j < osec; j++)
- {
- if(UTRSTAT0 & UTRSTAT_R_READY){
- uart_getchar();
- return LOAD_SHELL;
- }
- }
- uart_printf("/b%d", sec - i);
- }
- //uart_printf("return");
- return LOAD_OS;
- }
- /*Shell or OS*/
- void load(void)
- {
- int load_stat;
- if((load_stat = delay_p(SEC)) == LOAD_OS)
- {
- os_test();
- uart_printf("/rrun in the oprition system.../r");
- go((void *)OS_MEM_ADDR);
- }
- else
- {
- shell();
- }
- }
5.seg7.c
- /*
- * seg7.c - seg7 api & driver
- *
- * Board: akae2440
- * environment: bootloader & ADS
- * Author: akaedu
- * Date: 2009-5-26
- * web: www.akaedu.org
- *
- *
- * GPIO address_MAP
- *
- * CPLD_MAP_BASE physical address is 0x20800000
- * CPLD_LED physical address is 0x20800000
- * CPLD_SEG7 physical address is 0x20800080
- * CPLD_DIP physical address is 0x208000a0
- *
- * GPIO port_MAP
- *
- * GPA_PORT~GPB_PORT(130 multi-functional input port pins)
- * GPIO_BASE : GPACON : 0x56000000
- *
- * NAME GPIO CPLD_IN CPLD_OUT GPIO_CON MODE_bit_CON GPIO_DAT MODE_bit_DAT
- * BEEP GPB0 TOUT0 BEEP 0x56000010 [1:0] 0x56000014 [0]
- *
- * GPIO key_scn_MAP
- *
- * NAME PORT_OUT PORT_IN
- * KEY(sw1) KBOUT1 : GPB8 KBIN1 : ENT0 : GPF0
- * KEY(sw2) KBOUT0 : GPB9 KBIN1 : ENT0 : GPF0
- * KEY(sw3) KBOUT1 : GPB8 KBIN0 : ENT2 : GPF2
- * KEY(sw4) KBOUT1 : GPB8 KBIN1 : ENT2 : GPF2
- *
- * GPIO_CON GPIO_DAT GPIO MODE_bit_CON MODE_bit_DAT
- * GPBCON : 0x56000010 GPBDAT : 0x56000014 GPB8 [17:16] [8]
- * GPBCON : 0x56000010 GPBDAT : 0x56000014 GPB9 [19:18] [9]
- * GPFCON : 0x56000050 GPBDAT : 0x56000054 GPF0 [1:0] [0]
- * GPFCON : 0x56000050 GPBDAT : 0x56000054 GPF2 [5:4] [2]
- *
- */
- #include "seg7.h"
- #include "shell.h"
- #define CPLD_SEG7 *((volatile unsigned char *)0x20800080)
- /* delay for about one second */
- /*static void delay(int time)
- {
- int i, j;
- for(i = 0; i < time; i++)
- for(j = 0; j < 500000; j++)
- ;
- }*/
- int seg7_init(void)
- {
- CPLD_SEG7 = 0x0;
- return 0;
- }
- /* display number on seg7 */
- int seg7_display_num(int num)
- {
- CPLD_SEG7 = 1<<num;
- return 0;
- }
- int seg7_test(void)
- {
- int i;
- seg7_init();
- for(i = 0; i < 8; i++)
- {
- seg7_display_num(i);
- delay(1);
- }
- return 0;
- }
8.shell.c
- #include "shell.h"
- #include "uart.h"
- #include "stdlib.h"
- #include "stdio.h"
- #include "xmodem.h"
- #include "dip.h"
- #include "seg7.h"
- #include "nand.h"
- #define START_ADDR 0x30000000
- #define END_ADDR 0x34000000
- #define MAX_LINE 256
- #define CMD_NUM 11
- #define LED_NUM 8
- #define START_FLASH 0x0
- #define END_FLASH 0x40000000
- #define START_MEM 0x30000000
- #define END_MEM 0x34000000
- #define MAX_SIZE (END_MEM - START_MEM - 0x20000)
- #define LED_ADDR *((volatile unsigned int *)0x20800000)
- #define GPB0 *((volatile unsigned int *)0x56000010)
- #define BEEP *((volatile unsigned int *)0x56000014)
- /*delay*/
- void delay(int sec)
- {
- int i, j;
- for(i = 0; i < sec; i++)
- {
- for(j = 0; j < 500000; j++)
- ;
- }
- }
- struct CMD{
- char *cmd_line;
- void (*fun)(void *);
- }cmd[CMD_NUM] ={
- {"help", help},
- {"loadx", loadx},
- {"go", go},
- {"led_on", led_on},
- {"led_off", led_off},
- {"beep_test", beep_test},
- {"led_test", led_test},
- {"seg7_test", seg7_on},
- {"dip4_test", dip4_on},
- {"flash_load", flash_load},
- {"flash_write", flash_write},
- //{"flash_write", flash_write},
- };
- void flash_load(void *arg)
- {
- char *argv[4], *end;
- int flash_start, mem_start, size;
- argv[1] = arg;
- uart_printf("the arg is %s/r", arg);
- if((end = found_ch(arg, ' ')) == NULL)
- {
- uart_printf("Uaseage1: <flash_load> <flash address> <sdram address> <size>/r");
- return;
- }
- else
- {
- *end = '/0';
- end++;
- }
- argv[2] = end;
- if((end = found_ch(end, ' ')) == NULL)
- {
- uart_printf("Uaseage2: <flash_load> <flash address> <sdram address> <size>/r");
- return;
- }
- else
- {
- *end = '/0';
- end++;
- }
- argv[3] = end;
- if((flash_start = my_atox(argv[1])) < START_FLASH || (mem_start = my_atox(argv[2])) < START_MEM ||(size = my_atox(argv[3])) > MAX_SIZE || (mem_start + size) > END_MEM)
- {
- uart_printf("Access Violation: Please check your address/r");
- uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);
- }
- else
- { uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);
- nand_read_ll((unsigned char *)mem_start, flash_start, size);
- }
- }
- #if 1
- void flash_write(void *arg)
- {
- char *argv[4], *end;
- int flash_start, mem_start, size;
- argv[1] = arg;
- uart_printf("the arg is %s/r", arg);
- if((end = found_ch(arg, ' ')) == NULL)
- {
- uart_printf("Uaseage1: <flash_load> <sdram address> <flash address> <size>/r");
- return;
- }
- else
- {
- *end = '/0';
- end++;
- }
- argv[2] = end;
- if((end = found_ch(end, ' ')) == NULL)
- {
- uart_printf("Uaseage2: <flash_load> <sdram address> <flash address> <size>/r");
- return;
- }
- else
- {
- *end = '/0';
- end++;
- }
- argv[3] = end;
- if((flash_start = my_atox(argv[2])) < START_FLASH || (mem_start = my_atox(argv[1])) < START_MEM ||(size = my_atox(argv[3])) > MAX_SIZE || (mem_start + size) > END_MEM)
- {
- uart_printf("Access Violation: Please check your address/r");
- // reset_nand();
- // init_nand();
- uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);
- }
- else
- {
- uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);
- // reset_nand();
- // init_nand();
- nand_write_ll((unsigned char *)mem_start, flash_start, size);
- }
- }
- #endif
- void loadx(void * argv)
- {
- int argc;
- uart_printf("argv is %s/r",(char *)argv);
- if(argv != NULL) argc = 2;
- else argc = 1;
- if(found_ch(argv, ' ') != NULL)
- {
- uart_printf("Error: Usage <loadx> <address>/r");
- }
- else
- {
- xmodem_receive(argc, argv);
- uart_printf("Success!");
- }
- return;
- }
- void led_on(void * argv)
- {
- /*test 第3字节有效*/
- // uart_printf("%dnd led is on/r", (int)argv + 1);
- // LED_ADDR = 0xff0000;
- LED_ADDR |= (1 << ((int)argv + 16));
- }
- void led_off(void * argv)
- {
- // uart_printf("%dnd led is off/r", (int)argv + 1);
- LED_ADDR &= ~(1 << ((int)argv + 16));
- }
- void led_test(void * argv)
- {
- int i, j;
- for(i = 0; i < 3; i++ )
- {
- for(j = 0; j < LED_NUM; j++)
- {
- led_on((void *)j);
- }
- delay(1);
- for(j = 0; j < LED_NUM; j++)
- {
- led_off((void *)j);
- }
- delay(1);
- }
- }
- void beep_test(void *argv)
- {
- int i;
- GPB0 |= 0x1;
- for(i = 0; i < 3; i++)
- {
- BEEP = 0x1;
- delay(1);
- BEEP = 0x0;
- delay(1);
- }
- }
- void seg7_on(void *argv)
- {
- seg7_test();
- }
- void dip4_on(void * argv)
- {
- dip_test();
- }
- void help(void * argv)
- {
- uart_printf("loadx - [address], download a file to the borad/r");
- uart_printf("go - <address>, go to the addrress/r");
- uart_printf("flash_load - <flash address><sdram address><size>, Move the code to sdram from nandflash/r");
- uart_printf("flash_write - <sdram address><flash address><size>, Move the code to Nandflash from sdram/r");
- uart_printf("led_on - <led number>, test led/r");
- uart_printf("led_off - <led_number>, test_led/r");
- uart_printf("led_test - test all led/r");
- uart_printf("beep_test - test beep/r");
- uart_printf("seg7_test - test seg/r");
- uart_printf("dip4_test - test dip4, you have ten second to test it/r/r");
- }
- void go(void *argv)
- {
- int addr = (int)argv;
- if(addr == 0) addr = 0x32000000;
- // void (*gt)(void) = (void (*) (void))addr;
- if(addr < START_ADDR || addr > END_ADDR)
- {
- // return -1;
- }
- else
- {
- uart_printf("in go/r");
- (*(void (*) (void))addr)();
- }
- }
- void shellcmd(char buf[])
- {
- char *start, *end, *argv = NULL;
- int i, i_argv;
- start = buf;
- if((end = found_ch(buf, ' ')) != NULL)
- {
- *end = '/0';
- argv = end + 1;
- }
- // uart_printf("buf is before is%s/r",buf);
- // uart_printf("the command is %s", start);
- // uart_printf("the command is %s", cmd[0].cmd_line);
- for(i = 0; i < CMD_NUM; i++)
- {
- if(my_strcmp(start, cmd[i].cmd_line) == 0)
- {
- if(i == 3 || i == 4){
- i_argv = my_atoi(argv);
- // uart_printf("i_argv is %d/r", i_argv);
- (* cmd[i].fun)((void *) i_argv);
- }
- else if(i == 2)
- { i_argv = my_atox(argv);
- // uart_printf("i_argv is %x/r", i_argv);
- (* cmd[i].fun)((void *) i_argv);
- }
- else
- {
- (*cmd[i].fun)((void *) argv);
- }
- break;
- }
- }
- if(i == CMD_NUM)
- {
- uart_printf("Command not found/r");
- }
- }
- void shell(void)
- {
- char buf[MAX_LINE];
- while(1)
- {
- uart_puts("/rT-BOOT#");
- uart_gets(buf);
- // uart_printf("/rget the command/r");
- //uart_puts(buf);
- shellcmd(buf);
- }
- }
6.stdio.c
- #include <stdarg.h>
- #include "stdlib.h"
- #include "uart.h"
- #include "stdio.h"
- void uart_puts(char *str)
- {
- while(*str != '/0')
- {
- uart_putchar(*str);
- str++;
- }
- }
- char *uart_gets(char *str)
- {
- int i;
- if(str == NULL) return str;
- for(i = 0; ; i++)
- {
- str[i] = uart_getchar();
- /*do shomthing when '/b is input'*/
- if(str[i] == '/b')
- {
- if(i > 0){
- uart_putchar('/b');
- i -= 2;
- }
- else
- {
- i = -1;
- }
- }
- else
- {
- uart_putchar(str[i]);
- }
- if(str[i] == '/r' || str[i] == '/n')
- {
- str[i] = '/0';
- break;
- }
- }
- return str;
- }
- void uart_put_num(int num,int pow)
- {
- if(num != 0)
- {
- uart_put_num(num/pow, pow);
- if(num%pow > 9)
- uart_putchar((char)(num%pow - 10) + 'A');
- else
- uart_putchar((char)(num%pow + '0'));
- }
- }
- void uart_printf(const char *str, ...)
- {
- va_list ap;
- char c, ch;
- char * s; int num;
- va_start(ap, str);
- while(c = *str++)
- {
- if(c != '%')
- {
- uart_putchar(c);
- }
- else
- {
- c = *str++;
- switch(c)
- {
- case 'c':
- ch = va_arg(ap, int);
- uart_putchar((char)ch);
- break;
- case 's':
- s = va_arg(ap, char *);
- uart_puts(s);
- break;
- case 'd':
- num = va_arg(ap, int);
- uart_put_num(num, 10);
- break;
- case 'x':
- num = va_arg(ap, int);
- uart_put_num(num, 16);
- break;
- default:
- uart_putchar(c);
- }
- }
- }
- va_end(ap);
- }
6.stdlib.h
- #include "stdlib.h"
- #include "stdio.h"
- int my_strcmp(char *src, char *dst)
- {
- if(src == NULL || dst == NULL) goto exit;
- while(*src == *dst && *src!= '/0' && *dst != '/0')
- {
- src++;
- dst++;
- }
- exit:
- return (*src - *dst);
- }
- char *found_ch(char *str, char ch)
- {
- if(str == NULL) goto exit;
- while(*str != ch && *str != '/0')
- {
- str++;
- }
- exit:
- if(*str == ch) return str;
- else return NULL;
- }
- int my_strlen(char *str)
- {
- char *p = str;
- if(str == NULL) goto exit;
- while(*str != '/0')
- {
- str++;
- }
- exit:
- return (str - p);
- }
- int is_number(char ch)
- {
- if('0' <= ch && ch <= '9') return 1;
- else return 0;
- }
- int pow(int num, int power)
- {
- /*do not care about overflow*/
- int count = 1;
- while(power--)
- {
- count *= num;
- }
- return count;
- }
- int my_atoi(char *str)
- {
- int len = my_strlen(str), i, count = 0;
- // uart_printf("the str is %s/r", str);
- // uart_printf("len = %d/r", len);
- if(str == NULL) goto exit;
- // if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
- // str += 2;
- for(i = 0; i < len; i++)
- {
- if(!is_number(str[i])) goto exit;
- count += ((str[i] - '0')*pow(10, len - i - 1));
- }
- exit:
- return count;
- }
- int my_atox(char *str)
- {
- int len = my_strlen(str), i, count = 0;
- // uart_printf("the str is %s/r", str);
- // uart_printf("len = %d/r", len);
- if(str == NULL) goto exit;
- if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X')){
- str += 2;
- len -= 2;
- }
- for(i = 0; i < len; i++)
- {
- if(!is_number(str[i])) goto exit;
- count += ((str[i] - '0')*pow(16, len - i - 1));
- // uart_printf("the count is %x/r", count);
- }
- exit:
- return count;
- }
7.uart.c
- /*Uart Driver on S3C2440*/
- /*Athor: tongxiaohua */
- /*Time : 2009.12.27 */
- #include "uart.h"
- #include "stdlib.h"
- #include "stdio.h"
- #include "shell.h"
- /*Init Uart0*/
- void uart_init(void)
- {
- ULCON0 |= 3; /*8N1*/
- UCON0 = 5; /*Work Frequency Select PCLK, the mode of recive/send select poll*/
- UTRSTAT0 &= 6; /*Set Null of recive/send Buffer*/
- UBRDIV0 = 26; /*(int)50000000 / (115200*16) - 1*/
- GPHCON = 0xa0; /*Set F2, F3 Function*/
- UFCON0 = 0;
- UMCON0 = 0;
- }
- /*Put a byte to the Uart0*/
- void uart_putchar(char ch)
- {
- while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));
- UTX0 = ch;
- /*Back Space*/
- if(ch == '/b')
- {
- while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));
- UTX0 = ' ';
- while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));
- UTX0 = '/b';
- }
- /*Enter*/
- if(ch == '/r')
- {
- while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));
- UTX0 = '/n';
- }
- }
- /*Get a byte from Uart*/
- char uart_getchar(void)
- {
- while (!(UTRSTAT0 & UTRSTAT_R_READY));
- return URX0;
- }
- /*Test the Uart is or not Working*/
- void uart_test(void)
- {
- uart_init();
- uart_printf("/r/rWelecom to use my bootloader/rAuthor:tong xiaohua/rBoard:s3c2440/r");
- uart_printf("Time: 2009.12.27/rCPU: Arm 920T/rSRAM: 4k/rSDRAM:32M/rNAND FLASH:64M/r");
- uart_printf("Uart0 is working.../r");
- }
- /*Test the Sdram is or Not Working*/
- void sdram_test(void)
- {
- int testnum = 0x12345678;
- *((volatile unsigned int *)0x32000000) = testnum;
- testnum = *((volatile unsigned int *)0x32000000);
- if(testnum == 0x12345678)
- {
- // uart_printf("%x/r", testnum);
- uart_printf("sdram is working.../r");
- // uart_printf("test.../r");
- }
- else
- {
- // uart_printf("test faild/r");
- uart_printf("sdram working error.../r", testnum);
- // uart_printf("test.../r");
- }
- }
8.xmodem.c
- #include "xmodem.h"
- /* 这两个头文件是你已经实现的功能函数,下面
- * 代码中用到的函数如不是xmodem.c中定义的,
- * 需移植你已写好的函数接口到本程序中,如
- * uart0_getchar()、uart0_putchar()、
- * myprintf()等
- */
- #include "stdio.h"
- #include "uart.h"
- #include "stdlib.h"
- /* global error variable */
- char *xmodem_errtxt = NULL;
- int get_byte_err = 0;
- U8 volatile receive_buffer[BLOCK_SIZE];
- //unsigned download_addr = 0x8000;
- /* prototypes of helper functions */
- int get_record(void);
- enum
- {
- SAC_SEND_NAK = 0,
- SAC_SENT_NAK = 1,
- SAC_PAST_START_NAK = 2
- };
- static volatile int seen_a_char = SAC_SEND_NAK;
- //static int one_nak = 0;
- //static unsigned long xmodem_timeout = GET_BYTE_TIMEOUT;
- char debugbuf[4096];
- int db_idx = 0;
- static void delay(void)
- {
- int j;
- for (j = 0; j < 2000090; j++)
- ;
- }
- int xmodem_receive(int argc, char *argv)
- {
- char ochr;
- int r = 0, rx_block_num = 0, error_count = 0;
- int foffset = 0;
- int i;
- unsigned int download_addr;
- char nak = NAK;
- xmodem_errtxt = NULL;
- seen_a_char = 0;
- uart_printf("in xmodem argc = %d, argv = %s /r", argc, argv);
- // if(argc > 1) download_addr = atox(argv[1]);
- if(argc > 1) download_addr = my_atox(argv);
- else download_addr = 0x32000000;
- uart_printf("download_addr is %x," , download_addr);
- UART0_putchar('9');
- delay();
- UART0_putchar('8');
- delay();
- UART0_putchar('7');
- delay();
- UART0_putchar('6');
- delay();
- UART0_putchar('5');
- delay();
- UART0_putchar('4');
- delay();
- UART0_putchar('3');
- delay();
- UART0_putchar('2');
- delay();
- UART0_putchar('1');
- delay();
- UART0_putchar('0');
- //uart_putchar(UART0_BASE, nak);
- UART0_putchar(nak);
- rx_block_num = 1;
- /* times to retry */
- error_count = RETRIES;
- do {
- /* when local block number equals to the block number in the packet,
- store the data into the memory which download_addr points*/
- if ((r = get_record()) == (rx_block_num & 255)) {
- error_count = RETRIES;
- for (i = 0; i <BLOCK_SIZE; i++)
- *(U8 *)(download_addr+foffset+i) = receive_buffer[i];
- xmodem_errtxt = "RX PACKET";
- rx_block_num++;
- ochr = ACK;
- foffset += BLOCK_SIZE;
- } else {
- switch (r) {
- case -1: /* TIMEOUT */
- xmodem_errtxt = "TIMEOUT";
- ochr = NAK;
- break;
- case -2: /* Bad block */
- xmodem_errtxt = "BAD BLOCK#";
- /* eat teh rest of the block */
- #if 0
- get_byte_err = 0;
- while (get_byte_err != -1) get_byte();
- #endif
- ochr = NAK;
- break;
- case -3: /* Bad checksum */
- xmodem_errtxt = "BAD CHKSUM";
- ochr = NAK;
- break;
- case -4: /* End of file */
- xmodem_errtxt = "DONE";
- ochr = ACK;
- break;
- case -5: /* Cancel */
- xmodem_errtxt = "ABORTED";
- ochr = ACK;
- break;
- default: /* Block out of sequence */
- xmodem_errtxt = "WRONG BLK";
- ochr = NAK;
- }
- error_count--;
- }
- UART0_putchar(ochr);
- } while ((r > -3) && error_count);
- if ((!error_count) || (r != -4)) {
- foffset = 0; /* indicate failure to caller */
- }
- my_printf( "Loaded file at address 0x%x, size = %d /r/n",(int)download_addr, foffset);
- return foffset;
- }
- /*
- * Read a record in the XMODEM protocol, return the block number
- * (0-255) if successful, or one of the following return codes:
- * -1 = Bad byte
- * -2 = Bad block number
- * -3 = Bad block checksum
- * -4 = End of file
- * -5 = Canceled by remote
- */
- int get_record(void)
- {
- char c;
- int block_num = 0;
- int i;
- U32 check_sum;
- /* clear the buffer */
- for (i = 0; i < BLOCK_SIZE; i++)
- receive_buffer[i] = 0x00;
- check_sum = 0;
- /* initialize i to -2,when begin to transfer,the first byte
- will be store into blcok_num,and after plused one,the next
- byte will be treated as a negated section */
- i = -2;
- //uart_getchar( UART0_BASE, &c);
- c = UART0_getchar();
- switch (c)
- {
- case SOH: /* Receive packet */
- for (;;)
- {
- //uart_getchar( UART0_BASE, &c);
- c = UART0_getchar();
- switch (i)
- {
- case -2:
- block_num = c;
- break;
- case -1:
- #if 0
- #ifdef CHECK_NEGATED_SECTNUM
- if (c != (-block_num -1))
- return -2;
- #endif
- #endif
- break;
- case BLOCK_SIZE:
- /* check if reveived data is correct,
- when correct,block num is returned,
- else -3 is returned */
- if ((check_sum & 0xff) != c)
- return -3;
- else
- return block_num;
- break;
- default:
- /* save data to buffer,and accumulate to check_sum */
- receive_buffer[i] = c;
- check_sum += c;
- }
- i++;
- }
- case EOT: /* end of file encountered */
- return -4;
- case CAN: /* cancel protocol */
- return -5;
- default:
- return -5;
- }
- }
- 最小bootloader的实现,完整源代码
- MSP430F5438A BootLoader的实现
- 快速排序的基本实现(完整源代码)
- s3c2410的Bootloader(Vivi)源代码分析
- s3c2410的Bootloader(Vivi)源代码分析
- 8051的bootloader实现方式
- 播放声音文件的完整源代码
- 完整msk的MATLAB源代码
- 求格雷码的完整程序源代码
- 众数的完整程序源代码
- 实现进程隐藏(完整源代码)
- java实现电脑远程控制完整源代码
- Bootloader(Vivi)源代码分析
- Bootloader(Vivi)源代码分析
- Bootloader(Vivi)源代码分析
- 基于arm和linux的bootloader源代码下载
- bootloader实现
- 面试题:较为完整的atoi的实现,奶牛苹果的最小搬运次数
- 开始学习Android
- 做项目了!!
- 文字移动代码
- OPhone SDK
- 傅立叶变换的物理意义(转)
- 最小bootloader的实现,完整源代码
- 电源、滤波器、放大器PCB
- 迎新年LAMP兄弟连第一场免费在线讲座:Linux略窥门径
- WINCOSK编程没有了
- C#基础
- 5.定时
- 程序员小幽默
- 浮点数比较
- 看完《蜗居》,感觉很空虚