新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > Linux USB gadget设备驱动解析(4)--编写一个gadget驱动

Linux USB gadget设备驱动解析(4)--编写一个gadget驱动

作者:时间:2012-08-06来源:网络收藏

一、计划

本文引用地址:http://www.eepw.com.cn/article/148655.htm

通过前面几节的基础,本节计划简单的。重在让大家快速了解结构。

上节中简单介绍了zero.c程序。这个程序考虑到了多配置、高速传输、 OTG等因素。应该说写的比较清楚,是我们了解架构的非常好的途径。但把这些东西都放在一起,对很多初学人员来说还是不能快速理解。那就再把它简化一些,针对S3C2410平台,只实现配置、一个接口、一个端点,不考虑高速及OTG的情况。只完成单向从hoST端接收数据的功能,但要把字符结合在里面。这需要有一个host端的驱动,来完成向device端发送数据。关于在主机端一个简单的程序,有很多的资料。相信大家很快就会完成的。

二、功能展示

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 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/* size_t */

#include/* error codes */

#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 /* -USB Gadget Zero */

#define DRIVER_VENDOR_NUM 0x5345 /* NetChip */

#define DRIVER_PRODUCT_NUM 0x1234 /* -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, //对主机端来说,输出

linux操作系统文章专题:linux操作系统详解(linux不再难懂)

linux相关文章:linux教程



上一页 1 2 3 4 5 下一页

评论


相关推荐

技术专区

关闭