zoukankan      html  css  js  c++  java
  • Linux系统中用DNW向ARM开发板下载程序

    在Linux下通过dnw来给开发板发送程序。包括驱动程序代码:secbulk.c,应用程序代码:dnw.c。只能运行在32位系统上,在64位系统上提示错误:DNW download Data size is too big。

    dnw源代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <string.h>
    
    const char* dev = "/dev/secbulk0";
    
    int main(int argc, char* argv[])
    {
        unsigned char* file_buffer = NULL;
        
        long int addr  =  0;
        
        if( 3 != argc )    {
            printf("Usage: dwn <filename> address
    ");
            return 1;
        }
        
    
        int fd = open(argv[1], O_RDONLY);
        if(-1 == fd) {
            printf("Can not open file - %s
    ", argv[1]);
            return 1;
        }
        addr = strtol((char *) argv[2] ,NULL, 16);
        
        printf("addr = %lx 
    ", addr);
        
    
        // get file size 
        struct stat file_stat;
        if( -1 == fstat(fd, &file_stat) ) {
            printf("Get file size filed!
    ");
            return 1;
        }    
    
        file_buffer = (unsigned char*)malloc(file_stat.st_size+10);
        if(NULL == file_buffer) {
            printf("malloc failed!
    ");
            goto error;
        }
        //memset(file_buffer, '', sizeof(file_buffer)); // bad code ! corrected by Qulory
        memset(file_buffer, '', sizeof(char)*(file_stat.st_size+10));
    
        // the first 8 bytes in the file_buffer is reserved, the last 2 bytes also;
        if( file_stat.st_size !=  read(fd, file_buffer+8, file_stat.st_size))    {
            printf("Read file failed!
    ");
            goto error;
        }
    
        printf("File name : %s
    ", argv[1]);
        printf("File size : %ld bytes
    ", file_stat.st_size);// off_t is long int 
    
        int fd_dev = open(dev, O_WRONLY);
        if( -1 == fd_dev)    {
            printf("Can not open %s
    ", dev);
            goto error;
        }
    
        /*
         * Note: the first 4 bytes store the dest addr ;
         * the following 4 bytes store the file size ;
         * and the last 2 bytes store the sum of each bytes of the file ;
         */
        *((unsigned long*)file_buffer) = addr;     //load address
        *((unsigned long*)file_buffer+1) = file_stat.st_size+10;    //file size
        unsigned short sum = 0;
        int i;
        for(i=8; i<file_stat.st_size+8; i++)    {
            sum += file_buffer[i];
        }
    
        *((unsigned short*)(file_buffer+8+file_stat.st_size)) = sum;
    
        printf("Start Sending data...
    ");
        size_t remain_size = file_stat.st_size+10;
        size_t block_size = 512;
        size_t written = 0;
        while(remain_size > 0)    {
            size_t to_write = remain_size > block_size ? block_size:remain_size;
            size_t real_write = write(fd_dev, file_buffer+written, to_write);
            if( to_write != real_write)    {
                printf(" write  /dev/secbulk0 failed!");
                return 1;
            }
            remain_size -= to_write;
            written += to_write;
            printf("
    Sent %lu%% 	 %lu bytes !", written*100/(file_stat.st_size+10),  written);
            fflush(stdout);
    
        }    
    
        printf("OK
    ");
        return 0;
    
    error:
        if(-1 != fd_dev) {
            close(fd_dev);
        }
        if(fd != -1)  {
            close(fd);
        }
        if( NULL != file_buffer ) {
            free(file_buffer);
        }
        return -1;
    }

    secbulk.c源代码:

    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/usb.h>
    #include <linux/fs.h>
    #include <linux/uaccess.h>
    #include <linux/slab.h>
    
    #define BULKOUT_BUFFER_SIZE 512
    char *bulkout_buffer;
    struct usb_device *udev;
    __u8 bulk_out_endaddr;
    
    static struct usb_device_id dnw_id_table [] = {
        { USB_DEVICE(0x5345, 0x1234) },
        { }        
    };
    
    static int dnw_open(struct inode* inode, struct file *file)
    {
         bulkout_buffer = kmalloc(BULKOUT_BUFFER_SIZE,GFP_KERNEL);
         return 0;
    }
    
    static int dnw_release (struct inode* inode, struct file *file)
    {
        kfree(bulkout_buffer);
        return 0;    
    }
    
    static ssize_t dnw_write(struct file *file, const char __user *buf, size_t len, loff_t *pos)
    {
        size_t to_write;
        size_t total_write = 0;
        size_t act_len;
        
        while(len>0)    
        {
            to_write = min(len,(size_t)BULKOUT_BUFFER_SIZE);
                
        copy_from_user(bulkout_buffer,buf+total_write,to_write);
        
        usb_bulk_msg(udev,usb_sndbulkpipe(udev,bulk_out_endaddr),bulkout_buffer,to_write,&act_len,3*HZ);
        
        len -= to_write;
        total_write += to_write;
        }
        
        return total_write;
    }
    
    static struct file_operations dnw_ops =
    {
        .owner =    THIS_MODULE,
        .write =    dnw_write,
        .open =        dnw_open,
        .release =    dnw_release,
    };
    
    static struct usb_class_driver dnw_class = {
        .name =        "secbulk%d",
        .fops =        &dnw_ops,
        .minor_base =    100,
    };
    
    
    static int dnw_probe(struct usb_interface *intf, const struct usb_device_id *id)
    {
        /* œÓ¿ÚÉèÖÃÃèÊö */
        struct usb_host_interface *interface;
        struct usb_endpoint_descriptor *endpoint;    
        int i;
        
        interface = intf->cur_altsetting;
        
        
        
        for(i=0;i<interface->desc.bNumEndpoints;i++)
        {
            endpoint = &interface->endpoint[i].desc;
            if(usb_endpoint_is_bulk_out(endpoint))
            {
                bulk_out_endaddr =     endpoint->bEndpointAddress;
                break;
            }
            
        }
        
        usb_register_dev(intf,&dnw_class);
        
        udev = usb_get_dev(interface_to_usbdev(intf));
        
    }
    
    static void dnw_disconnect(struct usb_interface *intf)
    {
        usb_deregister_dev(intf,&dnw_class);
    }
    
    struct usb_driver dnw_driver = {
        .name        = "dnw",   /* Çý¶¯Ãû */
        .probe        = dnw_probe, /* ²¶»ñº¯Êý */
        .disconnect    = dnw_disconnect, /* жÔغ¯Êý */
        .id_table    = dnw_id_table, /* É豞Áбí */
    };
    
    
    
    int dnw_init( void )
    {
        usb_register( &dnw_driver );
        return 0;    
    }
    
    void dnw_exit( void )
    {
        usb_deregister(&dnw_driver);    
    }
    
    
    module_init(dnw_init);
    module_exit(dnw_exit);
    MODULE_LICENSE("GPL");

    Makefile代码:

    obj-m := secbulk.o
    
    KDIR := /lib/modules/`uname -r`/build
    PWD := $(shell pwd)
    
    all:
        make -C $(KDIR) M=$(PWD) modules
    
    clean:
        rm *.o* *.s* *.ko* *.mod.* *.k*
  • 相关阅读:
    git
    搁置:vue-element-admin
    JS
    开发心得
    CSS
    VSCode(主进程)
    Vue
    axios
    滚动条出现的原理
    element-ui 1.4.13
  • 原文地址:https://www.cnblogs.com/ynxf/p/6260104.html
Copyright © 2011-2022 走看看