Chinaunix首页 | 论坛 | 博客
  • 博客访问: 397376
  • 博文数量: 81
  • 博客积分: 45
  • 博客等级: 民兵
  • 技术积分: 608
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-22 11:46
个人简介

一个愤青

文章分类

全部博文(81)

文章存档

2015年(40)

2014年(29)

2013年(11)

2012年(1)

我的朋友

分类: LINUX

2013-10-11 18:22:07


点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <malloc.h>
  5. #include <errno.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <sys/time.h>
  9. #include <unistd.h>
  10. #include <fcntl.h>
  11. #include <stdint.h>
  12.   
  13. const char* dev = "/dev/secbulk0"; //dnw所创建的设备文件,要对其写入
  14. #define BLOCK_SIZE (1*1024*1024) //设置的写入块大小1MB
  15.   
  16. struct download_buffer {
  17.     uint32_t load_addr; /* load address */
  18.     uint32_t size; /* data size *///size=地址(4位)+大小(4位)+数据+校验(2位)
  19.     uint8_t data[0];//0长度数组,指向数据
  20.     /* uint16_t checksum; */ //数组后紧接着的两位是校验位
  21. };
  22.   
  23. static int _download_buffer(struct download_buffer *buf)//从缓存写入到usb设备文件
  24. {
  25.     int fd_dev = open(dev, O_WRONLY);//打开设备
  26.     if( -1 == fd_dev) {
  27.         printf("Can not open %s: %s\n", dev, strerror(errno));
  28.         return -1;
  29.     }
  30.   
  31.     printf("Writing data...\n");
  32.     size_t remain_size = buf->size;//写入文件的剩余大小
  33.     size_t block_size = BLOCK_SIZE;//每次写入的大小
  34.     size_t writed = 0;//已经写入的文件大小
  35.     while(remain_size>0) {
  36.         size_t to_write = remain_size > block_size ? block_size : remain_size;//每次写入的实际大小
  37.         if( to_write != write(fd_dev, (unsigned char*)buf + writed, to_write)) {
  38.             perror("write failed");
  39.             close(fd_dev);
  40.             return -1;
  41.         }
  42.         remain_size -= to_write;
  43.         writed += to_write;
  44.         printf("\r%02zu%%\t0x%08zX bytes (%zu K)",
  45.              (size_t)((uint64_t)writed*100/(buf->size)),
  46.              writed,
  47.              writed/1024);//打印写入的百分比
  48.         fflush(stdout);//将缓存写入文件
  49.     }
  50.     printf("\n");
  51.     close(fd_dev);
  52.     return 0;
  53. }
  54.   
  55. static inline void cal_and_set_checksum(struct download_buffer *buf)
  56. {
  57.     uint16_t sum = 0;
  58.     int i;
  59.   
  60.     for(i = 0; i < buf->size; i++) {
  61.         sum += buf->data[i];
  62.     }
  63.     *((uint16_t*)(&((uint8_t*)buf)[buf->size - 2])) = sum;//校验码赋值给最后一个word
  64. }
  65.   
  66. static struct download_buffer* alloc_buffer(size_t data_size)//分配空间的函数
  67. {
  68.     struct download_buffer *buffer = NULL;
  69.     size_t total_size = data_size + sizeof(struct download_buffer) + 2; //buffer=文件大小+结构体前两项的大小+2位的校验位
  70.     buffer = (typeof(buffer))malloc(total_size);
  71.     if(NULL == buffer)
  72.         return NULL;
  73.     buffer->size = total_size;
  74.     return buffer;//返回指向结构体的指针
  75. }
  76.   
  77. static void free_buffer(struct download_buffer *buf)
  78. {
  79.     free(buf);
  80. }
  81.   
  82. static struct download_buffer *load_file(const char *path, unsigned long load_addr)//载入文件到缓存
  83. {
  84.     struct stat file_stat;
  85.     struct download_buffer *buffer = NULL;
  86.     int fd;
  87.   
  88.     fd = open(path, O_RDONLY);//通过路径打开文件,获得fd文件标识符
  89.     if(-1 == fd) {
  90.         printf("Can not open file %s: %s\n", path, strerror(errno));
  91.         return NULL;
  92.     }
  93.   
  94.     if( -1 == fstat(fd, &file_stat) ) {//获取文件的属性
  95.         perror("Get file size filed!\n");
  96.         goto error;
  97.     }
  98.   
  99.     buffer = alloc_buffer(file_stat.st_size);//给buffer分配空间(文件占用空间+结构体空间+2位校验)
  100.     if(NULL == buffer) {
  101.         perror("malloc failed!\n");
  102.         goto error;
  103.     }
  104.     if( file_stat.st_size != read(fd, buffer->data, file_stat.st_size)) {//将文件写入buffer-》data
  105.         perror("Read file failed!\n");
  106.         goto error;
  107.     }
  108.   
  109.     buffer->load_addr = load_addr;//填充结构体
  110.     cal_and_set_checksum(buffer);//校验数据
  111.   
  112.     return buffer;
  113.   
  114. error:
  115.     if(fd != -1)
  116.         close(fd);
  117.     if( NULL != buffer )
  118.         free(buffer);
  119.     return NULL;
  120. }
  121.   
  122. static int download_file(const char *path, unsigned long load_addr)
  123. {
  124.     struct download_buffer *buffer;
  125.     struct timeval __start, __end;
  126.     long __time_val = 0;
  127.     float speed = 0.0;
  128.   
  129.     buffer = load_file(path, load_addr);//将文件载入到buffer中
  130.     gettimeofday(&__start,NULL);
  131.     
  132.     if (buffer != NULL) {
  133.         if (_download_buffer(buffer) == 0) {//将缓存中的数据写入usb口
  134.             gettimeofday(&__end,NULL);
  135.             __time_val = (long) (__end.tv_usec - __start.tv_usec)/1000 + \
  136.                 (long)(__end.tv_sec - __start.tv_sec) * 1000;
  137.             speed = (float)buffer->size/__time_val/(1024*1024) * 1000;
  138.             printf("speed: %fM/S\n",speed);
  139.             free_buffer(buffer);
  140.             return 0;
  141.         } else {
  142.             free_buffer(buffer);
  143.             return -1;
  144.         }
  145.     }

  146.     return -1;
  147. }
  148.   
  149. int main(int argc, char* argv[])
  150. {
  151.     unsigned load_addr = 0x57e00000;
  152.     char* path = NULL;
  153.     int c;
  154.   
  155.     while ((c = getopt (argc, argv, "a:h")) != EOF)
  156.         switch (c) {
  157.         case 'a':
  158.             load_addr = strtol(optarg, NULL, 16);
  159.             continue;
  160.         case '?':
  161.         case 'h':
  162.         default:
  163.         usage:
  164.             printf("Usage: dwn [-a load_addr] \n");
  165.             printf("Default load address: 0x57e00000\n");
  166.             return 1;
  167.         }
  168.     if (optind < argc)
  169.         path = argv[optind];
  170.     else
  171.         goto usage;
  172.   
  173.     printf("load address: 0x%08X\n", load_addr);
  174.     if (download_file(path, load_addr) != 0) {
  175.         return -1;
  176.     }
  177.   
  178.     return 0;
  179. }

阅读(1041) | 评论(0) | 转发(0) |
0

上一篇:linux 开发相关

下一篇:男儿当自强

给主人留下些什么吧!~~