查看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 -;
}

[国嵌攻略][165][usb下载线驱动设计]的更多相关文章

  1. [国嵌攻略][155][I2C用户态驱动设计]

    用户态驱动模型 用户态驱动模型首先是一个应用程序,其次是在这个用户程序中通过内核调用来驱动设备. IIC通用驱动代码 IIC通用驱动程序的代码在/drivers/i2c/i2c-dev.c中.一次读操 ...

  2. [国嵌攻略][164][USB驱动程序设计]

    USB驱动模型 1.USB host controller driver(主控器驱动):为USB主控制器提供驱动程序 2.USB core(USB核心):连接USB主控制器驱动和USB设备驱动 3.U ...

  3. [国嵌攻略][161][USB总线介绍]

    USB发展史 USB(universal serial bus),通用串行总线,是一种外部总线标准.用于规范电脑与外部设备的连接和通讯.USB是在1994年底由英特尔.康柏.IBM.Microsoft ...

  4. [国嵌攻略][162][USB协议分析]

    USB设备逻辑结构 在USB设备的逻辑组织中,包含设备.配置.接口和端点4个层次.设备通常有一个或多个配置,配置通常有一个或多个接口,接口通常有零个或多个端点. USB设备描述符 当我们把USB设备( ...

  5. [国嵌攻略][149][Yaffs2文件系统应用]

    嵌入式系统自启动 MTD技术通过把Nand FLash划分成bootloader分区,Linux kernel分区和file system分区来达到自启动的效果. 配置和编译内核 1.配置Linux内 ...

  6. [国嵌攻略][163][linux-usb软件系统架构]

    软件系统架构 1.主机端软件架构 USB设备驱动->USB核心->USB主控制器驱动->USB主控制器 2.设备端软件架构 Gadget驱动->Gadget API->U ...

  7. [国嵌攻略][171][V4L2图像编程接口深度学习]

    V4L2摄像编程模型 1.打开摄像头设备文件 2.获取驱动信息-VIDIOC_QUERYCAP 3.设置图像格式-VIDIOC_S_FMT 4.申请帧缓冲-VIDIOC_REQBUFS 5.获取帧缓冲 ...

  8. [国嵌攻略][157][SPI总线介绍]

    SPI总线架构 SPI(serial peripheral interface)串行外设接口,是一种高速,全双工,同步的通信总线.采用主从模式(master slave)架构,支持多个slave,一般 ...

  9. [国嵌攻略][156][I2C自编设备驱动设计]

    AT24C08的驱动在Linux内核中已经提供,在/drivers/misc/eeprom/at24.c文件中.在对应的probe函数中有一个创建/sys/.../eeprom文件的函数,应用程序通过 ...

随机推荐

  1. Prism for WPF再探(基于Prism事件的模块间通信)

    上篇博文链接 Prism for WPF初探(构建简单的模块化开发框架) 一.简单介绍: 在上一篇博文中初步搭建了Prism框架的各个模块,但那只是搭建了一个空壳,里面的内容基本是空的,在这一篇我将实 ...

  2. Spark源码剖析(七):Job触发流程原理与源码剖析

    引言 我们知道在application中每存在一个action操作就会触发一个job,那么spark底层是怎样触发job的呢?接下来我们用一个wordcount程序来剖析一下job的触发机制. 解析w ...

  3. animate.css – 齐全的CSS3动画库

    animate.css – 齐全的CSS3动画库 演 示 下 载   简介 animate.css 是一个来自国外的 CSS3 动画库,它预设了抖动(shake).闪烁(flash).弹跳(bounc ...

  4. Linux入门篇(一)——文件

    这一系列的Linux入门都是本人在<鸟哥的Linux私房菜>的基础上总结的基本内容,主要是记录下自己的学习过程,也方便大家简要的了解 Linux Distribution是Ubuntu而不 ...

  5. js小知识-replace的回调函数

    replace() 方法返回一个由替换值替换一些或所有匹配的模式后的新字符串.模式可以是一个字符串或者一个正则表达式, 替换值可以是一个字符串或者一个每次匹配都要调用的函数. 注意:原字符串不会改变. ...

  6. postfix : 452 4.3.1 Insufficient system storage

    postfix Error Message: 452 4.3.1 Insufficient system storage --> 空间不足. 但是实际情况是我的各个分区都没有满,只是我的20G ...

  7. dubbo filter链构建过程

    public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { if (Consta ...

  8. 用AndroidStudio发布Libs到Bintray jCenter

    1 RootProject[根目录]build.gradle中添加如下插件引用 dependencies { ....... classpath 'com.jfrog.bintray.gradle:g ...

  9. VBox 一款基于vue开发的音乐盒 序章

    己基于vue写了一个 Mplayer, github地址:https://github.com/xiangwenhu/MPlaer, 演示地址:http://babydairy2017.cloudap ...

  10. Pandas库的使用--Series

    一.概念 Series相当于一维数组. 1.调用Series的原生方法创建 import pandas as pd s1 = pd.Series(data=[1,2,4,6,7],index=['a' ...