Linux USB gadget设备驱动解析(4)--编写一个gadget驱动
一、编写计划
通过前面几节的基础,本节计划编写一个简单的gadget驱动。重在让大家快速了解gadget驱动结构。
上节中简单介绍了zero.c程序。这个程序考虑到了多配置、高速传输、USB OTG等因素。应该说写的比较清楚,是我们了解gadget驱动架构的一个非常好的途径。但把这些东西都放在一起,对很多初学人员来说还是不能快速理解。那就再把它简化一些,针对S3C2410平台,只实现一个配置、一个接口、一个端点,不考虑高速及OTG的情况。只完成单向从hoST端接收数据的功能,但要把字符设备驱动结合在里面。这需要有一个host端的驱动,来完成向device端发送数据。关于在主机端编写一个简单的USB设备驱动程序,有很多的资料。相信大家很快就会完成的。
二、功能展示
1、PC端编写了一个us^raNSfer.ko,能够向device端发送数据
2、对目标平台编写一个gadget驱动,名称是g_zero.ko
3、测试步骤
在目标平台(基于S3C2410)上加载gadget驱动
# insmod g_zero.ko
name=ep1-bulk
smdk2410_udc: Pull-up enable
# mknod /dev/usb_rcv c 251 0
#
在PC主机上加载驱动us^ransfer.ko
#insmod us^ransfer.ko
#mknod /dev/us^ransfer c 266 0
连接设备,目标平台的终端显示:
cONnected
目标平台读取数据
# cat /dev/usb_rcv
PC端发送数据
#echo “12345” > /dev/us^ransfer
#echo “abcd” > /dev/us^ransfer
设备端会显示收到的数据
# cat /dev/usb_rcv
12345
abcd
三、代码分析
下面的代码是在原有的zero.c基础上做了精简、修改的。一些结构的名称还是保留以前的,但含义有所变化。如:loopback_config,不再表示loopback,而只是单向的接收数据。
/*
* zero.c -- Gadget Zero, for simple USB development
* lht@farsight.com.cn
* All rights reserved.*/
/* #define VERBOSE_DEBUG */
#include
#include
#include
#include
#include
#include gadget_chips.h
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*-------------------------------------------------------------------------*/
stATIc const char shortname[] = zero;
staTIc const char loopback[] = loop input to output;
static const char longname[] = Gadget Zero;
static const char source_sink[] = source and sink data;
#define STRING_MANUFACTURER 25
#define STRING_PRODUCT 42
#define STRING_SERIAL 101
#define STRING_SOURCE_SINK 250
#define STRING_LOOPBACK 251
//#define DRIVER_VENDOR_NUM 0x0525 /* NetChip */
//#define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB Gadget Zero */
#define DRIVER_VENDOR_NUM 0x5345 /* NetChip */
#define DRIVER_PRODUCT_NUM 0x1234 /* Linux-USB Gadget Zero */
static int usb_zero_major = 251;
/*-------------------------------------------------------------------------*/
static const char *EP_OUT_NAME; /* sink */
/*-------------------------------------------------------------------------*/
/* big enough to hold our biggest descriptor */
#define USB_BUFSIZ 256
struct zero_dev { //zero设备结构
spinlock_t lock;
struct usb_gadget *gadget;
struct usb_request *req; /* for control responses */
struct usb_ep *out_ep;
struct cdev cdev;
unsigned char data[128];
unsigned int data_size;
wait_queue_head_t bulkrq;
};
#define CONFIG_LOOPBACK 2
static struct usb_device_descriptor device_desc = { //设备描述符
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = __constant_cpu_to_le16(0x0110),
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
.idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM),
.idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialnumber = STRING_SERIAL,
.bNumConfigurations = 1,
};
static struct usb_endpoint_descriptor fs_sink_desc = { //端点描述符
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT, //对主机端来说,输出
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
static struct usb_config_descriptor loopback_config = { //配置描述符
.bLength = sizeof loopback_co
gadget 一个 驱动 编写 设备驱动 USB Linux 解析 相关文章:
- 关于spiflash存储器读写一个字节的问题方案(11-27)
- 第1节:单片机到底是学什么?我的两个比喻和一个规则(11-22)
- 汇编入门学习笔记 (三) —— 第一个程序(11-09)
- DIY一个MSP430F149最小系统的设计(07-22)
- 视频显示卡直接写屏的一个实例(09-14)
- 单片机c语言教程:建立你的第一个KeilC51项目(09-11)