[国嵌攻略][165][usb下载线驱动设计]

查看USB设备的生产商ID和设备ID

示例:

lsusb

Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

生产商ID是1d6b,设备ID是0002

创建USB总线型字符设备

usb_register_dev   //效果同cdev创建字符设备效果相同

创建的主设备号都是180,次设备号可以设置为100

头文件

<linux/usb.h>

usb.c

/********************************************************************
*头文件
*********************************************************************/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/uaccess.h> /********************************************************************
*宏定义
*********************************************************************/
#define BUFSIZE 512 /********************************************************************
*全局变量
*********************************************************************/
struct usb_device *dnwdev; //设备结构
unsigned char bulkEndAddr; //端点地址
char *bulkBuffer; //批量缓存 /********************************************************************
*设备方法
*********************************************************************/
//写入设备
ssize_t dnw_write(struct file *filp, const char __user *buf, size_t lenght, loff_t *ppos){
int sumLen; //数据总长
int tmpLen; //临时长度
int retLen; //返回长度 //发送数据内容
sumLen = ; while(lenght > ){
//设置发送长度
tmpLen = (lenght > BUFSIZE) ? BUFSIZE : lenght; //写入数据内容
retLen = copy_from_user(bulkBuffer, buf + sumLen, tmpLen); //提交数据内容
usb_bulk_msg(
dnwdev,
usb_sndbulkpipe(dnwdev, bulkEndAddr),
bulkBuffer,
tmpLen,
&retLen,
* HZ
); //设置数据长度
lenght -= tmpLen;
sumLen += tmpLen;
} return sumLen;
} //打开设备
int dnw_open(struct inode *node, struct file *filp){
//分配批量缓存
bulkBuffer = kmalloc(BUFSIZE * sizeof(char), GFP_KERNEL); return ;
} //关闭设备
int dnw_close(struct inode *node, struct file *filp){
//释放批量缓存
kfree(bulkBuffer); return ;
} //设备方法
struct file_operations dnwfops = {
.owner = THIS_MODULE,
.write = dnw_write,
.open = dnw_open,
.release = dnw_close
}; /********************************************************************
*驱动方法
*********************************************************************/
//设备信息
struct usb_class_driver dnwClass = {
.name = "dnw%d", //设备名称
.fops = &dnwfops, //设备方法
.minor_base = //起始次设备号,主设备号为180
}; //捕获设备
int dnw_probe(struct usb_interface *intf, const struct usb_device_id *id){
struct usb_host_interface *interface;
int i;
struct usb_endpoint_descriptor *endpoint;
int isBulk; //获取设备
dnwdev = usb_get_dev(interface_to_usbdev(intf)); //获取接口
interface = intf->cur_altsetting; //获取端点
for(i = ; i < interface->desc.bNumEndpoints; i++){
//获取端点结构
endpoint = &interface->endpoint[i].desc; //判断批量端点
isBulk = usb_endpoint_is_bulk_out(endpoint);
if(isBulk){
bulkEndAddr = endpoint->bEndpointAddress;
break;
}
} //注册设备
usb_register_dev(intf, &dnwClass); return ;
} //移除设备
void dnw_disconnect(struct usb_interface *intf){
//注销设备
usb_deregister_dev(intf, &dnwClass);
} /********************************************************************
*驱动安装
*********************************************************************/
//设备列表
struct usb_device_id dnw_id_table[] = {
{ USB_DEVICE(0x5345, 0x1234) }, //Vender ID,Device ID
{ }
}; //驱动结构
struct usb_driver dnwdrv = {
.name = "idnw", //驱动名称
.probe = dnw_probe, //捕获设备
.disconnect = dnw_disconnect, //移除设备
.id_table = dnw_id_table //设备列表
}; //安装驱动
static int idnw_init(void){
//注册驱动
usb_register(&dnwdrv); return ;
} //卸载驱动
static void idnw_exit(void){
//注销驱动
usb_deregister(&dnwdrv);
} /********************************************************************
*驱动声明
*********************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("D");
MODULE_DESCRIPTION("");
MODULE_VERSION("v1.0"); module_init(idnw_init);
module_exit(idnw_exit);

Makefile

obj-m := usb.o
KDIR := /lib/modules/2.6.-.el6.i686/build/ all:
make -C $(KDIR) M=$(PWD) modules clean:
@rm -f *.ko *.ko.unsigned *.mod.c *.mod.o *.o *.order *.symvers

dnw.c

#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 = ; if( != argc ) {
printf("Usage: dwn <filename> address\n");
return ;
} int fd = open(argv[], O_RDONLY);
if(- == fd) {
printf("Can not open file - %s\n", argv[]);
return ;
}
addr = strtol((char *) argv[] ,NULL, ); printf("addr = %x \n", addr); // get file size
struct stat file_stat;
if( - == fstat(fd, &file_stat) ) {
printf("Get file size filed!\n");
return ;
} file_buffer = (unsigned char*)malloc(file_stat.st_size+);
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+)); // the first 8 bytes in the file_buffer is reserved, the last 2 bytes also;
if( file_stat.st_size != read(fd, file_buffer+, file_stat.st_size)) {
printf("Read file failed!\n");
goto error;
} printf("File name : %s\n", argv[]);
printf("File size : %ld bytes\n", file_stat.st_size);// off_t is long int int fd_dev = open(dev, O_WRONLY);
if( - == 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+) = file_stat.st_size+; //file size
unsigned short sum = ;
int i;
for(i=; i<file_stat.st_size+; i++) {
sum += file_buffer[i];
} *((unsigned short*)(file_buffer++file_stat.st_size)) = sum; printf("Start Sending data...\n");
size_t remain_size = file_stat.st_size+;
size_t block_size = ;
size_t written = ;
while(remain_size > ) {
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 ;
}
remain_size -= to_write;
written += to_write;
printf("\rSent %lu%% \t %u bytes !", written*/(file_stat.st_size+), written);
fflush(stdout); } printf("OK\n");
return ; error:
if(- != fd_dev) {
close(fd_dev);
}
if(fd != -) {
close(fd);
}
if( NULL != file_buffer ) {
free(file_buffer);
}
return -;
}
上一篇:Vue 获取登录用户名


下一篇:Django Aggregation聚合