第十章Composite设备
10.1 Composite设备介绍
USB的Composite类是USB 复合设备类,一个USB设备具有多种设备功能,比如一个USB设备同时具有鼠标和键盘功能。单一的USB设备开发相对简单,但在很多时候使用的USB设备具有多种功能。Composite类可以满足这种要求。
10.2 Composite数据类型
usbdcomp.h中已经定义好composite设备类中使用的所有数据类型和函数。下面介绍composite设备类使用的数据类型。
typedef struct
{
const tDeviceInfo *pDeviceInfo;
const tConfigHeader *psConfigHeader;
unsigned char ucIfaceOffset;
} tUSBDCompositeEntry;
tUSBDCompositeEntry,定义composite设备信息。定义在usbdcomp.h。
typedef struct
{
unsigned long ulUSBBase;
tDeviceInfo *psDevInfo;
tConfigDescriptor sConfigDescriptor;
tDeviceDescriptor sDeviceDescriptor;
tConfigHeader sCompConfigHeader;
tConfigSection psCompSections[2];
tConfigSection *ppsCompSections[2];
unsigned long ulDataSize;
unsigned char *pucData;
}
tCompositeInstance;
tCompositeInstance,设备类实例。定义了Composite设备类的USB基地址、设备信息、IN端点、OUT端点等信息。
typedef struct
{
const tDeviceInfo *psDevice;
void *pvInstance;
}
tCompositeEntry;
tCompositeEntry,Composite各设备的设备信息。
typedef struct
{
unsigned short usVID;
unsigned short usPID;
unsigned short usMaxPowermA;
unsigned char ucPwrAttributes;
tUSBCallback pfnCallback;
const unsigned char * const *ppStringDescriptors;
unsigned long ulNumStringDescriptors;
unsigned long ulNumDevices;
tCompositeEntry *psDevices;
tCompositeInstance *psPrivateData;
}
tUSBDCompositeDevice;
tUSBDCompositeDevice,Composite设备类,定义了VID、PID、电源属性、字符串描述符等,还包括了Composite设备类实例。其它设备描述符、配置信息通过API函数储入tCompositeInstance定义的Composite设备实例中。
10.3 API函数
在Composite设备类API库中定义了2个函数,完成USB Composite设备初始化、配置及数据处理。下面为usbdcomp.h中定义的API函数:
void *USBDCompositeInit(unsigned long ulIndex,
tUSBDCompositeDevice *psCompDevice,
unsigned long ulSize,
unsigned char *pucData);
void USBDCompositeTerm(void *pvInstance);
void *USBDCompositeInit(unsigned long ulIndex,
tUSBDCompositeDevice *psCompDevice,
unsigned long ulSize,
unsigned char *pucData);
作用:初始化Composite设备硬件、协议,把其它配置参数填入psCompDevice实例中。
参数:ulIndex,USB模块代码,固定值:USB_BASE0。psMSCDevice,MSC设备类。
返回:指向配置后的tUSBDCompositeDevice。
void USBDCompositeTerm(void *pvInstance);
作用:结束Composite设备。
参数:pvInstance,指向tUSBDCompositeDevice。
返回:无。
在这些函数中USBDCompositeInit函数最重要,用于处理各子设备信息,保存所有子设备配置及其它数据。
9.4 Composite设备开发
Composite设备开发只需要3步就能完成:各子设备配置、完善接口函数;Composite设备配置、协调;各子设备数据处理。如图2所示,
<ignore_js_op>

图2
下面以“电子教鞭”实例说明使用USB库开发USB Composite设备过程,电子教鞭有两个重要功能,U盘功能和控制功能。所以要做两个子类:大容量存储类与键盘类:
第一步:各子设备配置、完善接口函数:
#define DESCRIPTOR_DATA_SIZE (COMPOSITE_DHID_SIZE + COMPOSITE_DMSC_SIZE)
unsigned char g_pucDescriptorData[DESCRIPTOR_DATA_SIZE];
//声明函数原型
unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgParam,
void *pvMsgData);
//声明函数原型
unsigned long KeyboardHandler(void *pvCBData,
unsigned long ulEvent,
unsigned long ulMsgData,
void *pvMsgData);
unsigned long EventHandler(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgData, void *pvMsgData);
const tUSBDMSCDevice g_sMSCDevice;
//msc状态
volatile enum
{
MSC_DEV_DISCONNECTED,
MSC_DEV_CONNECTED,
MSC_DEV_IDLE,
MSC_DEV_READ,
MSC_DEV_WRITE,
}
g_eMSCState;
//全局标志
#define FLAG_UPDATE_STATUS 1
static unsigned long g_ulFlags;
//DMA
tDMAControlTable sDMAControlTable[64] __attribute__ ((aligned(1024)));
//****************************************************************************
// 语言描述符
//****************************************************************************
const unsigned char g_pLangDescriptor[] =
{
4,
USB_DTYPE_STRING,
USBShort(USB_LANG_EN_US)
};
//****************************************************************************
// 制造商 字符串 描述符
//****************************************************************************
const unsigned char g_pManufacturerString[] =
{
(17 + 1) * 2,
USB_DTYPE_STRING,
'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0,
't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0,
};
//****************************************************************************
//产品 字符串 描述符
//****************************************************************************
const unsigned char g_pProductString[] =
{
(19 + 1) * 2,
USB_DTYPE_STRING,
'M', 0, 'a', 0, 's', 0, 's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0, 'r', 0,
'a', 0, 'g', 0, 'e', 0, ' ', 0, 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0,
'e', 0
};
//****************************************************************************
// 产品 序列号 描述符
//****************************************************************************
const unsigned char g_pSerialNumberString[] =
{
(8 + 1) * 2,
USB_DTYPE_STRING,
'1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0
};
//*****************************************************************************
// 字符串描述符集合
//*****************************************************************************
const unsigned char * const g_pStringDescriptors[] =
{
g_pLangDescriptor,
g_pManufacturerString,
g_pProductString,
g_pSerialNumberString,
};
#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) / \
sizeof(unsigned char *))
//*****************************************************************************
//MSC实例,配置并为设备信息提供空间
//*****************************************************************************
tMSCInstance g_sMSCInstance;
//*****************************************************************************
//msc设备配置
//*****************************************************************************
const tUSBDMSCDevice g_sMSCDevice =
{
USB_VID_STELLARIS,
USB_PID_MSC,
"TI ",
"Mass Storage ",
"1.00",
200,
USB_CONF_ATTR_SELF_PWR,
g_pStringDescriptors,
NUM_STRING_DESCRIPTORS,
{
USBDMSCStorageOpen,
USBDMSCStorageClose,
USBDMSCStorageRead,
USBDMSCStorageWrite,
USBDMSCStorageNumBlocks
},
USBDMSCEventCallback,
&g_sMSCInstance
};
#define MSC_BUFFER_SIZE 512
//*****************************************************************************
//键盘实例,配置并为设备信息提供空间
//*****************************************************************************
tHIDKeyboardInstance g_KeyboardInstance;
//*****************************************************************************
//键盘设备配置
//*****************************************************************************
const tUSBDHIDKeyboardDevice g_sKeyboardDevice =
{
USB_VID_STELLARIS,
USB_VID_STELLARIS,
200,
USB_CONF_ATTR_SELF_PWR | USB_CONF_ATTR_RWAKE,
KeyboardHandler,
(void *)&g_sKeyboardDevice,
0,
0,
&g_KeyboardInstance
};
//*****************************************************************************
//callback函数
//*****************************************************************************
unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgParam, void *pvMsgData)
{
switch(ulEvent)
{
// 正在写数据到存储设备.
case USBD_MSC_EVENT_WRITING:
{
break;
}
//读取数据.
case USBD_MSC_EVENT_READING:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);
break;
}
//空闲
case USBD_MSC_EVENT_IDLE:
default:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x00);
break;
}
}
return(0);
}
//*****************************************************************************
//键盘callback函数
//*****************************************************************************
unsigned long KeyboardHandler(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgData, void *pvMsgData)
{
switch (ulEvent)
{
case USB_EVENT_CONNECTED:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);
break;
}
case USB_EVENT_DISCONNECTED:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x00);
break;
}
case USB_EVENT_TX_COMPLETE:
{
break;
}
case USB_EVENT_SUSPEND:
{
break;
}
case USB_EVENT_RESUME:
{
break;
}
case USBD_HID_KEYB_EVENT_SET_LEDS:
{
break;
}
default:
{
break;
}
}
return (0);
}
第二步:完成Composite设备配置、协调:
//*****************************************************************************
//复合设备配置
//*****************************************************************************
tCompositeEntry g_psCompDevices[]=
{
{
&g_sMSCDeviceInfo,
(void *)&g_sMSCDeviceInfo
},
{
&g_sHIDDeviceInfo,
(void *)&g_sHIDDeviceInfo
}
};
#define NUM_DEVICES (sizeof(g_psCompDevices)/sizeof(tCompositeEntry))
tCompositeInstance g_CompInstance;
unsigned long xxx[10];
tUSBDCompositeDevice g_sCompDevice =
{
USB_VID_STELLARIS,
0x0123,
500,
USB_CONF_ATTR_BUS_PWR,
EventHandler,
g_pStringDescriptors,
NUM_STRING_DESCRIPTORS,
2,
g_psCompDevices,
xxx,
&g_CompInstance
};
//*****************************************************************************
//复合设备callback函数
//*****************************************************************************
unsigned long EventHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgData,
void *pvMsgData)
{
unsigned long ulNewEvent;
ulNewEvent = 1;
switch(ulEvent)
{
case USB_EVENT_CONNECTED:
{
break;
}
case USB_EVENT_DISCONNECTED:
{
break;
}
case USB_EVENT_SUSPEND:
{
break;
}
case USB_EVENT_RESUME:
{
break;
}
default:
{
ulNewEvent = 0;
break;
}
}
if(ulNewEvent)
{
}
return(0);
}
第三步:各子设备数据处理,主要是按键处理,U盘功能自动调用底层驱动自动完成:
//系统初始化。
SysCtlLDOSet(SYSCTL_LDO_2_75V);
SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,0xf0);
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,0x0f);
HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= 0x0f;
// ucDMA配置
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlDelay(10);
uDMAControlBaseSet(&sDMAControlTable[0]);
uDMAEnable();
g_ulFlags = 0;
g_eMSCState = MSC_DEV_IDLE;
//复合设备初始化
g_sCompDevice.psDevices[0].pvInstance =
USBDMSCCompositeInit(0, &g_sMSCDevice);
g_sCompDevice.psDevices[1].pvInstance =
USBDHIDKeyboardInit(0, &g_sKeyboardDevice);
USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_DATA_SIZE,
g_pucDescriptorData);
//初始化存储设备
disk_initialize(0);
while(1)
{
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, HID_KEYB_CAPS_LOCK,
HID_KEYB_USAGE_A,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_0)
? false : true);
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,
HID_KEYB_USAGE_DOWN_ARROW,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_1)
? false : true);
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,
HID_KEYB_USAGE_UP_ARROW,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_2)
? false : true);
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,
HID_KEYB_USAGE_ESCAPE,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_3)
? false : true);
SysCtlDelay(SysCtlClockGet()/3000);
}
使用上面三步就完成Composite设备开发。Composite设备开发时要加入两个lib库函数: usblib.lib和DriverLib.lib,在启动代码中加入USB0DeviceIntHandler中断服务函数。以上Composite备开发完成,在Win xp下运行效果如下图所示:
<ignore_js_op>
在电脑中可以发现多了USB MSC设备和HID设备,同时还多了一个Composite设备。
Composite设备开发源码较多,下面只列出一部分如下:
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_gpio.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"
#include "driverlib/systick.h"
#include "driverlib/usb.h"
#include "driverlib/udma.h"
#include "usblib/usblib.h"
#include "usblib/usb-ids.h"
#include "usblib/device/usbdevice.h"
#include "usblib/device/usbdmsc.h"
#include "diskio.h"
#include "usbdsdcard.h"
#include "usblib/usblib.h"
#include "usblib/usbhid.h"
#include "usblib/device/usbdhid.h"
#include "usblib/device/usbdcomp.h"
#include "usblib/device/usbdhidkeyb.h"
#define DESCRIPTOR_DATA_SIZE (COMPOSITE_DHID_SIZE + COMPOSITE_DMSC_SIZE)
unsigned char g_pucDescriptorData[DESCRIPTOR_DATA_SIZE];
//声明函数原型
unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgParam,
void *pvMsgData);
//声明函数原型
unsigned long KeyboardHandler(void *pvCBData,
unsigned long ulEvent,
unsigned long ulMsgData,
void *pvMsgData);
unsigned long EventHandler(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgData, void *pvMsgData);
const tUSBDMSCDevice g_sMSCDevice;
//msc状态
volatile enum
{
MSC_DEV_DISCONNECTED,
MSC_DEV_CONNECTED,
MSC_DEV_IDLE,
MSC_DEV_READ,
MSC_DEV_WRITE,
}
g_eMSCState;
//全局标志
#define FLAG_UPDATE_STATUS 1
static unsigned long g_ulFlags;
//DMA
tDMAControlTable sDMAControlTable[64] __attribute__ ((aligned(1024)));
//****************************************************************************
// 语言描述符
//****************************************************************************
const unsigned char g_pLangDescriptor[] =
{
4,
USB_DTYPE_STRING,
USBShort(USB_LANG_EN_US)
};
//****************************************************************************
// 制造商 字符串 描述符
//****************************************************************************
const unsigned char g_pManufacturerString[] =
{
(17 + 1) * 2,
USB_DTYPE_STRING,
'T', 0, 'e', 0, 'x', 0, 'a', 0, 's', 0, ' ', 0, 'I', 0, 'n', 0, 's', 0,
't', 0, 'r', 0, 'u', 0, 'm', 0, 'e', 0, 'n', 0, 't', 0, 's', 0,
};
//****************************************************************************
//产品 字符串 描述符
//****************************************************************************
const unsigned char g_pProductString[] =
{
(19 + 1) * 2,
USB_DTYPE_STRING,
'M', 0, 'a', 0, 's', 0, 's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0, 'r', 0,
'a', 0, 'g', 0, 'e', 0, ' ', 0, 'D', 0, 'e', 0, 'v', 0, 'i', 0, 'c', 0,
'e', 0
};
//****************************************************************************
// 产品 序列号 描述符
//****************************************************************************
const unsigned char g_pSerialNumberString[] =
{
(8 + 1) * 2,
USB_DTYPE_STRING,
'1', 0, '2', 0, '3', 0, '4', 0, '5', 0, '6', 0, '7', 0, '8', 0
};
//*****************************************************************************
// 字符串描述符集合
//*****************************************************************************
const unsigned char * const g_pStringDescriptors[] =
{
g_pLangDescriptor,
g_pManufacturerString,
g_pProductString,
g_pSerialNumberString,
};
#define NUM_STRING_DESCRIPTORS (sizeof(g_pStringDescriptors) / \
sizeof(unsigned char *))
//*****************************************************************************
//MSC实例,配置并为设备信息提供空间
//*****************************************************************************
tMSCInstance g_sMSCInstance;
//*****************************************************************************
//msc设备配置
//*****************************************************************************
const tUSBDMSCDevice g_sMSCDevice =
{
USB_VID_STELLARIS,
USB_PID_MSC,
"TI ",
"Mass Storage ",
"1.00",
200,
USB_CONF_ATTR_SELF_PWR,
g_pStringDescriptors,
NUM_STRING_DESCRIPTORS,
{
USBDMSCStorageOpen,
USBDMSCStorageClose,
USBDMSCStorageRead,
USBDMSCStorageWrite,
USBDMSCStorageNumBlocks
},
USBDMSCEventCallback,
&g_sMSCInstance
};
#define MSC_BUFFER_SIZE 512
//*****************************************************************************
//键盘实例,配置并为设备信息提供空间
//*****************************************************************************
tHIDKeyboardInstance g_KeyboardInstance;
//*****************************************************************************
//键盘设备配置
//*****************************************************************************
const tUSBDHIDKeyboardDevice g_sKeyboardDevice =
{
USB_VID_STELLARIS,
USB_VID_STELLARIS,
200,
USB_CONF_ATTR_SELF_PWR | USB_CONF_ATTR_RWAKE,
KeyboardHandler,
(void *)&g_sKeyboardDevice,
0,
0,
&g_KeyboardInstance
};
//*****************************************************************************
//复合设备配置
//*****************************************************************************
tCompositeEntry g_psCompDevices[]=
{
{
&g_sMSCDeviceInfo,
(void *)&g_sMSCDeviceInfo
},
{
&g_sHIDDeviceInfo,
(void *)&g_sHIDDeviceInfo
}
};
#define NUM_DEVICES (sizeof(g_psCompDevices)/sizeof(tCompositeEntry))
tCompositeInstance g_CompInstance;
unsigned long xxx[10];
tUSBDCompositeDevice g_sCompDevice =
{
USB_VID_STELLARIS,
0x0124,
500,
USB_CONF_ATTR_BUS_PWR,
EventHandler,
g_pStringDescriptors,
NUM_STRING_DESCRIPTORS,
2,
g_psCompDevices,
xxx,
&g_CompInstance
};
//*****************************************************************************
//callback函数
//*****************************************************************************
unsigned long USBDMSCEventCallback(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgParam, void *pvMsgData)
{
switch(ulEvent)
{
// 正在写数据到存储设备.
case USBD_MSC_EVENT_WRITING:
{
break;
}
//读取数据.
case USBD_MSC_EVENT_READING:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x10);
break;
}
//空闲
case USBD_MSC_EVENT_IDLE:
default:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x10,0x00);
break;
}
}
return(0);
}
//*****************************************************************************
//键盘callback函数
//*****************************************************************************
unsigned long KeyboardHandler(void *pvCBData, unsigned long ulEvent,
unsigned long ulMsgData, void *pvMsgData)
{
switch (ulEvent)
{
case USB_EVENT_CONNECTED:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x20);
break;
}
case USB_EVENT_DISCONNECTED:
{
GPIOPinWrite(GPIO_PORTF_BASE,0x20,0x00);
break;
}
case USB_EVENT_TX_COMPLETE:
{
break;
}
case USB_EVENT_SUSPEND:
{
break;
}
case USB_EVENT_RESUME:
{
break;
}
case USBD_HID_KEYB_EVENT_SET_LEDS:
{
break;
}
default:
{
break;
}
}
return (0);
}
//*****************************************************************************
//复合设备callback函数
//*****************************************************************************
unsigned long EventHandler(void *pvCBData, unsigned long ulEvent, unsigned long ulMsgData,
void *pvMsgData)
{
unsigned long ulNewEvent;
ulNewEvent = 1;
switch(ulEvent)
{
case USB_EVENT_CONNECTED:
{
break;
}
case USB_EVENT_DISCONNECTED:
{
break;
}
case USB_EVENT_SUSPEND:
{
break;
}
case USB_EVENT_RESUME:
{
break;
}
default:
{
ulNewEvent = 0;
break;
}
}
if(ulNewEvent)
{
}
return(0);
}
//*****************************************************************************
//主函数
//*****************************************************************************
int main(void)
{
//系统初始化。
SysCtlLDOSet(SYSCTL_LDO_2_75V);
SysCtlClockSet(SYSCTL_XTAL_8MHZ | SYSCTL_SYSDIV_8 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN );
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,0xf0);
GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,0x0f);
HWREG(GPIO_PORTF_BASE+GPIO_O_PUR) |= 0x0f;
// ucDMA配置
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlDelay(10);
uDMAControlBaseSet(&sDMAControlTable[0]);
uDMAEnable();
g_ulFlags = 0;
g_eMSCState = MSC_DEV_IDLE;
//复合设备初始化
g_sCompDevice.psDevices[0].pvInstance =
USBDMSCCompositeInit(0, &g_sMSCDevice);
g_sCompDevice.psDevices[1].pvInstance =
USBDHIDKeyboardInit(0, &g_sKeyboardDevice);
USBDCompositeInit(0, &g_sCompDevice, DESCRIPTOR_DATA_SIZE,
g_pucDescriptorData);
//初始化存储设备
disk_initialize(0);
while(1)
{
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, HID_KEYB_CAPS_LOCK,
HID_KEYB_USAGE_A,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_0)
? false : true);
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,
HID_KEYB_USAGE_DOWN_ARROW,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_1)
? false : true);
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,
HID_KEYB_USAGE_UP_ARROW,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_2)
? false : true);
USBDHIDKeyboardKeyStateChange((void *)&g_sKeyboardDevice, 0,
HID_KEYB_USAGE_ESCAPE,
(GPIOPinRead(GPIO_PORTF_BASE, 0x0f) & GPIO_PIN_3)
? false : true);
SysCtlDelay(SysCtlClockGet()/3000);
}
}
第十章Composite设备的更多相关文章
- USB组合设备 Interface Association Descriptor (IAD)
Communication Device Class,简称CDCUSB Compound Device,USB复合设备USB Composite Device,USB组合设备 摘要USB复合设备 Co ...
- Linux下时钟框架实践---一款芯片的时钟树配置
关键词:时钟.PLL.Mux.Divider.Gate.clk_summary等. 时钟和电源是各种设备的基础设施,整个时钟框架可以抽象为几种基本的元器件:负责提供晶振 Linux内核提供了良好的CC ...
- Linux usb gadget框架概述
很幸运,在公司开发了gadget相关驱动,总结下来,大大小小开发了四个与gadget相关的驱动,字符驱动.g_multi.g_ether.g_zero,在这里把自己对gadget的开发中自己的感悟记录 ...
- USB Compound Device,USB复合设备 ; USB Composite Device,USB组合设备【转】
本文转载自:https://blog.csdn.net/autumn20080101/article/details/52776863 科普下USB复合设备和USB组合设备的区别. 关键字 Commu ...
- windows无法停用“Android Composite Interface”设备的解决方法
遇到这个问题时,解决方法如下: 打开设备管理器 -> 进程 -> 找到 adb.exe -> 右击选择结束进程 -> 然后重新弹出Android设备
- Android composite adb interface
我的平板连上电脑后,在eclipse的DDMS中查看不到.很奇怪以前不会,我以为在进程中有其他的adb.exe冲突.查看任务管理器没有看到其他adb.exe进程.然后重启eclipse也不用,重启电脑 ...
- 20135306黄韧 附录A及第十章学习总结
附录A 错误处理 A.1 Unix系统中的错误处理 1.Unix风格的错误处理 if ((pid = wait(NULL)) < 0) { fprintf(stderr,”wait error ...
- [platform]新旧内核的device设备注册对比
转自:http://blog.chinaunix.net/uid-7332782-id-3268801.html 1. Version2.6内核启动过程 start_kernel( ) //板子上电启 ...
- android 与usb 设备通信(二)
再次遇到android mUsbManager.getDevicelist() 得不到usb 设备的问题.于是深入去探讨android 与usb 外围设备通信的问题.第一篇文章写的有点乱,本质就是需 ...
随机推荐
- lrzsz on linux
Linux Disibutaion:Ubuntu 16.04.1 LTS lrzsz是一款在linux里可代替ftp上传和下载的程序. 1.下载lrzsz源码包 #下载源码包 wget https:/ ...
- 解决从linux本地文件系统上传文件到HDFS时的权限问题
当使用 hadoop fs -put localfile /user/xxx 时提示: put: Permission denied: user=root, access=WRITE, inode=& ...
- mysql安全
安装MySql时,尽量选择别的端口(默认是3306),密码设复杂一点!在next的步骤中,注意不要选中"允许远程登录". Web漏洞检测及修复 http://wiki.open.q ...
- 信鸽推送.net 服务端代码
//推送代码 private void send() { #region 安卓推送 XingeApp app = new XingeApp("accessId", "se ...
- 包含为 HTTP 定义的状态代码的值(枚举)
using System; namespace System.Net { // 摘要: // 包含为 HTTP 定义的状态代码的值. public enum HttpStatusCode { // 摘 ...
- 使用C++11安全的在线程中控制UI
本篇文章由:http://www.sollyu.com/using-the-c11-secure-online-process-control-ui/ 说明 首先这里使用的是 Visual Studi ...
- 【NOI2001】炮兵阵地
[题目描述] 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形 ...
- Headfirst设计模式的C++实现——外观模式(Facade)
light.h #ifndef _LIGHT_H_ #define _LIGHT_H_ #include <iostream> class LIGHT { public: void dim ...
- Linux DNS 设置失败
在执行 yum install gcc 时 发现下载失败 ping www.baidu.com ping 不通 ping 百度的IP:220.181.111.188却能ping 通 由此证明是DNS的 ...
- 纯javascript 回到 顶部 实例
很多网站都会采用瀑布式的加载模式,像qq空间加载好友动态,为了用户体验更好,很多网站会加上回到顶部的连接,但大多数网站都是一下子就回到了顶部,当然,这样有这样的好处,但是我是个比较喜欢很炫的东西的人, ...