查看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. vbs的一些入门基础。。。

    VBS(VBScript的进一步简写)是基于Visual Basic的脚本语言. Microsoft Visual Basic是微软公司出品的一套可视化编程工具, 语法基于Basic. 脚本语言, 就 ...

  2. 解决NTPD漏洞,升级Ntpd版本

    关于解决漏洞的问题我就不详说了,主要就是升级版本.这里我们就直接简单记录下步骤: 1.升级 使用root用户登录系统进入到/home/guankong ,上传ntp-4.2.8p9-1.el6.x86 ...

  3. 小白的Python之路 day4 json and pickle数据标准序列化

    一.简述 我们在写入文件中的数据,只能是字符串或者二进制,但是要传入文件的数据不一定全是字符串或者二进制,那还要进行繁琐的转换,然后再读取的时候,还要再转回去,显得很麻烦,今天就来学习标准的序列化:j ...

  4. Android模拟器

    一.Genymotion 1.下载安装:https://www.genymotion.com/download/  (注:安装前需要先注册) 因为Genymotion运行需要VirtualBox,如果 ...

  5. 微信小程序+“芝麻小客服”可设自动关注公众号,助力运营闭环

    微信小程序全面上线已经接近1年的时间,从最初的"用完即走"理念到2017年总计更新开放60余次的功能创新,微信小程序不一定会爆发下一次的红利,但绝对是微信生态中重要的一环. 芝麻小 ...

  6. Tomcat 到底依赖JRE还是JDK

    Tomcat 6.0 以上可以不再依赖JDK运行,直接使用JRE即可,但Tomcat 5.5以下,是必须安装JDK的. 这主要是由于,Tomcat 5.5及以下版本主要是依赖JDK去编译JSP文件生成 ...

  7. NPOI 1.2 教程

    NPOI 1.2 教程官方地址 很多人可能对NPOI还很陌生,别担心,通过本教程你将对NPOI有进一步的认识和理解. 目录 1. 认识NPOI 2. 使用NPOI生成xls文件 2.1 创建基本内容 ...

  8. 部署Tomcat服务时,解决Cannot invoke Tomcat Manager 异常

    最近,在使用Jenkins对工程一键部署的时候,出现调用Tomcat Manager 异常,对其解决方案特记于次. 异常信息 可能存在的异常:(1)Cannot invoke Tomcat manag ...

  9. vue2.0 样式表引入的方法 css sass less

    在引入样式之前,首先要了解static.assets两个文件夹的区别. 从字面上可以看出,static用来存放静态文件,assets用来存放资源文件: static存放的文件不会被编译,打包后直接赋值 ...

  10. 自学Aruba1.1-Aruba体系结构-产品线

    点击返回:自学Aruba之路Aruba产品线 IP switches: 1500.2500.3500 Controllers:7200 .70x0 Series.7005 Meridian:基于ACE ...