赞
踩
1.模块代码的初始化函数和退出函数
- static struct usb_driver dnw_driver =
- {
- .name = "dnw", /* 驱动名 */
- .probe = dnw_probe, /* 捕获函数 */
- .disconnect = dnw_disconnect, /* 卸载函数 */
- .id_table = dnw_id_table, /* 设备列表 */
- };
-
- int dnw_init()
- {
- usb_register(&dnw_driver);
- return 0;
- }
-
- void dnw_exit()
- {
- usb_deregister(&dnw_driver);
- }
-
- module_init(dnw_init);
- module_exit(dnw_exit);
-
- MODULE_LICENSE("GPL");
2.实现id_table
- static struct usb_device_id dnw_id_table [] =
- {
- { USB_DEVICE(0x5345, 0x1234) },
- { }
- };
3.probe函数
- int usb_register_dev(struct usb_interface *intf,
- struct usb_class_driver *class_driver)
- static struct usb_class_driver dnw_class =
- {
- .name = "dnw%d", // 设备文件名字
- .fops = &dnw_ops, // 函数操作集
- .minor_base = 100, // 次设备号,字符设备的主设备号为固定的180
- };
- static const struct file_operations dnw_fops =
- {
- .owner = THIS_MODULE,
- .write = dnw_write,
- .open = dnw_open,
- .release = dnw_release,
- };
- #define BULKOUT_BUFFER_SIZE 512
- char *bulkout_buffer;
-
- static int dnw_open(struct inode* inode, struct file *file)
- {
- // 为这个buffer分配空间,大小为512个字节
- bulkout_buffer = kmalloc(BULKOUT_BUFFER_SIZE,GFP_KERNEL);
- return 0;
- }
-
- static int dnw_release (struct inode* inode, struct file *file)
- {
- // 这里面释放buffer的空间
- 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);
-
- /* 把用户空间的数据分批拷贝到内核中
- * buffer的内存分配可以在open函数中完成
- * buffer的释放在release中完成
- */
- copy_from_user(bulkout_buffer,buf+total_write,to_write);
-
- // 提交URB
- 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;
- }
4.源代码
- #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)
- {
- // 为这个buffer分配空间,大小为512个字节
- bulkout_buffer = kmalloc(BULKOUT_BUFFER_SIZE, GFP_KERNEL);
- return 0;
- }
-
- static int dnw_release(struct inode* inode, struct file *file)
- {
- // 这里面释放buffer的空间
- 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);
-
- /* 把用户空间的数据分批拷贝到内核中
- * buffer的内存分配可以在open函数中完成
- * buffer的释放在release中完成
- */
- copy_from_user(bulkout_buffer, buf + total_write, to_write);
-
- // 提交URB
- 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 const struct file_operations dnw_fops =
- {
- .owner = THIS_MODULE,
- .write = dnw_write,
- .open = dnw_open,
- .release = dnw_release,
- };
-
- static struct usb_class_driver dnw_class =
- {
- .name = "dnw%d", // 设备文件名字
- .fops = &dnw_ops, // 函数操作集
- .minor_base = 100, // 次设备号,字符设备的主设备号为固定的180
- };
-
- 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));
-
- return 0;
- }
-
- static void dnw_disconnect(struct usb_interface *intf)
- {
- usb_deregister_dev(intf,&dnw_class);
- }
-
- static struct usb_driver dnw_driver =
- {
- .name = "dnw", /* 驱动名 */
- .probe = dnw_probe, /* 捕获函数 */
- .disconnect = dnw_disconnect, /* 卸载函数 */
- .id_table = dnw_id_table, /* 设备列表 */
- };
-
- int dnw_init()
- {
- usb_register(&dnw_driver);
- return 0;
- }
-
- void dnw_exit()
- {
- usb_deregister(&dnw_driver);
- }
-
- module_init(dnw_init);
- module_exit(dnw_exit);
-
- MODULE_LICENSE("GPL");
- #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/dnw0";
-
- 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 = %x \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! to_write = %u real_write = %u \n" , to_write ,real_write );
- return 1;
- }
- remain_size -= to_write;
- written += to_write;
- printf("\rSent %lu%% \t %u 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;
- }
- KDIR = /lib/modules/`uname -r`/build
- PWD := $(shell pwd)
- obj-m := dnw_usb.o
-
- all:
- make -C $(KDIR) M=$(PWD) modules
-
- clean:
- rm -rf *.o *.ko *.ko.unsigned *.mod.c *.order *.symvers
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。