最小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

 

Code:
  1.     ;s3c2440 bootloader  
  2.     ;author: tongxiaohua  
  3.     ;time :  2009.12.22  
  4.       
  5.     AREA FIRST, CODE, READONLY  
  6.     ENTRY  
  7.     CODE32  
  8.     IMPORT uart_test  
  9.     IMPORT sdram_test  
  10.       
  11. START  
  12.   
  13. WatchDog  
  14.   ;Close WatchDog  
  15.     LDR R0, =0X53000000  
  16.     MOV R1, #0X0  
  17.     STR R1, [R0]  
  18.       
  19. Led_on  
  20.     ;Make a Led on  
  21.     LDR R2,  =0x20800000  
  22.     MOV R4,  #0X1  
  23.     STRB R4, [R2]  
  24.       
  25.     ;BL DELAY  
  26.   
  27. Beep_off  
  28.     ;Close Beep  
  29.     ;Control GPB0 output  
  30.     LDR R0, =0x56000010  
  31.     MOV R1, #0X1  
  32.     STR R1, [R0]  
  33.       
  34.     LDR R0, =0X56000014  
  35.     MOV R1, #0X0  
  36.     STR R1, [R0]  
  37.   
  38. Interrupt_off  
  39.     ;CLose Interrupt  
  40.     LDR R0, =0X4A000008  
  41.     LDR R1, =0XFFFFFFFF  
  42.     STR R1, [R0]  
  43.       
  44. Init_Clock  
  45.   
  46.     ; Init Clock    
  47.     ; Set Mode  
  48.     MRC p15,0,R1,c1,c0,0                    
  49.     ORR R1,R1,#0XC0000000  
  50.     MCR p15,0,R1,c1,c0,0  
  51.       
  52.     ;CAMDIVN  
  53.     ;When Config the register CLKDIVN Nedd This Configre  
  54.     LDR R0,=0x4c000018  
  55.     MOV R1,#0x0  
  56.     STR R1,[r0]  
  57.       
  58.       
  59.     ;LOCKTIME PLL  
  60.     LDR R0,=0x4c000000  
  61.     LDR R1,=0x00ffffff  
  62.     STR R1,[r0]  
  63.       
  64.     ;UPLLCON  
  65.     LDR R0,=0x4c000008  
  66.     LDR R1,=0x00038022  
  67.     STR R1,[R0]  
  68.     NOP  
  69.     NOP  
  70.     NOP  
  71.     NOP  
  72.     NOP  
  73.     NOP  
  74.     NOP  
  75.       
  76.     ;MPLLCON  
  77.     LDR R0,=0x4c000004  
  78.     LDR R1,=0x00044011  
  79.     STR R1,[r0]  
  80.       
  81.     ;CLKCON  
  82.     ;Witch divice need Clock  
  83.     LDR R0,=0x4c00000c  
  84.     LDR R1,=0x00fffff0  
  85.     STR R1,[R0]  
  86.       
  87.     ;CLKSLOW  
  88.     ;Low Clock  
  89.     LDR R0,=0x4c000010  
  90.     LDR R1,=0x00000004  
  91.     STR R1,[R0]  
  92.       
  93.     ;CLKDIVN  
  94.     ;HCLK = FCLK/3  PCLK = HCLK/2  
  95.     LDR R0,=0x4c000014  
  96.     LDR R1,=0x00000007  
  97.     STR R1,[R0]  
  98.       
  99. ;Uart0    
  100.     ;Uart  
  101.     ;LDR SP, =0x1000  
  102.     ;LDR R2,  =0x20800000  
  103.     ;MOV R4,  #0X7  
  104.     ;STRB R4, [R2]  
  105.     ;BL uart_test  
  106.   
  107. Memsetup  
  108.       
  109.     ;SDRAM Init  
  110.     ldr r1,=MEM_CTL_BASE    
  111.     adrl r2,mem_cfg_val     
  112.     add r3,r1,#52  
  113.   
  114. 1  
  115.     ldr r4,[r2],#4  
  116.     str r4,[r1],#4  
  117.     cmp r1,r3  
  118.     bne %1  
  119.     nop  
  120.     nop  
  121.     nop  
  122.     nop  
  123.   
  124. MEM_CTL_BASE EQU 0X48000000  
  125.   
  126. mem_cfg_val  
  127.     DCD 0x22111110  
  128.     DCD 0x00000700  
  129.     DCD 0x00000700  
  130.     DCD 0x00000700  
  131.     DCD 0x00000700  
  132.     DCD 0x00000700  
  133.     DCD 0x00000700  
  134.     DCD 0X00018005  
  135.     DCD 0X00018005  
  136.     DCD 0X008E0459  
  137.     DCD 0X000000B1  
  138.     DCD 0X00000030  
  139.     DCD 0X00000030    
  140.   
  141.   
  142. Nandflash  
  143.       
  144.     ;NandFlash,Bootloader CopyMyself  
  145.     ldr sp,=0x33ef0000  
  146.       
  147.     IMPORT copy_myself  
  148.       
  149. ;nand_begin=0x0   
  150. ;size=0x20000  
  151. ;sdram_begin=0x33f00000  
  152.       
  153.     BL copy_myself  
  154.       
  155.         ldr r1,=on_the_ram  
  156.     add pc,r1,#0  
  157.     nop  
  158.     nop  
  159.     nop  
  160.   
  161. on_the_ram  
  162.   
  163.     ;Select mode      
  164.     IMPORT load  
  165.     ldr sp,=0x33ef0000  
  166.     BL uart_test  
  167.     BL sdram_test  
  168.     BL load  
  169.       
  170.     B .  
  171.       
  172.     END  

2.Copy_myself.c

Code:
  1. /* NAND Flash registers 2440*/  
  2. #include "DataType.h"  
  3. #include "stdio.h"  
  4. #define NFCONF    (*(volatile unsigned int *)0x4e000000)  
  5. #define NFCONT    (*(volatile unsigned int *)0x4e000004)  
  6. #define NFCMD    (*(volatile unsigned char *)0x4e000008)  
  7. #define NFADDR    (*(volatile unsigned char *)0x4e00000c)  
  8. #define NFDATA    (*(volatile unsigned char *)0x4e000010)  
  9. #define NFSTAT    (*(volatile unsigned char *)0x4e000020)  
  10. #define NFMECC0 (*(volatile unsigned *)0x4E00002C)  
  11. #define NAND_CHIP_ENABLE (NFCONT &= ~(1<<1))  
  12. #define NAND_CHIP_DISABLE (NFCONT |= (1<<1))  
  13. #define NAND_CLEAR_RB (NFSTAT |= (1<<2))  
  14. #define NAND_DETECT_RB { while(! (NFSTAT&(1<<0)) );}  
  15. /* 在第一次实用NAND Flash前,复位一下NAND Flash */  
  16. #define BUSY 1  
  17. #define InitEcc()       (NFCONT |= (1<<4))  
  18. #define MEccUnlock()    (NFCONT &= ~(1<<5))  
  19. #define MEccLock()      (NFCONT |= (1<<5))  
  20. #define SEccUnlock()    (NFCONT &= ~(1<<6))  
  21. #define SEccLock()      (NFCONT |= (1<<6))  
  22.   
  23. /*for 8 bit nand flash, only use NFMECC0*/  
  24. #define RdNFMEcc()      (NFMECC0)  
  25. #define NAND_SECTOR_SIZE 512  
  26. #define NAND_BLOCK_MASK  (NAND_SECTOR_SIZE - 1)  
  27.   
  28. /* 
  29.    inline void wait_idle(void)  
  30.    { 
  31.    while(!(NFSTAT & BUSY)); 
  32.    NFSTAT |= BUSY; 
  33.    } 
  34.    */  
  35.   
  36.   
  37. void reset_nand(void)  
  38. {  
  39.     //int i=0;  
  40.     // NFCONF &= ~0x800;  
  41.     //     for(; i<10; i++);  
  42.   
  43.     NFCONF = 0x1400;  
  44.     NFCONT = 0x73;  
  45.   
  46.     NAND_CHIP_ENABLE;  
  47.   
  48.     NFCMD = 0xff; //reset command  
  49.   
  50.     while(!(NFSTAT & BUSY));  
  51.     NFSTAT |= BUSY;  
  52. }  
  53.   
  54.   
  55. /* 初始化NAND Flash */  
  56.   
  57. void init_nand(void)  
  58. {  
  59.   
  60.     NFCONT = 0x73;  
  61.     NAND_CHIP_DISABLE;  
  62.     reset_nand();  
  63. }  
  64.   
  65. /* low level nand read function */  
  66. int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)  
  67. {  
  68.     int i, j;  
  69.   
  70.     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {  
  71.         return -1; /* invalid alignment */  
  72.     }  
  73.   
  74.     NAND_CHIP_ENABLE;  
  75.   
  76.     for(i=start_addr; i < (start_addr + size);) {  
  77.         /* READ0 */  
  78.         NAND_CLEAR_RB;  
  79.         NFCMD = 0;  
  80.   
  81.         /* Write Address */  
  82.         NFADDR = i & 0xff;  
  83.         NFADDR = (i >> 9) & 0xff;  
  84.         NFADDR = (i >> 17) & 0xff;  
  85.         NFADDR = (i >> 25) & 0xff;  
  86.   
  87.         NAND_DETECT_RB;  
  88.   
  89.         for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {  
  90.             *buf = (NFDATA & 0xff);  
  91.             buf++;  
  92.         }  
  93.   
  94.     }  
  95.     NAND_CHIP_DISABLE;  
  96.     return 0;  
  97. }  
  98.   
  99.   
  100. int NandErase(unsigned long start_addr)  
  101. {  
  102.     if (start_addr & NAND_BLOCK_MASK) {  
  103.             return -1; /* invalid alignment */  
  104.     }  
  105.   
  106.     NAND_CHIP_ENABLE;  
  107.   
  108.     NAND_CLEAR_RB;  
  109.         NFCMD = 0x60;  
  110.   
  111.         NFADDR = (start_addr>> 9) & 0xff;  
  112.         NFADDR = (start_addr>> 17) & 0xff;  
  113.         NFADDR = (start_addr>> 25) & 0xff;  
  114.   
  115.   
  116.           
  117.     NFCMD = 0xd0;  
  118.     NAND_DETECT_RB;  
  119.     uart_printf("Erase 0x%x/r",start_addr);   
  120.   
  121.     NAND_CHIP_DISABLE;  
  122.   
  123.     return 0;  
  124. }  
  125.   
  126. int nand_write_ll(unsigned char *buf, unsigned long start_addr, int size)  
  127. {  
  128.     int i, j, k;  
  129.   
  130.     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {  
  131.         return -1; /* invalid alignment */  
  132.     }  
  133.     for(k = 0; k <= size / (16 * 1024); k++)  
  134.         NandErase(start_addr + (k * 16 * 1024));  
  135.     NAND_CHIP_ENABLE;  
  136.   
  137.     for(i=start_addr; i < (start_addr + size);) {  
  138.         /* READ0 */  
  139.     //    if(k % 32 == 0)  NandErase(start_addr);  
  140.       
  141.     NAND_CLEAR_RB;  
  142.         NFCMD = 0x80;  
  143.   
  144.         /* Write Address */  
  145.         NFADDR = i & 0xff;  
  146.         NFADDR = (i >> 9) & 0xff;  
  147.         NFADDR = (i >> 17) & 0xff;  
  148.         NFADDR = (i >> 25) & 0xff;  
  149.   
  150.   
  151.         for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {  
  152.             NFDATA = *buf;  
  153.         buf++;  
  154.         }  
  155.     NFCMD = 0x10;  
  156.     NAND_DETECT_RB;  
  157.     }  
  158.     NAND_CHIP_DISABLE;  
  159.     return 0;  
  160. }  
  161.   
  162.   
  163. void copy_myself(void)  
  164. {  
  165.     unsigned char *buf = ((unsigned char *)0x33f00000);  
  166.     unsigned long start_addr = 0;  
  167.     int size = 0x20000;  
  168.   
  169.     reset_nand();  
  170.     init_nand();  
  171.     nand_read_ll(buf,start_addr,size);  
  172.   
  173. }  

3.dip.c

Code:
  1. /* 
  2.  *    dip.c  -  dip api & driver 
  3.  * 
  4.  *    Board:        akae2440 
  5.  *    environment:  bootloader & ADS 
  6.  *    Author:       akaedu 
  7.  *    Date:         2009-5-26 
  8.  *    web:          www.akaedu.org 
  9.  * 
  10.  *     
  11.  *    GPIO address_MAP 
  12.  *     
  13.  *    CPLD_MAP_BASE physical address is 0x20800000       
  14.  *    CPLD_LED      physical address is 0x20800000       
  15.  *    CPLD_SEG      physical address is 0x20800080 
  16.  *    CPLD_DIP      physical address is 0x208000a0 
  17.  * 
  18.  *    GPIO port_MAP 
  19.  * 
  20.  *    GPA_PORT~GPB_PORT(130 multi-functional input port pins) 
  21.  *    GPIO_BASE :   GPACON  :   0x56000000   
  22.  * 
  23.  *    NAME          GPIO        CPLD_IN     CPLD_OUT    GPIO_CON        MODE_bit_CON    GPIO_DAT        MODE_bit_DAT         
  24.  *    BEEP          GPB0        TOUT0       BEEP        0x56000010      [1:0]           0x56000014      [0] 
  25.  * 
  26.  *    GPIO key_scn_MAP 
  27.  * 
  28.  *    NAME          PORT_OUT            PORT_IN          
  29.  *    KEY(sw1)      KBOUT1 : GPB8       KBIN1 : ENT0 : GPF0              
  30.  *    KEY(sw2)      KBOUT0 : GPB9       KBIN1 : ENT0 : GPF0          
  31.  *    KEY(sw3)      KBOUT1 : GPB8       KBIN0 : ENT2 : GPF2              
  32.  *    KEY(sw4)      KBOUT1 : GPB8       KBIN1 : ENT2 : GPF2              
  33.  * 
  34.  *    GPIO_CON                      GPIO_DAT                GPIO        MODE_bit_CON        MODE_bit_DAT 
  35.  *    GPBCON : 0x56000010           GPBDAT : 0x56000014     GPB8        [17:16]             [8]          
  36.  *    GPBCON : 0x56000010           GPBDAT : 0x56000014     GPB9        [19:18]             [9]          
  37.  *    GPFCON : 0x56000050           GPBDAT : 0x56000054     GPF0        [1:0]               [0]          
  38.  *    GPFCON : 0x56000050           GPBDAT : 0x56000054     GPF2        [5:4]               [2]          
  39.  * 
  40.  */  
  41. #include "dip.h"  
  42. #include "seg7.h"  
  43.   
  44. #define CPLD_DIP        *((volatile unsigned char *)0x208000a0)  
  45.   
  46. int dip_init(void)  
  47. {  
  48.     return 0;  
  49. }  
  50. int dip_num(void)  
  51. {  
  52.     return CPLD_DIP;  
  53. }  
  54.   
  55. int dip_test(void)  
  56. {  
  57.     int dip_input;  
  58.     int i = 5000000;      
  59.     seg7_init();  
  60.     dip_init();  
  61.       
  62.     while(i--)  
  63.     {  
  64.         dip_input = dip_num();  
  65.         seg7_display_num(dip_input);  
  66.     }  
  67.       
  68.     return 0;  
  69. }  

4.load.c

Code:
  1. #include "uart.h"  
  2. #include "shell.h"  
  3. #include "stdlib.h"  
  4. #include "stdio.h"  
  5. #include "nand.h"  
  6.   
  7. #define SEC 3  
  8. #define LOAD_OS 0  
  9. #define LOAD_SHELL 1  
  10. #define OS_MEM_ADDR 0x31000000  
  11. #define OS_ADDR (100 * 32 * 512) /*OS address*/  
  12. #define OS_SIZE 0x20000  
  13.   
  14. /*Move OS to Sdram From NandFlash*/  
  15. void os_test(void)  
  16. {  
  17.   
  18.     unsigned char *buf = (unsigned char *)OS_MEM_ADDR;  
  19.     unsigned long start = OS_ADDR;  
  20.     int size = OS_SIZE;  
  21.   
  22.     uart_printf("/rcopy opration system to the sdrm from nanflash.../r");  
  23.   
  24.     reset_nand();  
  25.     init_nand();  
  26.     nand_read_ll(buf, start, size);  
  27.   
  28. }  
  29.   
  30. /*Wait for User Enter Any Key to Login in the Shell of Bootloader*/  
  31. int delay_p(int sec)  
  32. {  
  33.     int osec = 500000, i, j;  
  34.       
  35.     uart_printf("Enter any key to load in the shell of bootloader:%d", sec);  
  36.     for(i = 0; i < sec; i++)  
  37.     {  
  38.         for(j = 0; j < osec; j++)  
  39.         {  
  40.             if(UTRSTAT0 & UTRSTAT_R_READY){  
  41.                 uart_getchar();  
  42.                 return LOAD_SHELL;  
  43.             }     
  44.         }  
  45.   
  46.         uart_printf("/b%d", sec - i);  
  47.     }  
  48.     //uart_printf("return");  
  49.     return LOAD_OS;  
  50. }  
  51.   
  52. /*Shell or OS*/  
  53. void load(void)  
  54. {  
  55.     int load_stat;  
  56.       
  57.     if((load_stat = delay_p(SEC)) == LOAD_OS)  
  58.     {  
  59.         os_test();  
  60.         uart_printf("/rrun in the oprition system.../r");  
  61.         go((void *)OS_MEM_ADDR);  
  62.     }  
  63.     else  
  64.     {  
  65.         shell();  
  66.     }  
  67. }  

5.seg7.c

Code:
  1. /* 
  2.  *    seg7.c  -  seg7 api & driver 
  3.  * 
  4.  *    Board:        akae2440 
  5.  *    environment:  bootloader & ADS 
  6.  *    Author:       akaedu 
  7.  *    Date:         2009-5-26 
  8.  *    web:          www.akaedu.org 
  9.  * 
  10.  *     
  11.  *    GPIO address_MAP 
  12.  *     
  13.  *    CPLD_MAP_BASE physical address is 0x20800000       
  14.  *    CPLD_LED      physical address is 0x20800000       
  15.  *    CPLD_SEG7     physical address is 0x20800080 
  16.  *    CPLD_DIP      physical address is 0x208000a0 
  17.  * 
  18.  *    GPIO port_MAP 
  19.  * 
  20.  *    GPA_PORT~GPB_PORT(130 multi-functional input port pins) 
  21.  *    GPIO_BASE :   GPACON  :   0x56000000   
  22.  * 
  23.  *    NAME          GPIO        CPLD_IN     CPLD_OUT    GPIO_CON        MODE_bit_CON    GPIO_DAT        MODE_bit_DAT         
  24.  *    BEEP          GPB0        TOUT0       BEEP        0x56000010      [1:0]           0x56000014      [0] 
  25.  * 
  26.  *    GPIO key_scn_MAP 
  27.  * 
  28.  *    NAME          PORT_OUT            PORT_IN          
  29.  *    KEY(sw1)      KBOUT1 : GPB8       KBIN1 : ENT0 : GPF0              
  30.  *    KEY(sw2)      KBOUT0 : GPB9       KBIN1 : ENT0 : GPF0          
  31.  *    KEY(sw3)      KBOUT1 : GPB8       KBIN0 : ENT2 : GPF2              
  32.  *    KEY(sw4)      KBOUT1 : GPB8       KBIN1 : ENT2 : GPF2              
  33.  * 
  34.  *    GPIO_CON                      GPIO_DAT                GPIO        MODE_bit_CON        MODE_bit_DAT 
  35.  *    GPBCON : 0x56000010           GPBDAT : 0x56000014     GPB8        [17:16]             [8]          
  36.  *    GPBCON : 0x56000010           GPBDAT : 0x56000014     GPB9        [19:18]             [9]          
  37.  *    GPFCON : 0x56000050           GPBDAT : 0x56000054     GPF0        [1:0]               [0]          
  38.  *    GPFCON : 0x56000050           GPBDAT : 0x56000054     GPF2        [5:4]               [2]          
  39.  * 
  40.  */  
  41. #include "seg7.h"  
  42. #include "shell.h"  
  43.   
  44. #define CPLD_SEG7          *((volatile unsigned char *)0x20800080)  
  45.   
  46.   
  47. /* delay for about one second */  
  48. /*static void delay(int time)    
  49. { 
  50.     int i, j; 
  51.  
  52.     for(i = 0; i < time; i++) 
  53.         for(j = 0; j < 500000; j++) 
  54.             ; 
  55. }*/  
  56.   
  57. int seg7_init(void)  
  58. {  
  59.     CPLD_SEG7 = 0x0;  
  60.       
  61.     return 0;  
  62. }  
  63.   
  64. /* display  number on seg7 */  
  65. int seg7_display_num(int num)  
  66. {  
  67.     CPLD_SEG7 = 1<<num;  
  68.       
  69.     return 0;  
  70. }  
  71.   
  72. int seg7_test(void)  
  73. {  
  74.     int i;    
  75.       
  76.     seg7_init();  
  77.     for(i = 0; i < 8; i++)  
  78.     {  
  79.         seg7_display_num(i);  
  80.         delay(1);  
  81.     }     
  82.     return 0;  
  83. }    

8.shell.c

Code:
  1. #include "shell.h"  
  2. #include "uart.h"  
  3. #include "stdlib.h"  
  4. #include "stdio.h"  
  5. #include "xmodem.h"  
  6. #include "dip.h"  
  7. #include "seg7.h"  
  8. #include "nand.h"  
  9.   
  10. #define START_ADDR 0x30000000  
  11. #define END_ADDR 0x34000000  
  12. #define MAX_LINE 256  
  13. #define CMD_NUM 11  
  14. #define LED_NUM 8  
  15. #define START_FLASH 0x0  
  16. #define END_FLASH 0x40000000  
  17. #define START_MEM 0x30000000  
  18. #define END_MEM 0x34000000  
  19. #define MAX_SIZE (END_MEM - START_MEM - 0x20000)  
  20. #define LED_ADDR *((volatile unsigned int *)0x20800000)  
  21. #define GPB0     *((volatile unsigned int *)0x56000010)  
  22. #define BEEP     *((volatile unsigned int *)0x56000014)  
  23.   
  24. /*delay*/  
  25. void delay(int sec)  
  26. {  
  27.     int i, j;  
  28.     for(i = 0; i < sec; i++)  
  29.     {  
  30.         for(j = 0; j < 500000; j++)  
  31.             ;  
  32.     }  
  33. }  
  34.   
  35. struct CMD{  
  36.     char *cmd_line;  
  37.         void (*fun)(void *);      
  38. }cmd[CMD_NUM] ={  
  39.     {"help", help},  
  40.     {"loadx", loadx},  
  41.     {"go", go},  
  42.     {"led_on", led_on},  
  43.     {"led_off", led_off},  
  44.     {"beep_test", beep_test},  
  45.     {"led_test", led_test},  
  46.     {"seg7_test", seg7_on},  
  47.     {"dip4_test", dip4_on},  
  48.     {"flash_load", flash_load},  
  49.     {"flash_write", flash_write},  
  50. //{"flash_write", flash_write},  
  51. };  
  52.   
  53.   
  54. void flash_load(void *arg)  
  55. {  
  56.     char *argv[4], *end;  
  57.     int flash_start, mem_start, size;  
  58.   
  59.     argv[1] = arg;  
  60.     uart_printf("the arg is %s/r", arg);  
  61.     if((end = found_ch(arg, ' ')) == NULL)  
  62.     {  
  63.         uart_printf("Uaseage1: <flash_load> <flash address> <sdram address> <size>/r");  
  64.         return;  
  65.     }  
  66.     else  
  67.     {  
  68.         *end = '/0';  
  69.         end++;  
  70.     }  
  71.   
  72.     argv[2] = end;  
  73.     if((end = found_ch(end, ' ')) == NULL)  
  74.     {  
  75.         uart_printf("Uaseage2: <flash_load> <flash address> <sdram address> <size>/r");  
  76.         return;  
  77.     }  
  78.     else  
  79.     {  
  80.         *end = '/0';  
  81.         end++;  
  82.     }  
  83.       
  84.     argv[3] = end;    
  85.   
  86.     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)  
  87.     {  
  88.         uart_printf("Access Violation: Please check your address/r");  
  89.         uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);  
  90.     }  
  91.     else  
  92.     {   uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);  
  93.         nand_read_ll((unsigned char *)mem_start, flash_start, size);      
  94.     }     
  95. }  
  96. #if 1  
  97. void flash_write(void *arg)  
  98. {  
  99.     char *argv[4], *end;  
  100.     int flash_start, mem_start, size;  
  101.   
  102.     argv[1] = arg;  
  103.     uart_printf("the arg is %s/r", arg);  
  104.     if((end = found_ch(arg, ' ')) == NULL)  
  105.     {  
  106.         uart_printf("Uaseage1: <flash_load> <sdram address> <flash address> <size>/r");  
  107.         return;  
  108.     }  
  109.     else  
  110.     {  
  111.         *end = '/0';  
  112.         end++;  
  113.     }  
  114.   
  115.     argv[2] = end;  
  116.     if((end = found_ch(end, ' ')) == NULL)  
  117.     {  
  118.         uart_printf("Uaseage2: <flash_load> <sdram address> <flash address> <size>/r");  
  119.         return;  
  120.     }  
  121.     else  
  122.     {  
  123.         *end = '/0';  
  124.         end++;  
  125.     }  
  126.       
  127.     argv[3] = end;    
  128.   
  129.     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)  
  130.     {  
  131.         uart_printf("Access Violation: Please check your address/r");  
  132.     //  reset_nand();  
  133.     //  init_nand();  
  134.         uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);  
  135.     }  
  136.     else  
  137.     {  
  138.         uart_printf("flash_start = %x/rmem_start = %x/r size = %x/r", flash_start, mem_start, size);  
  139.     //  reset_nand();  
  140.     //  init_nand();  
  141.         nand_write_ll((unsigned char *)mem_start, flash_start, size);     
  142.     }     
  143. }  
  144.   
  145. #endif  
  146.   
  147. void loadx(void * argv)  
  148. {  
  149.     int argc;  
  150.   
  151.     uart_printf("argv is %s/r",(char *)argv);  
  152.     if(argv != NULL) argc = 2;  
  153.     else             argc = 1;  
  154.   
  155.     if(found_ch(argv, ' ') != NULL)  
  156.     {  
  157.         uart_printf("Error: Usage <loadx> <address>/r");  
  158.     }  
  159.     else  
  160.     {  
  161.         xmodem_receive(argc, argv);   
  162.         uart_printf("Success!");  
  163.     }  
  164.       
  165.     return;  
  166.           
  167. }  
  168.   
  169. void led_on(void * argv)  
  170. {  
  171.     /*test 第3字节有效*/  
  172. //  uart_printf("%dnd led is on/r", (int)argv + 1);  
  173. //  LED_ADDR = 0xff0000;  
  174.     LED_ADDR |= (1 << ((int)argv + 16));  
  175. }  
  176.   
  177. void led_off(void * argv)  
  178. {  
  179. //  uart_printf("%dnd led is off/r", (int)argv + 1);  
  180.     LED_ADDR &= ~(1 << ((int)argv + 16));  
  181. }  
  182.   
  183. void led_test(void * argv)  
  184. {  
  185.     int i, j;  
  186.     for(i = 0; i < 3; i++ )  
  187.     {  
  188.         for(j = 0; j < LED_NUM; j++)  
  189.         {  
  190.             led_on((void *)j);  
  191.         }  
  192.         delay(1);  
  193.         for(j = 0; j < LED_NUM; j++)  
  194.         {  
  195.             led_off((void *)j);  
  196.         }  
  197.         delay(1);  
  198.     }  
  199. }  
  200.   
  201. void beep_test(void *argv)  
  202. {  
  203.     int i;  
  204.       
  205.     GPB0 |= 0x1;  
  206.       
  207.     for(i = 0; i < 3; i++)  
  208.     {  
  209.         BEEP = 0x1;  
  210.         delay(1);  
  211.         BEEP = 0x0;  
  212.         delay(1);  
  213.     }  
  214.   
  215. }  
  216.   
  217. void seg7_on(void *argv)  
  218. {  
  219.     seg7_test();  
  220. }  
  221.   
  222. void dip4_on(void * argv)  
  223. {  
  224.     dip_test();  
  225. }  
  226.   
  227. void help(void * argv)  
  228. {  
  229.   
  230.     uart_printf("loadx        - [address], download a file to the borad/r");  
  231.     uart_printf("go           - <address>, go to the addrress/r");  
  232.     uart_printf("flash_load   - <flash address><sdram address><size>, Move the code to sdram from nandflash/r");  
  233.     uart_printf("flash_write  - <sdram address><flash address><size>, Move the code to Nandflash from sdram/r");  
  234.     uart_printf("led_on       - <led number>, test led/r");  
  235.     uart_printf("led_off      - <led_number>, test_led/r");  
  236.     uart_printf("led_test     -  test all led/r");  
  237.     uart_printf("beep_test    - test beep/r");  
  238.     uart_printf("seg7_test    - test seg/r");  
  239.     uart_printf("dip4_test    - test dip4, you have ten second to test it/r/r");  
  240. }  
  241.   
  242. void go(void *argv)  
  243. {  
  244.     int addr = (int)argv;  
  245.     if(addr == 0) addr = 0x32000000;  
  246.     //  void (*gt)(void) = (void (*) (void))addr;  
  247.     if(addr < START_ADDR || addr > END_ADDR)  
  248.     {  
  249.     //  return -1;  
  250.     }  
  251.     else  
  252.     {  
  253.         uart_printf("in go/r");  
  254.         (*(void (*) (void))addr)();   
  255.     }  
  256. }  
  257.   
  258. void shellcmd(char buf[])  
  259. {  
  260.     char *start, *end, *argv = NULL;  
  261.     int i, i_argv;  
  262.   
  263.     start = buf;  
  264.       
  265.     if((end = found_ch(buf, ' ')) != NULL)  
  266.     {  
  267.         *end = '/0';  
  268.         argv = end + 1;  
  269.     }  
  270.   
  271. //  uart_printf("buf is before is%s/r",buf);  
  272. //  uart_printf("the command is %s", start);  
  273. //  uart_printf("the command is %s", cmd[0].cmd_line);  
  274.   
  275.     for(i = 0; i < CMD_NUM; i++)  
  276.     {  
  277.         if(my_strcmp(start, cmd[i].cmd_line) == 0)  
  278.         {     
  279.             if(i == 3 || i == 4){  
  280.                 i_argv = my_atoi(argv);  
  281. //              uart_printf("i_argv is %d/r", i_argv);  
  282.                 (* cmd[i].fun)((void *) i_argv);  
  283.             }  
  284.             else if(i == 2)  
  285.             {   i_argv = my_atox(argv);  
  286. //              uart_printf("i_argv is %x/r", i_argv);  
  287.                 (* cmd[i].fun)((void *) i_argv);              
  288.             }  
  289.             else  
  290.             {  
  291.                 (*cmd[i].fun)((void *) argv);  
  292.             }  
  293.             break;  
  294.         }  
  295.     }  
  296.     if(i == CMD_NUM)  
  297.     {  
  298.         uart_printf("Command not found/r");  
  299.     }  
  300. }  
  301.   
  302. void shell(void)  
  303. {  
  304.     char buf[MAX_LINE];  
  305.   
  306.     while(1)  
  307.     {  
  308.         uart_puts("/rT-BOOT#");  
  309.         uart_gets(buf);  
  310. //      uart_printf("/rget the command/r");  
  311.         //uart_puts(buf);  
  312.         shellcmd(buf);  
  313.     }  
  314. }  

6.stdio.c

Code:
  1. #include <stdarg.h>  
  2. #include "stdlib.h"  
  3. #include "uart.h"  
  4. #include "stdio.h"  
  5.   
  6. void uart_puts(char *str)  
  7. {  
  8.     while(*str != '/0')  
  9.     {  
  10.         uart_putchar(*str);  
  11.         str++;  
  12.     }  
  13. }  
  14.   
  15. char *uart_gets(char *str)  
  16. {  
  17.     int i;  
  18.     if(str == NULL) return str;  
  19.       
  20.     for(i = 0; ; i++)  
  21.     {  
  22.         str[i] = uart_getchar();  
  23.   
  24.         /*do shomthing when '/b is input'*/  
  25.         if(str[i] == '/b')  
  26.         {  
  27.             if(i > 0){  
  28.                 uart_putchar('/b');  
  29.                 i -= 2;  
  30.             }  
  31.             else  
  32.             {  
  33.                 i = -1;  
  34.             }  
  35.         }  
  36.         else  
  37.         {  
  38.             uart_putchar(str[i]);  
  39.         }  
  40.         if(str[i] == '/r' || str[i] == '/n')  
  41.         {  
  42.             str[i] = '/0';  
  43.             break;  
  44.         }  
  45.     }  
  46.   
  47.     return str;  
  48. }  
  49.   
  50. void uart_put_num(int num,int pow)  
  51. {  
  52.     if(num != 0)  
  53.     {  
  54.         uart_put_num(num/pow, pow);  
  55.         if(num%pow > 9)  
  56.             uart_putchar((char)(num%pow - 10) + 'A');  
  57.         else  
  58.             uart_putchar((char)(num%pow + '0'));  
  59.     }  
  60. }  
  61.   
  62.   
  63. void uart_printf(const char *str, ...)  
  64. {  
  65.     va_list ap;  
  66.     char c, ch;   
  67.     char * s; int num;  
  68.       
  69.     va_start(ap, str);  
  70.     while(c = *str++)  
  71.     {  
  72.         if(c != '%')  
  73.         {  
  74.             uart_putchar(c);  
  75.         }  
  76.         else  
  77.         {  
  78.             c = *str++;  
  79.             switch(c)  
  80.             {  
  81.                 case 'c':  
  82.                     ch = va_arg(ap, int);  
  83.                     uart_putchar((char)ch);  
  84.                     break;  
  85.                 case 's':  
  86.                     s = va_arg(ap, char *);  
  87.                     uart_puts(s);  
  88.                     break;  
  89.                 case 'd':  
  90.                   num = va_arg(ap, int);  
  91.                     uart_put_num(num, 10);  
  92.                     break;  
  93.                 case 'x':  
  94.                   num = va_arg(ap, int);  
  95.                     uart_put_num(num, 16);  
  96.                     break;  
  97.                 default:  
  98.                     uart_putchar(c);  
  99.             }  
  100.         }  
  101.     }  
  102.     va_end(ap);  
  103. }  

6.stdlib.h

Code:
  1. #include "stdlib.h"  
  2. #include "stdio.h"  
  3.   
  4. int my_strcmp(char *src, char *dst)  
  5. {  
  6.     if(src == NULL || dst == NULL) goto exit;  
  7.   
  8.     while(*src == *dst && *src!= '/0' && *dst != '/0')  
  9.     {  
  10.         src++;  
  11.         dst++;  
  12.     }  
  13.   
  14. exit:  
  15.     return (*src - *dst);  
  16. }  
  17.   
  18. char *found_ch(char *str, char ch)  
  19. {  
  20.     if(str == NULL) goto exit;  
  21.   
  22.     while(*str != ch && *str != '/0')  
  23.     {  
  24.         str++;  
  25.     }  
  26.   
  27. exit:  
  28.     if(*str == ch) return str;  
  29.     else           return NULL;  
  30. }  
  31.   
  32. int my_strlen(char *str)  
  33. {  
  34.     char *p = str;  
  35.   
  36.     if(str == NULL) goto exit;  
  37.   
  38.     while(*str != '/0')  
  39.     {  
  40.         str++;  
  41.     }  
  42. exit:  
  43.     return (str - p);  
  44. }  
  45.   
  46. int is_number(char ch)  
  47. {  
  48.     if('0' <= ch && ch <= '9'return 1;  
  49.     else            return 0;  
  50. }  
  51.   
  52. int pow(int num, int power)  
  53. {  
  54.     /*do not care about overflow*/  
  55.     int count = 1;  
  56.   
  57.     while(power--)  
  58.     {  
  59.         count *= num;  
  60.     }  
  61.   
  62.     return count;  
  63. }  
  64.   
  65. int my_atoi(char *str)  
  66. {  
  67.     int len = my_strlen(str), i, count = 0;  
  68.   
  69. //  uart_printf("the str is %s/r", str);  
  70. //  uart_printf("len = %d/r", len);  
  71.   
  72.     if(str == NULL) goto exit;  
  73.   
  74. //  if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))  
  75. //      str += 2;  
  76.       
  77.     for(i = 0; i < len; i++)  
  78.     {  
  79.         if(!is_number(str[i])) goto exit;  
  80.   
  81.         count += ((str[i] - '0')*pow(10, len - i - 1));  
  82.     }  
  83.           
  84. exit:  
  85.     return count;  
  86. }  
  87.   
  88. int my_atox(char *str)  
  89. {  
  90.     int len = my_strlen(str), i, count = 0;  
  91.   
  92. //  uart_printf("the str is %s/r", str);  
  93. //  uart_printf("len = %d/r", len);  
  94.   
  95.     if(str == NULL) goto exit;  
  96.   
  97.     if(*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X')){  
  98.         str += 2;  
  99.         len -= 2;  
  100.     }  
  101.     for(i = 0; i < len; i++)  
  102.     {  
  103.         if(!is_number(str[i])) goto exit;  
  104.   
  105.         count += ((str[i] - '0')*pow(16, len - i - 1));  
  106. //      uart_printf("the count is %x/r", count);  
  107.     }  
  108.           
  109. exit:  
  110.     return count;  
  111. }  

7.uart.c

Code:
  1. /*Uart Driver on S3C2440*/  
  2. /*Athor: tongxiaohua    */  
  3. /*Time : 2009.12.27     */  
  4. #include "uart.h"  
  5. #include "stdlib.h"  
  6. #include "stdio.h"  
  7. #include "shell.h"  
  8.   
  9.   
  10. /*Init Uart0*/  
  11. void uart_init(void)  
  12. {  
  13.     ULCON0 |= 3;    /*8N1*/  
  14.     UCON0   = 5;    /*Work Frequency Select PCLK, the mode of recive/send select poll*/  
  15.     UTRSTAT0 &= 6;  /*Set Null of recive/send Buffer*/  
  16.     UBRDIV0 = 26;   /*(int)50000000 / (115200*16) - 1*/  
  17.     GPHCON = 0xa0;  /*Set F2, F3 Function*/   
  18.     UFCON0 = 0;  
  19.     UMCON0 = 0;  
  20. }  
  21.   
  22. /*Put a byte to the Uart0*/  
  23. void uart_putchar(char ch)  
  24. {  
  25.     while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));  
  26.     UTX0 = ch;  
  27.       
  28.     /*Back Space*/        
  29.     if(ch == '/b')  
  30.     {  
  31.         while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));  
  32.         UTX0 = ' ';  
  33.         while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));  
  34.         UTX0 = '/b';  
  35.     }  
  36.       
  37.     /*Enter*/  
  38.     if(ch == '/r')  
  39.     {     
  40.       while (!(UTRSTAT0 & UTRSTAT_T_EMPTY));  
  41.         UTX0 = '/n';          
  42.     }  
  43. }  
  44.   
  45. /*Get a byte from Uart*/  
  46. char uart_getchar(void)  
  47. {   
  48.     while (!(UTRSTAT0 & UTRSTAT_R_READY));  
  49.     return URX0;      
  50. }  
  51.   
  52. /*Test the Uart is or not Working*/  
  53. void uart_test(void)  
  54. {  
  55.     uart_init();  
  56.     uart_printf("/r/rWelecom to use my bootloader/rAuthor:tong xiaohua/rBoard:s3c2440/r");  
  57.     uart_printf("Time: 2009.12.27/rCPU: Arm 920T/rSRAM: 4k/rSDRAM:32M/rNAND FLASH:64M/r");    
  58.     uart_printf("Uart0 is working.../r");  
  59. }  
  60.   
  61. /*Test the Sdram is or Not Working*/  
  62. void sdram_test(void)  
  63. {  
  64.     int testnum = 0x12345678;  
  65.     *((volatile unsigned int *)0x32000000) = testnum;  
  66.     testnum = *((volatile unsigned int *)0x32000000);  
  67.     if(testnum == 0x12345678)  
  68.     {  
  69. //      uart_printf("%x/r", testnum);  
  70.         uart_printf("sdram is working.../r");  
  71. //      uart_printf("test.../r");  
  72.     }  
  73.     else  
  74.     {  
  75. //      uart_printf("test faild/r");  
  76.         uart_printf("sdram working error.../r", testnum);  
  77. //      uart_printf("test.../r");  
  78.     }  
  79. }  

8.xmodem.c

Code:
  1. #include "xmodem.h"  
  2. /* 这两个头文件是你已经实现的功能函数,下面 
  3. *  代码中用到的函数如不是xmodem.c中定义的, 
  4. *  需移植你已写好的函数接口到本程序中,如 
  5. *  uart0_getchar()、uart0_putchar()、 
  6. *  myprintf()等 
  7. */  
  8. #include "stdio.h"  
  9. #include "uart.h"  
  10. #include "stdlib.h"  
  11.   
  12.   
  13. /* global error variable */  
  14. char *xmodem_errtxt = NULL;  
  15. int get_byte_err = 0;  
  16. U8 volatile receive_buffer[BLOCK_SIZE];  
  17. //unsigned download_addr = 0x8000;  
  18. /* prototypes of helper functions */  
  19. int get_record(void);  
  20.   
  21. enum  
  22. {  
  23.     SAC_SEND_NAK = 0,  
  24.     SAC_SENT_NAK = 1,  
  25.     SAC_PAST_START_NAK = 2  
  26. };  
  27.   
  28. static volatile int seen_a_char = SAC_SEND_NAK;  
  29.   
  30. //static int one_nak = 0;  
  31. //static unsigned long xmodem_timeout = GET_BYTE_TIMEOUT;  
  32.   
  33. char debugbuf[4096];  
  34. int db_idx = 0;  
  35.   
  36. static void delay(void)  
  37. {  
  38.     int j;  
  39.     for (j = 0; j < 2000090; j++)  
  40.         ;  
  41. }  
  42.   
  43.  int xmodem_receive(int argc, char *argv)  
  44. {  
  45.     char ochr;  
  46.     int r = 0, rx_block_num = 0, error_count = 0;  
  47.     int foffset = 0;  
  48.     int i;  
  49.     unsigned int download_addr;  
  50.     char nak = NAK;  
  51.   
  52.     xmodem_errtxt = NULL;  
  53.     seen_a_char = 0;  
  54.       
  55.     uart_printf("in xmodem argc = %d, argv = %s /r", argc, argv);     
  56.       
  57. //  if(argc > 1) download_addr = atox(argv[1]);  
  58.     if(argc > 1) download_addr = my_atox(argv);  
  59.     else download_addr = 0x32000000;  
  60.   
  61.     uart_printf("download_addr is %x," , download_addr);  
  62.   
  63.     UART0_putchar('9');   
  64.     delay();  
  65.     UART0_putchar('8');  
  66.     delay();  
  67.     UART0_putchar('7');  
  68.     delay();  
  69.     UART0_putchar('6');  
  70.     delay();  
  71.     UART0_putchar('5');   
  72.     delay();  
  73.     UART0_putchar('4');  
  74.     delay();  
  75.     UART0_putchar('3');  
  76.     delay();  
  77.     UART0_putchar('2');  
  78.     delay();  
  79.     UART0_putchar('1');  
  80.     delay();  
  81.     UART0_putchar('0');  
  82.       
  83.     //uart_putchar(UART0_BASE, nak);  
  84.     UART0_putchar(nak);  
  85.       
  86.     rx_block_num = 1;  
  87.   
  88.     /* times to retry */  
  89.     error_count = RETRIES;  
  90.   
  91.     do {  
  92.         /* when local block number equals to the block number in the packet, 
  93.             store the data into the memory which download_addr points*/  
  94.         if ((r = get_record()) == (rx_block_num & 255)) {  
  95.             error_count = RETRIES;  
  96.             for (i = 0; i <BLOCK_SIZE; i++)  
  97.                 *(U8 *)(download_addr+foffset+i) = receive_buffer[i];  
  98.             xmodem_errtxt = "RX PACKET";  
  99.             rx_block_num++;  
  100.             ochr = ACK;  
  101.             foffset += BLOCK_SIZE;  
  102.         } else {  
  103.             switch (r) {  
  104.             case -1: /* TIMEOUT */  
  105.                 xmodem_errtxt = "TIMEOUT";  
  106.                 ochr = NAK;  
  107.                 break;  
  108.             case -2: /* Bad block */  
  109.                 xmodem_errtxt = "BAD BLOCK#";  
  110.                 /* eat teh rest of the block */  
  111. #if 0  
  112.                 get_byte_err = 0;  
  113.                 while (get_byte_err != -1) get_byte();  
  114. #endif  
  115.                 ochr = NAK;  
  116.                 break;  
  117.             case -3: /* Bad checksum */  
  118.                 xmodem_errtxt = "BAD CHKSUM";  
  119.                 ochr = NAK;  
  120.                 break;  
  121.             case -4: /* End of file */  
  122.                 xmodem_errtxt = "DONE";  
  123.                 ochr = ACK;  
  124.                 break;  
  125.             case -5: /* Cancel */  
  126.                 xmodem_errtxt = "ABORTED";  
  127.                 ochr = ACK;  
  128.                 break;  
  129.             default/* Block out of sequence */  
  130.                 xmodem_errtxt = "WRONG BLK";  
  131.                 ochr = NAK;  
  132.             }  
  133.             error_count--;  
  134.         }  
  135.   
  136.         UART0_putchar(ochr);  
  137.     } while ((r > -3) && error_count);  
  138.   
  139.     if ((!error_count) || (r != -4)) {  
  140.         foffset = 0;    /* indicate failure to caller */  
  141.     }  
  142.     my_printf( "Loaded file at address 0x%x, size = %d /r/n",(int)download_addr, foffset);  
  143.   
  144.     return foffset;  
  145. }  
  146.   
  147. /* 
  148.  * Read a record in the XMODEM protocol, return the block number 
  149.  * (0-255) if successful, or one of the following return codes: 
  150.  *  -1 = Bad byte 
  151.  *  -2 = Bad block number 
  152.  *  -3 = Bad block checksum 
  153.  *  -4 = End of file 
  154.  *  -5 = Canceled by remote 
  155.  */  
  156. int get_record(void)  
  157. {  
  158.     char c;   
  159.     int block_num = 0;  
  160.     int i;  
  161.   
  162.     U32 check_sum;  
  163.   
  164.     /* clear the buffer */  
  165.     for (i = 0; i < BLOCK_SIZE; i++)  
  166.         receive_buffer[i] = 0x00;  
  167.   
  168.     check_sum = 0;  
  169.   
  170.     /* initialize i to -2,when begin to transfer,the first byte 
  171.        will be store into blcok_num,and after plused one,the next 
  172.        byte will be treated as a negated section */  
  173.     i = -2;  
  174.     //uart_getchar( UART0_BASE, &c);  
  175.     c = UART0_getchar();  
  176.   
  177.     switch (c)   
  178.     {  
  179.         case SOH:   /* Receive packet */  
  180.             for (;;)   
  181.             {  
  182.                 //uart_getchar( UART0_BASE, &c);  
  183.                 c = UART0_getchar();  
  184.   
  185.                 switch (i)   
  186.                 {  
  187.                     case -2:   
  188.                         block_num = c;  
  189.                         break;  
  190.                   
  191.                     case -1:  
  192. #if 0  
  193. #ifdef CHECK_NEGATED_SECTNUM  
  194.                 if (c != (-block_num -1))  
  195.                     return -2;  
  196. #endif  
  197. #endif  
  198.                         break;  
  199.                     case BLOCK_SIZE:  
  200.                     /* check if reveived data is correct, 
  201.                     when correct,block num is returned, 
  202.                      else -3 is returned */  
  203.                         if ((check_sum & 0xff) != c)  
  204.                             return -3;  
  205.                         else  
  206.                             return block_num;  
  207.                         break;  
  208.                       
  209.                     default:  
  210.                     /* save data to buffer,and accumulate to check_sum */  
  211.                         receive_buffer[i] = c;  
  212.                         check_sum += c;  
  213.                 }  
  214.                 i++;  
  215.             }  
  216.     case EOT:   /* end of file encountered */  
  217.         return -4;  
  218.     case CAN:   /* cancel protocol */  
  219.         return -5;  
  220.     default:  
  221.         return -5;  
  222.     }  
  223. }  

 

原创粉丝点击