Linux USB gadget設(shè)備驅(qū)動解析(4)--編寫一個gadget驅(qū)動
一、編寫計劃
本文引用地址:http://m.butianyuan.cn/article/148655.htm通過前面幾節(jié)的基礎(chǔ),本節(jié)計劃編寫一個簡單的gadget驅(qū)動。重在讓大家快速了解gadget驅(qū)動結(jié)構(gòu)。
上節(jié)中簡單介紹了zero.c程序。這個程序考慮到了多配置、高速傳輸、USB OTG等因素。應(yīng)該說寫的比較清楚,是我們了解gadget驅(qū)動架構(gòu)的一個非常好的途徑。但把這些東西都放在一起,對很多初學(xué)人員來說還是不能快速理解。那就再把它簡化一些,針對S3C2410平臺,只實現(xiàn)一個配置、一個接口、一個端點,不考慮高速及OTG的情況。只完成單向從hoST端接收數(shù)據(jù)的功能,但要把字符設(shè)備驅(qū)動結(jié)合在里面。這需要有一個host端的驅(qū)動,來完成向device端發(fā)送數(shù)據(jù)。關(guān)于在主機端編寫一個簡單的USB設(shè)備驅(qū)動程序,有很多的資料。相信大家很快就會完成的。
二、功能展示
1、PC端編寫了一個us^raNSfer.ko,能夠向device端發(fā)送數(shù)據(jù)
2、對目標(biāo)平臺編寫一個gadget驅(qū)動,名稱是g_zero.ko
3、測試步驟
在目標(biāo)平臺(基于S3C2410)上加載gadget驅(qū)動
# insmod g_zero.ko
name=ep1-bulk
smdk2410_udc: Pull-up enable
# mknod /dev/usb_rcv c 251 0
#
在PC主機上加載驅(qū)動us^ransfer.ko
#insmod us^ransfer.ko
#mknod /dev/us^ransfer c 266 0
連接設(shè)備,目標(biāo)平臺的終端顯示:
cONnected
目標(biāo)平臺讀取數(shù)據(jù)
# cat /dev/usb_rcv
PC端發(fā)送數(shù)據(jù)
#echo “12345” > /dev/us^ransfer
#echo “abcd” > /dev/us^ransfer
設(shè)備端會顯示收到的數(shù)據(jù)
# cat /dev/usb_rcv
12345
abcd
三、代碼分析
下面的代碼是在原有的zero.c基礎(chǔ)上做了精簡、修改的。一些結(jié)構(gòu)的名稱還是保留以前的,但含義有所變化。如:loopback_config,不再表示loopback,而只是單向的接收數(shù)據(jù)。
/*
* 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設(shè)備結(jié)構(gòu)
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 = { //設(shè)備描述符
.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操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)linux相關(guān)文章:linux教程
評論