USB驱动中,设备相关的类及其继承关系如下:
CDevice (ADT)
/ /
CFunction CHub (ADT)
/ /
CRootHub CExternalHub
父类CDevice中包含一个虚函数成员EnterOperationalState。各个子类中,根据需要,对该函数有不同的实现。
各个子类的EnterOperationalState函数被调用的地方也不相同。其中,CRootHub的该函数,在函数CEhcd::DeviceInitialize中被调用。CFunction和CExternalHub的该函数在函数CHub::HubStatusChangeThread中被调用。
也就是说,在HCD进行Device初始化的时候,会首先启动Root Hub的监视线程。
若有External Hub插入Root Hub,Root Hub 会启动External Hub的监视线程。若有Function插入Root Hub,Root Hub会启动Function的USB传输。
当External Hub和Function插入到External Hub时,操作与插入到Root Hub类似。
下面具体说说各个子类中,函数EnterOperationalState的实现。
1、函数CRootHub::EnterOperationalState
// 成员变量check
// 创建事件m_hHubStatusChangeEvent - Auto Reset, and Initial State = non-signaled
m_hHubStatusChangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
//创建设备列表。
AllocateDeviceArray()
// 启动状态改变监视线程,并设置线程优先级
m_hHubStatusChangeThread = CreateThread( 0, 0, HubStatusChangeThreadStub, this, 0, NULL );
CeSetThreadPriority( m_hHubStatusChangeThread, g_IstThreadPriority);
2、函数CExternalHub::EnterOperationalState
// 成员变量check
// 参数checkpEndpoint0Pipe != NULL
// 创建事件m_hHubStatusChangeEvent - Auto Reset, and Initial State = non-signaled
m_hHubStatusChangeEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
// 检查endpoint的Descriptor
// 创建InterruptPipe
CPipeAbs* pStatusChangePipe = CreateInterruptPipe ( &m_deviceInfo.lpActiveConfig->lpInterfaces[0].lpEndpoints[0].Descriptor,
m_fIsLowSpeed,m_fIsHighSpeed,m_address,
uTTAddress,uTTPort,
m_pCHcd);
// 分配Pipe数组的空间
AllocatePipeArray()
// AllocatePipeArray函数,根据m_deviceInfo结构体中endpoint的个数分配pipe array需要的内存
m_ppCPipe = new CPipeAbs* [ numPipes ];
//创建设备列表。
AllocateDeviceArray()
// 打开InterruptPipe
pStatusChangePipe->OpenPipe()
// 由于状态监视线程中要用到Control Pipe和Interrupt Pipe,需要将它们保存到成员变量中
m_ppCPipe[ ENDPOINT0_CONTROL_PIPE ] = pEndpoint0Pipe; // pEndpoint0Pipe参数传入
m_ppCPipe[ STATUS_CHANGE_INTERRUPT_PIPE ] = pStatusChangePipe;
// 启动状态改变监视线程,并设置线程优先级
m_hHubStatusChangeThread = CreateThread( 0, 0, HubStatusChangeThreadStub, this, 0, NULL );
CeSetThreadPriority( m_hHubStatusChangeThread, g_IstThreadPriority);
3、函数CFunction::EnterOperationalState
// 成员变量check
// 参数checkpEndpoint0Pipe != NULL
// 创建事件m_hFunctionFeatureEvent - Auto Reset, and Initial State = non-signaled
m_hFunctionFeatureEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
// 分配Pipe数组的空间
AllocatePipeArray()
// AllocatePipeArray函数,根据m_deviceInfo结构体中endpoint的个数分配pipe array需要的内存
m_ppCPipe = new CPipeAbs* [ numPipes ];
// 保存Control Pipe到成员变量
m_ppCPipe[ ENDPOINT0_CONTROL_PIPE ] = pEndpoint0Pipe;
// 调用USBD中的函数HcdDeviceAttached。
// 调用方式:通过成员变量m_pCHcd获取函数指针进行调用
// m_pCHcd中CFunction对象构造时被传入
// CFunction对象的构造在函数CHub::AttachDevice中进行。也就是在Root Hub或者External Hub的AttachDevice函数中进行创建。
// 所以,m_pCHcd最终是在Root Hub对象创建的时候传入
// Root Hub对象在函数CEhcd::DeviceInitialize中被创建,传入的CHcd对象的指针式This指针
// 追溯发现,函数GetpUSBDAttachProc的实现在类CDeviceGlobal中 : { return m_pUSBDAttachProc; }
// 成员变量m_pUSBDAttachProc的赋值在函数CDeviceGlobal::Initialize中,如下:
// m_hUSBDInstance = LoadDriver(TEXT("USBD.DLL"));
// m_pUSBDAttachProc = (LPUSBD_ATTACH_PROC) GetProcAddress(m_hUSBDInstance, TEXT("HcdDeviceAttached"));
fSuccess = (*m_pCHcd->GetpUSBDAttachProc())(m_pCHcd->GetpHcdContext(), // context for Host Controller Driver
m_address, // used to indicate this specific device
ENDPOINT0_CONTROL_PIPE, // index of endpoint 0 pipe
LPCUSB_DEVICE( &m_deviceInfo ), // USB descriptors
&m_lpvDetachId ); // used to tell USBD this device is being detached
HCD相关,类的继承关系:
CDeviceGlobal LockObject
/ / /
CHcd USB2lib
/ /
CHW /
/ /
CEhcd
分享到:
相关推荐
驱动程序的编写上, 与Linux是一致的, 无需关心任何Android相关的事物. 代码如下: #include #include #include #include #include #include #include static dev_t dev_num = 0; static struct cdev *cdevice = ...
I2C相关库文件 AD7746 Restructure repository to better support multiple platforms 2 years ago ADS1115 Fix issue when changing MUX or PGA, an invalid result is 9 months ago ADXL345 Updating I2Cdev ...
Arduino-Adafruit-GFX-Font-Customiser.zip,为adafruit gfx库定制像素字体的一个小实用程序adafruit gfx像素字体定制器,Arduino是一家开源软硬件公司和制造商社区。Arduino始于21世纪初,深受电子制造商的欢迎,...
Adafuit library BusIO
I2CDevice和SPIDevice帮助器类使管理总线上的事务状态变得容易。 例如,他们管理锁定总线以防止其他并发访问。 对于SPI设备,它管理芯片选择和协议更改(例如模式)。 对于I2C,它管理设备地址。 在Raspberry Pi等...
i2c-dotnet 是.NET Core库,用于使用共享库Raspberry Pi上的设备/ dev / i2c-0 / dev / i2c-1 在Raspberry Pi 3上测试要运行该库,首先需要在Raspberry P中安装
Adafruit总线IO库 这是一个辅助库,用于抽象掉I2C和SPI事务和寄存器 Adafruit投入时间和资源来提供此开源代码,请通过从Adafruit购买产品来支持Adafruit和开源硬件! MIT许可证,任何重新分发中都必须包含上述所有...
i2cdev 非常简单的用于 linux 的 i2c 模块 from devi2c import I2Cdevice, bus = 0x42, 0i2c = I2C(device, bus)value = i2c.read(1) # read 1 bytei2c.write(b’some raw data’) # write bytesi2c.close() # close...
用于与 HMC5883L 3 轴... I2CDevice库提供了HMC5883L类和 Arduino 微控制器之间的接口,并且可以替换为任何等效接口以支持其他接口。 可以在找到该库的完整文档。 此代码是根据知识共享署名 4.0 国际许可 ( ) 发布的。