Linux Gadget的一点研究之例程分析

学习Gadget比较有效的办法是掌握基本架构后,认真研读例程。其实不单Gadget如此,其他Linux驱动或子系统都是如此。另外Linux下的外设驱动通常有分层的概念,有带有面向对象的思想,因此研读代码是比较有效的领悟办法。

一般一个Linux的USB设备驱动,包括两大部分,一是CPU USB控制器部分的驱动,驱动文件名往往是xxx_udc.c,此部分驱动很多是与硬件CPU相关,包含寄存器设置、DMA设置,同时此部分也柔和了USB Gadget架构的东西,通常此部分代码是比较枯燥且难于理解的,每个CPU平台,此部分代码差异很大,但幸好此部分代码一般厂商会提供。二是gadget功能驱动,如果说USB控制器驱动是肉体,则此部分是灵魂,USB要在通信中是属于什么类型设备(HID?键盘?U盘?),怎样传输等等都是在此部分驱动中实现的。

Linux内核源码driver/usb/gadget/zero.c是一个很好的gadget功能驱动框架,本来内核开发者是想通过这个驱动框架来来方便第三方USB控制器驱动开发者测试UDC驱动的。

先上一个例程,这个例程是华清远见刘洪涛老师在阐述USB驱动部分写的一个例程,尽管例程尚有很多可优化、冗余的东西,尽管例程中描述注册字符设备驱动的方式是陈旧的方式,但是这个例程还是精彩阐述的如何开发一个gadget功能驱动。

在放这个例程前,为方便阅读,我更改部分代码格式。

/* 
 * zero.c -- Gadget Zero, for simple USB development
 * All rights reserved.
 */
 
/* #define VERBOSE_DEBUG */

#include <linux/kernel.h>
#include <linux/utsname.h>
#include <linux/device.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include "gadget_chips.h"
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/types.h> /* size_t */
#include <linux/errno.h> /* error codes */
#include <asm/system.h>
#include <asm/io.h>
#include <linux/sched.h>

/*-------------------------------------------------------------------------*/
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,
	.bNum
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值