Linux系统中用DNW向ARM开发板下载程序
Posted 叶念西风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n"); return 1; } int fd = open(argv[1], O_RDONLY); if(-1 == fd) { printf("Can not open file - %s\n", argv[1]); return 1; } addr = strtol((char *) argv[2] ,NULL, 16); printf("addr = %lx \n", addr); // get file size struct stat file_stat; if( -1 == fstat(fd, &file_stat) ) { printf("Get file size filed!\n"); return 1; } file_buffer = (unsigned char*)malloc(file_stat.st_size+10); if(NULL == file_buffer) { printf("malloc failed!\n"); goto error; } //memset(file_buffer, ‘\0‘, sizeof(file_buffer)); // bad code ! corrected by Qulory memset(file_buffer, ‘\0‘, 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!\n"); goto error; } printf("File name : %s\n", argv[1]); printf("File size : %ld bytes\n", 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\n", 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...\n"); 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("\rSent %lu%% \t %lu bytes !", written*100/(file_stat.st_size+10), written); fflush(stdout); } printf("OK\n"); 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", /* ?y?ˉ?? */ .probe = dnw_probe, /* 2???oˉêy */ .disconnect = dnw_disconnect, /* D???oˉêy */ .id_table = dnw_id_table, /* éè±?áD±í */ }; 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*
以上是关于Linux系统中用DNW向ARM开发板下载程序的主要内容,如果未能解决你的问题,请参考以下文章