查看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下载线驱动设计]的更多相关文章
-
[国嵌攻略][155][I2C用户态驱动设计]
用户态驱动模型 用户态驱动模型首先是一个应用程序,其次是在这个用户程序中通过内核调用来驱动设备. IIC通用驱动代码 IIC通用驱动程序的代码在/drivers/i2c/i2c-dev.c中.一次读操 ...
-
[国嵌攻略][164][USB驱动程序设计]
USB驱动模型 1.USB host controller driver(主控器驱动):为USB主控制器提供驱动程序 2.USB core(USB核心):连接USB主控制器驱动和USB设备驱动 3.U ...
-
[国嵌攻略][161][USB总线介绍]
USB发展史 USB(universal serial bus),通用串行总线,是一种外部总线标准.用于规范电脑与外部设备的连接和通讯.USB是在1994年底由英特尔.康柏.IBM.Microsoft ...
-
[国嵌攻略][162][USB协议分析]
USB设备逻辑结构 在USB设备的逻辑组织中,包含设备.配置.接口和端点4个层次.设备通常有一个或多个配置,配置通常有一个或多个接口,接口通常有零个或多个端点. USB设备描述符 当我们把USB设备( ...
-
[国嵌攻略][149][Yaffs2文件系统应用]
嵌入式系统自启动 MTD技术通过把Nand FLash划分成bootloader分区,Linux kernel分区和file system分区来达到自启动的效果. 配置和编译内核 1.配置Linux内 ...
-
[国嵌攻略][163][linux-usb软件系统架构]
软件系统架构 1.主机端软件架构 USB设备驱动->USB核心->USB主控制器驱动->USB主控制器 2.设备端软件架构 Gadget驱动->Gadget API->U ...
-
[国嵌攻略][171][V4L2图像编程接口深度学习]
V4L2摄像编程模型 1.打开摄像头设备文件 2.获取驱动信息-VIDIOC_QUERYCAP 3.设置图像格式-VIDIOC_S_FMT 4.申请帧缓冲-VIDIOC_REQBUFS 5.获取帧缓冲 ...
-
[国嵌攻略][157][SPI总线介绍]
SPI总线架构 SPI(serial peripheral interface)串行外设接口,是一种高速,全双工,同步的通信总线.采用主从模式(master slave)架构,支持多个slave,一般 ...
-
[国嵌攻略][156][I2C自编设备驱动设计]
AT24C08的驱动在Linux内核中已经提供,在/drivers/misc/eeprom/at24.c文件中.在对应的probe函数中有一个创建/sys/.../eeprom文件的函数,应用程序通过 ...
随机推荐
-
c#编程基础之字符串函数
c#常用的字符串函数 例一: 获取字符串的大小写函数 ToLower():得到字符串的小写形式 ToUpper():得到字符串的大写形式 注意: 字符串时不可变的,所以这些函数都不会直接改变字符串的内 ...
-
ExtJS笔记 Ext.data.Model
A Model represents some object that your application manages. For example, one might define a Model ...
-
ODBC连接问题
http://zhidao.baidu.com/link?url=EPEMTuGC1q5wWavZigWseoHOwRLvpHyAVsdIgMLspErJOUZMEepIICUnT9IdkPQlYTm ...
-
oracle修改列的类型
alter table table_name modify column_name datatype;
-
【LeetCode】70 - Climbing Stairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...
-
原生app与web app的比较
http://www.2ee9.com/news/news_show_36_237.html http://zhidao.baidu.com/link?url=7lWq2tgqiMiDmsRd54hO ...
-
机器学习,安装python的支持包
windows10,64位: 以下命令行安装均在python目录下,对应的whl文件也被我拷贝到python目录下: http://www.lfd.uci.edu/~gohlke/pythonlibs ...
-
[SCOI2011]飞镖[数学模拟]
2335: [SCOI2011]飞镖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 482 Solved: 152[Submit][Status][ ...
-
linux虚拟机更改时区
第一种方法: cat /etc/sysconfig/clock ZONE="Asia/Shanghai" UTC=true ARC=false rm -f /etc/loca ...
-
Java_String_Arrays_Character_BigDecimal_Calendar_Math_System
1.String package cn.itcast_01; /* * Scanner:用于接收键盘录入数据. * * 前面的时候: * A:导包 * B:创建对象 * C:调用方法 * * Sy ...