📄 tftpdl.c
字号:
#include <target/io.h>#include <target/herrno.h>#include <target/flash.h>#include "mmu.h"#include "memregions.h"#include "board.h"#include "tftpdl.h"#include <target/net/eth.h>#include <target/net/tftp.h>#include <target/net/eth_util.h>#include "eth_ep93xx.h"typedef struct tftpdl_option_info{ unsigned char client_ipaddr[4]; unsigned char server_ipaddr[4]; char *bootloader_file; char *kernel_file; char *userland_file; char fake;}app_opt_info;//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int program_file(const unsigned long flash_base_addr, const int flash_start_sector_no, const unsigned long file_base_addr, const unsigned int file_size){ unsigned long flash_addr = flash_base_addr; unsigned long file_addr = file_base_addr; unsigned int program_size; unsigned int programed_len = 0; int sector = flash_start_sector_no; int ret; int i, j; int padding; for(i=0;;i++){ if(programed_len >= file_size) break; hprintf("#"); program_size = get_flash_sector_size(sector); if(programed_len + program_size > file_size){ char *tmp_addr; program_size = file_size - programed_len; padding = ((program_size % 4) ? (4 - (program_size % 4)) : 0); tmp_addr = (char *)(file_addr + program_size); for(j=0;j<padding;j++,tmp_addr++){ *tmp_addr = 0xff; } program_size += padding; }#ifdef DEBUG_ETH hprintf("erase: %p\n", flash_addr); hprintf("program: FLASH: %p, RAM: %p, size: %p(%d)\n", flash_addr, file_addr, program_size, program_size);#endif ret = flash_erase(flash_addr); if(ret != 0){ hprintf("\nerase error\n"); return ret; } ret = flash_program(file_addr, flash_addr, program_size); if(ret != 0){ hprintf("\nprogram error\n"); return ret; } programed_len += program_size; flash_addr += program_size; file_addr += program_size; sector++; } hprintf("\n\n"); return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int download_use_tftp(app_opt_info *info){ int ret; unsigned long filebuf; unsigned long flash_addr; int sector; int retry; unsigned int bootloader_filesize; unsigned int kernel_filesize; unsigned int userland_filesize; //download section if(info->bootloader_file != 0){ for(retry = 3;; retry--){ filebuf = 0xc5000000; ret = tftp_get(info->server_ipaddr, info->bootloader_file, &bootloader_filesize, (void *)filebuf, FLASH_BOOTLOADER_SIZE); switch(ret){ case -1://Common Error if(retry > 0){ hprintf("retry: \n"); continue; } hprintf("error..\n"); return -1; case -2://TFTP Error return -1; default: break; } break; } if(bootloader_filesize > FLASH_BOOTLOADER_SIZE){ hprintf("too large filesize\n"); return -1; } } if(info->kernel_file != 0){ for(retry = 3;; retry--){ filebuf = 0xc5000000 + FLASH_BOOTLOADER_SIZE; ret = tftp_get(info->server_ipaddr, info->kernel_file, &kernel_filesize, (void *)filebuf, FLASH_KERNEL_SIZE); switch(ret){ case -1://Common Error if(retry > 0){ hprintf("retry: \n"); continue; } hprintf("error..\n"); return -1; case -2://TFTP Error return -1; default: break; } break; } if(kernel_filesize > FLASH_KERNEL_SIZE){ hprintf("too large filesize\n"); return -1; } } if(info->userland_file != 0){ for(retry = 3;; retry--){ filebuf = 0xc5000000 + FLASH_BOOTLOADER_SIZE + FLASH_KERNEL_SIZE; ret = tftp_get(info->server_ipaddr, info->userland_file, &userland_filesize, (void *)filebuf, FLASH_USERLAND_SIZE); switch(ret){ case -1://Common Error if(retry > 0){ hprintf("retry: \n"); continue; } hprintf("error..\n"); return -1; case -2://TFTP Error return -1; default: break; } break; } if(userland_filesize > FLASH_USERLAND_SIZE){ hprintf("too large filesize\n"); return -1; } } if(info->fake == 0){ //program section if(info->bootloader_file != 0){ flash_addr = FLASH_START; filebuf = 0xc5000000; sector = SECTOR_IDX_BOOTLOADER; hprintf("programing: bootloader\n"); ret = program_file(flash_addr, sector, filebuf, bootloader_filesize); if(ret != 0){ return ret; } } if(info->kernel_file != 0){ flash_addr = FLASH_START + FLASH_BOOTLOADER_SIZE; filebuf = 0xc5000000 + FLASH_BOOTLOADER_SIZE; sector = SECTOR_IDX_KERNEL; hprintf("programing: kernel\n"); ret = program_file(flash_addr, sector, filebuf, kernel_filesize); if(ret != 0){ return ret; } } if(info->userland_file != 0){ flash_addr = FLASH_START + FLASH_BOOTLOADER_SIZE + FLASH_KERNEL_SIZE; filebuf = 0xc5000000 + FLASH_BOOTLOADER_SIZE + FLASH_KERNEL_SIZE; sector = SECTOR_IDX_USERLAND; hprintf("programing: userland\n"); ret = program_file(flash_addr, sector, filebuf, userland_filesize); if(ret != 0){ return ret; } } } hprintf("completed!!\n\n"); return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int parse_ipaddr(const char *str, unsigned char *ipaddr){ unsigned int num; int i,j; int ptr; for(i=0, ptr=0; i<4; i++){ for(j=0, num=0; j<4; j++, ptr++){ if(str[ptr] == 0){ if(i < 3) return -1; break; } switch(str[ptr]){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(j > 2) return -1; num = (num * 10) + (str[ptr] - '0'); break; case '.': j = 4; break; default: return -1; } } if(num >= 255) return -1; ipaddr[i] = (unsigned char)num; } if(str[ptr] != 0) return -1; return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int option_detect(int argc, char *argv[], app_opt_info *info){ int i; int ret; for(i=1;i<argc;i++){ if(safe_strncmp("--help", argv[i], 6+1) == 0){ return -1; } } if(argc < 3) return -1; ret = parse_ipaddr(argv[1], info->client_ipaddr); if(ret == -1){ hprintf("unknown ipaddr: %s\n", argv[1]); return -1; } ret = parse_ipaddr(argv[2], info->server_ipaddr); if(ret == -1){ hprintf("unknown ipaddr: %s\n", argv[2]); return -1; } for(i=3; i<argc; i++){ if(safe_strncmp("--bootloader=", argv[i], 13) == 0){ info->bootloader_file = &argv[i][13]; }else if(safe_strncmp("--kernel=", argv[i], 9) == 0){ info->kernel_file = &argv[i][9]; }else if(safe_strncmp("--userland=", argv[i], 11) == 0){ info->userland_file = &argv[i][11]; }else if(safe_strncmp("--fake", argv[i], 6+1) == 0){ info->fake = 1; }else{ hprintf("unknown option: %s\n", argv[i]); return -1; } } return 0;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static void tftpdl_usage(void){ hprintf("Usage: tftpdl [Client-IPaddr] [Server-IPaddr] [option]\n"); hprintf("\n"); hprintf(" to download from server using TFTP, " "and to program on flash-memory.\n"); hprintf("\n"); hprintf("option:\n"); hprintf(" --bootloader=[file] :\n"); hprintf(" --kernel=[file] :\n"); hprintf(" --userland=[file] :\n"); hprintf(" --fake : only download from server\n"); hprintf(" --help : display this message\n"); hprintf("\n");}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++static int tftpdl_cmdfunc(int argc, char *argv[]){ app_opt_info info; int ret; LED_RED_ON(); safe_memset(&info, 0, sizeof(app_opt_info)); ret = option_detect(argc, argv, &info); if(ret == -1){ tftpdl_usage(); return 0; } hprintf("\n"); hprintf("Client IPaddr : "); print_ip(info.client_ipaddr); hprintf("Server IPaddr : "); print_ip(info.server_ipaddr); if(info.bootloader_file != 0) hprintf("Bootloader file : %s\n", info.bootloader_file); if(info.kernel_file != 0) hprintf("Kernel file : %s\n", info.kernel_file); if(info.userland_file != 0) hprintf("Userland file : %s\n", info.userland_file); if(info.fake) hprintf("Fake Mode : %s\n", "Enable"); hprintf("\n"); hprintf("initializing net-device..."); ret = ep93xx_eth_init(info.client_ipaddr); if(ret == -1){ hprintf("NG\n"); LED_RED_OFF(); return -H_EIO; } hprintf("OK\n"); boost_on(BOOST_ETH_MODE); ret = download_use_tftp(&info); boost_off(); return ret;}//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++const command_t tftpdl_command = { "tftpdl", "--help", "flash programer using tftp", &tftpdl_cmdfunc };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -