如何在 CompleteAsyncIO 中访问 IOMemoryBufferDescriptor,该描述符通过中断 EP
How to access the IOMemoryBufferDescriptor in CompleteAsyncIO, which is sent through AsyncIO on Interrupt EP
我正在尝试使用AsyncIO为中断EP发送请求,对于AsyncIO,我已经创建了IOMemoryBufferDescriptor,一旦IOMemoryBufferDescriptor,创建是成功的,我使用了GetAddressRange并将地址存储在dext的ivars结构中。对于此请求完成(CompleteAsyncIO(是使用action-> GetReference((调用的,我得到了ivars结构,我期待从USB设备接收的中断完成数据,不幸的是我没有看到相关数据。在wireshark中,我试图调试接收的数据是16字节,CompleteAsyncIO实际字节也是16字节。
使用 IOMemoryBufferDescribe or 获取从设备接收的中断数据的正确方法是什么?
OSAction Create for CompleteAsyncIO
ret = OSAction::Create(this,
Data_interruptComplete_ID,
IOUSBHostPipe_CompleteAsyncIO_ID,
sizeof(IntActRef),
&ivars->interruptComplete);
USB 中断 EP 的 IOMemoryBufferDescriptor 分配:
IOBufferMemoryDescriptor* fCommPipeMDP;
ivars->fCommPipeMDP->Create(kIOMemoryDirectionIn,
ivars->fcomBuffSize,
0,
&ivars->fCommPipeMDP);
ivars->fCommPipeMDP->SetLength(ivars->fcomBuffSize);
ivars->fCommPipeMDP->GetAddressRange(&aRange);
ivars->fCommPipeBuffer = (uint8_t*)&aRange.address;
发送异步IO请求以中断EP
ret = ivars->fCommPipe->AsyncIO(ivars->fCommPipeMDP,
ivars->fcomBuffSize,
ivars->interruptComplete,
0);
框架调用的 CompleteAsyncIO
void
IMPL (ClassData,interruptComplete)
{
struct interruptActionRef *actionref = (struct interruptActionRef*)action->GetReference();
Data_IVars * livars = actionref->interruptactionref;
for(tmp = 0; tmp < actualByteCount; tmp++)
os_log(OS_LOG_DEFAULT, "%x",livars->fCommPipeBuffer[tmp]);
//TRYING PRINT DATA RECEIVED FROM USB DEVICE IN INTERRUPT COMPLETION(CompleteAsyncIO)
//UNFORTUNATELY DATA IS NOT MATCHING
}
如何使用我使用 AsyncIO 发送的 IOBufferMemoryDescriptor 获取从 USB 设备接收的实际数据以进行中断完成?是否需要将地址映射到当前进程地址空间?
我看到带有USB过滤器的wireshark只有实际数据长度匹配。
Wireshark 日志 a1 2000 00 01 00 02 00 03 00 00 00 00 00 00 00 (16 字节数据("3029","32.105745","64.16.4","主机","USB","40","URB_INTERRUPT in (已提交(" "3030","32.169565","64.16.4","主机","USB","56","URB_INTERRUPT输入(已完成(">
0000 01 01 28 01 10 00 00 00 00 00 00 00 00 00 00 00 ..(.............
0010 31 d8 05 00 00 00 00 00 00 00 40 14 02 10 84 03 1.........@.....
0020 ff 02 01 00 04 10 3e 63 a1 20 00 00 01 00 02 00 ......>c. ......
0030 03 00 00 00 00 00 00 00
问题出在这一行:
ivars->fCommPipeBuffer = (uint8_t*)&aRange.address;
这是保存指向IOAddressSegment
结构变量的地址字段的指针,而不是指向缓冲区本身的指针。你想要:
ivars->fCommPipeBuffer = (uint8_t*)aRange.address;
或者,不太容易出错且更惯用C++:
ivars->fCommPipeBuffer = reinterpret_cast<uint8_t*>(aRange.address);
(虽然公平地说,类型检查器仍然不会发现错误;但是静态分析可能会发现。
使用正确的缓冲区指针,它应该开始输出正确的数据。
- 使用VerQueryValue检索应用程序的文件描述
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- PC中的程序和PHONE中的本机描述应用程序之间的数据连接
- 从 Boost ASIO 获取 epoll 描述符 io_service对象
- I2C 文件描述符上的 I2C 总线可写/可读标志
- 如何在 CompleteAsyncIO 中访问 IOMemoryBufferDescriptor,该描述符通过中断 EP
- 如何在动态创建的CMFCToolbar的工具提示中添加描述?
- 下面描述的概念如何在C++14中定义?
- 请描述一下在 c++ 中在此类中定义构造函数的方式?
- numpy.load 给出 ValueError: descr 不是有效的 dtype 描述符:
- 在 Direct3D 12 的描述符范围内设置多个描述符
- 默认安全描述符
- 许多文件描述符在调用sys_clone时
- 按唯一标识符描述数字列表
- AMQP-CPP >处理程序中的错误文件描述符
- 如何使用 WINAPI 和 C++ 提取可执行文件的文件描述?
- Vulkan中的描述符集计数不明确
- 正在等待在非阻塞文件描述符上长时间运行ioctl
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)