HarmonyOS 鸿蒙Next USB DDK 发送数据成功,但是无法接收数据
HarmonyOS 鸿蒙Next USB DDK 发送数据成功,但是无法接收数据
<markdown _ngcontent-ibh-c149="" class="markdownPreContainer">
USB DDK 发送数据成功,但是无法接收数据,接收的时候每次都是返回-7
使用步骤如下:
#define GET_DEV_HANDLE(busNum, devID) ((uint64_t)busNum << 32 | devID & 0xFFFFFFFF)
static napi_value Test(napi_env env, napi_callback_info info)
{
// 从arkts获取USB设备的busNum和devID
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
int busNum;
napi_get_value_int32(env, args[0], &busNum);
int devID;
napi_get_value_int32(env, args[1], &devID);
<span class="hljs-comment">// 初始化USB DDK</span>
int32_t re = OH_Usb_Init();
LOGD(<span class="hljs-string">"OH_Usb_Init结果 : %{public}d"</span>, re);
<span class="hljs-comment">// 生成deviceId</span>
uint64_t deviceId = GET_DEV_HANDLE(value0, value1);
<span class="hljs-comment">// 获取设备描述符</span>
<span class="hljs-keyword">struct</span> UsbDeviceDescriptor devDesc = {};
int32_t re1 = OH_Usb_GetDeviceDescriptor(deviceId, &devDesc);
LOGD(<span class="hljs-string">"OH_Usb_GetDeviceDescriptor : %{public}d"</span>, re1);
LOGD(<span class="hljs-string">"OH_Usb_GetDeviceDescriptor : PID :%{public}d , VID: %{public}d"</span>, devDesc.idProduct, devDesc.idVendor);
<span class="hljs-comment">// 获取配置描述符</span>
<span class="hljs-keyword">struct</span> UsbDdkConfigDescriptor *config = <span class="hljs-keyword">nullptr</span>;
int32_t re2 = OH_Usb_GetConfigDescriptor(deviceId, <span class="hljs-number">1</span>, &config);
LOGD(<span class="hljs-string">"OH_Usb_GetConfigDescriptor : %{public}d"</span>, re2);
<span class="hljs-comment">// 获取发送端点</span>
<span class="hljs-keyword">auto</span> [res, interface, endpoint, maxPktSize] = GetInterfaceAndEndpoint(config);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpoint ret %{public}d"</span>, res);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpoint interface %{public}d"</span>, interface);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpoint endpoint %{public}d"</span>, endpoint);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpoint maxPktSize %{public}d"</span>, maxPktSize);
<span class="hljs-comment">// 获取接收端点</span>
<span class="hljs-keyword">auto</span> [resIn, interfaceIn, endpointIn, maxPktSizeIn] = GetInterfaceAndEndpointIn(config);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpointIn ret %{public}d"</span>, resIn);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpointIn interface %{public}d"</span>, interfaceIn);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpointIn endpoint %{public}d"</span>, endpointIn);
LOGD(<span class="hljs-string">"GetInterfaceAndEndpointIn maxPktSize %{public}d"</span>, maxPktSizeIn);
<span class="hljs-comment">// 根据配置描述符,找到所需要通信的interfaceIndex</span>
<span class="hljs-comment">// 发送</span>
uint64_t interfaceHandle = <span class="hljs-number">0</span>;
int32_t re3 = OH_Usb_ClaimInterface(deviceId, interface, &interfaceHandle);
<span class="hljs-comment">// 接收</span>
uint64_t interfaceHandleIn = <span class="hljs-number">0</span>;
int32_t re3In = OH_Usb_ClaimInterface(deviceId, interfaceIn, &interfaceHandleIn);
<span class="hljs-comment">// 发送数据</span>
<span class="hljs-keyword">unsigned</span> <span class="hljs-keyword">char</span> data[] = {<span class="hljs-number">0x01</span>, <span class="hljs-number">0x02</span>, <span class="hljs-number">0x03</span>, <span class="hljs-number">0x04</span>......};
size_t length = <span class="hljs-keyword">sizeof</span>(data) / <span class="hljs-keyword">sizeof</span>(data[<span class="hljs-number">0</span>]);
struct UsbDeviceMemMap *devMmap = nullptr;
// 创建用于存放数据的缓冲区
size_t bufferLen = length;
int32_t reMemMap = OH_Usb_CreateDeviceMemMap(deviceId, bufferLen, &devMmap);
LOGD(“OH_Usb_CreateDeviceMemMap : %{public}d”, reMemMap);
// 拷贝发送的数据
memcpy(devMmap->address, data, length);
struct UsbRequestPipe pipe;
pipe.interfaceHandle = interfaceHandle;
// 根据配置描述符找到所要通信的端点
pipe.endpoint = endpoint;
pipe.timeout = 3000;
// 发送请求
int32_t reRequest = OH_Usb_SendPipeRequest(&pipe, devMmap);
LOGD(“OH_Usb_SendPipeRequest : %{public}d”, reRequest);
LOGD(“OH_Usb_SendPipeRequest bufferLength : %{public}d”, devMmap->bufferLength);
LOGD(“OH_Usb_SendPipeRequest size : %{public}d”, devMmap->size);
LOGD(“OH_Usb_SendPipeRequest transferedLength : %{public}d”, devMmap->transferedLength);
// 释放资源
OH_Usb_DestroyDeviceMemMap(devMmap);
<span class="hljs-comment">// 接收数据</span>
struct UsbDeviceMemMap *devMmap1 = nullptr;
// 创建用于存放数据的缓冲区
size_t bufferLen1 = maxPktSizeIn;
int32_t reMemMap1 = OH_Usb_CreateDeviceMemMap(deviceId, bufferLen1, &devMmap1);
LOGD(“OH_Usb_CreateDeviceMemMap : %{public}d”, reMemMap1);
struct UsbRequestPipe pipe1;
pipe1.interfaceHandle = interfaceHandleIn;
// 根据配置描述符找到所要通信的端点
pipe1.endpoint = endpointIn;
pipe1.timeout = 3000;
// 发送请求
int32_t reRequest1 = OH_Usb_SendPipeRequest(&pipe1, devMmap1);
LOGD(“OH_Usb_ReadPipeRequest : %{public}d”, reRequest1);
LOGD(“OH_Usb_ReadPipeRequest bufferLength : %{public}d”, devMmap1->bufferLength);
LOGD(“OH_Usb_ReadPipeRequest size : %{public}d”, devMmap1->size);
LOGD(“OH_Usb_ReadPipeRequest transferedLength : %{public}d”, devMmap1->transferedLength);
OH_Usb_DestroyDeviceMemMap(devMmap1);
}
更多关于HarmonyOS 鸿蒙Next USB DDK 发送数据成功,但是无法接收数据的实战教程也可以访问 https://www.itying.com/category-93-b0.html
// 定义异步回调结构体  
struct UsbTransferContext {  
    napi_ref callback;  
    napi_env env;  
    uint64_t deviceId;  
    uint8_t* buffer;  
    size_t bufferSize;  
    int32_t status;  
};  
// USB数据接收回调函数  
void UsbReceiveCallback(struct UsbRequestPipe* pipe, struct UsbDeviceMemMap* memMap, void* context) {
UsbTransferContext* transferCtx = static_cast<UsbTransferContext*>(context);
<span class="hljs-keyword">if</span> (memMap->transferedLength > <span class="hljs-number">0</span>) {  
    <span class="hljs-comment">// 快速拷贝数据  </span>
    memcpy(transferCtx->buffer, memMap->address, memMap->transferedLength);  
    transferCtx->status = memMap->transferedLength;  
} <span class="hljs-keyword">else</span> {  
    transferCtx->status = -<span class="hljs-number">1</span>;  
}  
<span class="hljs-comment">// 触发JS回调  </span>
napi_handle_scope scope;  
napi_open_handle_scope(transferCtx->env, &scope);  
napi_value global, callback, result;  
napi_get_global(transferCtx->env, &global);  
napi_get_reference_value(transferCtx->env, transferCtx->callback, &callback);  
<span class="hljs-comment">// 构造返回结果  </span>
napi_create_object(transferCtx->env, &result);  
napi_value jsBuffer, jsLength;  
napi_create_buffer_copy(  
    transferCtx->env,   
    transferCtx->status > <span class="hljs-number">0</span> ? transferCtx->status : <span class="hljs-number">0</span>,   
    transferCtx->buffer,   
    nullptr,   
    &jsBuffer  
);  
napi_create_int32(transferCtx->env, transferCtx->status, &jsLength);  
napi_set_named_property(transferCtx->env, result, <span class="hljs-string">"data"</span>, jsBuffer);  
napi_set_named_property(transferCtx->env, result, <span class="hljs-string">"length"</span>, jsLength);  
<span class="hljs-comment">// 调用回调  </span>
napi_value <span class="hljs-literal">undefined</span>;  
napi_get_undefined(transferCtx->env, &<span class="hljs-literal">undefined</span>);  
napi_call_function(transferCtx->env, global, callback, <span class="hljs-number">1</span>, &result, nullptr);  
napi_close_handle_scope(transferCtx->env, scope);  
<span class="hljs-comment">// 释放资源  </span>
OH_Usb_DestroyDeviceMemMap(memMap);  
<span class="hljs-keyword">delete</span>[] transferCtx->buffer;  
<span class="hljs-keyword">delete</span> transferCtx;  
}
// 高性能USB接收函数  
static napi_value FastUsbReceive(napi_env env, napi_callback_info info) {
size_t argc = 4;
napi_value args[4];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
<span class="hljs-comment">// 解析参数  </span>
int busNum, devID, interfaceIndex, endpointIndex;  
napi_get_value_int32(env, args[<span class="hljs-number">0</span>], &busNum);  
napi_get_value_int32(env, args[<span class="hljs-number">1</span>], &devID);  
napi_get_value_int32(env, args[<span class="hljs-number">2</span>], &interfaceIndex);  
napi_get_value_int32(env, args[<span class="hljs-number">3</span>], &endpointIndex);  
<span class="hljs-comment">// 创建异步上下文  </span>
UsbTransferContext* transferCtx = <span class="hljs-keyword">new</span> UsbTransferContext();  
transferCtx->env = env;  
transferCtx->deviceId = GET_DEV_HANDLE(busNum, devID);  
<span class="hljs-comment">// 获取JS回调  </span>
napi_create_reference(env, args[<span class="hljs-number">4</span>], <span class="hljs-number">1</span>, &transferCtx->callback);  
<span class="hljs-comment">// 准备接收缓冲区  </span>
size_t bufferSize = <span class="hljs-number">1024</span>;  <span class="hljs-comment">// 根据实际需求调整  </span>
transferCtx->buffer = <span class="hljs-keyword">new</span> uint8_t[bufferSize];  
transferCtx->bufferSize = bufferSize;  
<span class="hljs-comment">// 创建内存映射  </span>
struct UsbDeviceMemMap* devMmap = nullptr;  
int32_t reMemMap = OH_Usb_CreateDeviceMemMap(  
    transferCtx->deviceId,   
    bufferSize,   
    &devMmap  
);  
<span class="hljs-keyword">if</span> (reMemMap != <span class="hljs-number">0</span>) {  
    <span class="hljs-comment">// 错误处理  </span>
    <span class="hljs-keyword">delete</span>[] transferCtx->buffer;  
    <span class="hljs-keyword">delete</span> transferCtx;  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 配置管道  </span>
struct UsbRequestPipe pipe;  
pipe.interfaceHandle = OH_Usb_ClaimInterface(transferCtx->deviceId, interfaceIndex, nullptr);  
pipe.endpoint = endpointIndex;  
pipe.timeout = <span class="hljs-number">100</span>;  <span class="hljs-comment">// 极短超时  </span>
<span class="hljs-comment">// 设置异步接收  </span>
OH_Usb_SetPipeCallback(&pipe, UsbReceiveCallback, transferCtx);  
<span class="hljs-comment">// 发起异步读取  </span>
OH_Usb_ReadPipeRequestAsync(&pipe, devMmap);  
<span class="hljs-keyword">return</span> nullptr;  
}
  写的比较快,可能有点小问题,你对照看看
更多关于HarmonyOS 鸿蒙Next USB DDK 发送数据成功,但是无法接收数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
帮你做了点优化,再次运行后可以把更详细的错误日志发给我看看:
#define GET_DEV_HANDLE(busNum, devID) ((uint64_t)busNum << 32 | devID & 0xFFFFFFFF)  
// 错误码映射函数  
const char* MapErrorCode(int32_t errorCode) {
switch(errorCode) {
case -1: return “USB_DDK_ERR_INVALID_PARAMETER”;
case -2: return “USB_DDK_ERR_MEMORY_ALLOC”;
case -3: return “USB_DDK_ERR_DEVICE_NOT_FOUND”;
case -4: return “USB_DDK_ERR_INTERFACE_CLAIM_FAILED”;
case -5: return “USB_DDK_ERR_PIPE_TRANSFER_FAILED”;
case -6: return “USB_DDK_ERR_DEVICE_BUSY”;
case -7: return “USB_DDK_ERR_TIMEOUT”;
default: return “UNKNOWN_ERROR”;
}
}
static napi_value Test(napi_env env, napi_callback_info info)
{
// 从arkts获取USB设备的busNum和devID  
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
int busNum;
napi_get_value_int32(env, args[0], &busNum);
int devID;
napi_get_value_int32(env, args[1], &devID);
<span class="hljs-comment">// 初始化USB DDK  </span>
int32_t re = OH_Usb_Init();  
<span class="hljs-keyword">if</span> (re != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"USB初始化失败: %s"</span>, MapErrorCode(re));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 生成deviceId  </span>
uint64_t deviceId = GET_DEV_HANDLE(busNum, devID);  
<span class="hljs-comment">// 获取设备描述符  </span>
struct UsbDeviceDescriptor devDesc = {};  
int32_t re1 = OH_Usb_GetDeviceDescriptor(deviceId, &devDesc);  
<span class="hljs-keyword">if</span> (re1 != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"获取设备描述符失败: %s"</span>, MapErrorCode(re1));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
LOGD(<span class="hljs-string">"设备描述符 - PID: %d, VID: %d"</span>, devDesc.idProduct, devDesc.idVendor);  
<span class="hljs-comment">// 获取配置描述符  </span>
struct UsbDdkConfigDescriptor *config = nullptr;  
int32_t re2 = OH_Usb_GetConfigDescriptor(deviceId, <span class="hljs-number">1</span>, &config);  
<span class="hljs-keyword">if</span> (re2 != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"获取配置描述符失败: %s"</span>, MapErrorCode(re2));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 获取发送端点  </span>
auto [res, interface, endpoint, maxPktSize] = GetInterfaceAndEndpoint(config);  
<span class="hljs-keyword">if</span> (res != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"获取发送端点失败: %s"</span>, MapErrorCode(res));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 获取接收端点  </span>
auto [resIn, interfaceIn, endpointIn, maxPktSizeIn] = GetInterfaceAndEndpointIn(config);  
<span class="hljs-keyword">if</span> (resIn != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"获取接收端点失败: %s"</span>, MapErrorCode(resIn));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 声明接口  </span>
uint64_t interfaceHandle = <span class="hljs-number">0</span>;  
int32_t re3 = OH_Usb_ClaimInterface(deviceId, interface, &interfaceHandle);  
<span class="hljs-keyword">if</span> (re3 != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"声明发送接口失败: %s"</span>, MapErrorCode(re3));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
uint64_t interfaceHandleIn = <span class="hljs-number">0</span>;  
int32_t re3In = OH_Usb_ClaimInterface(deviceId, interfaceIn, &interfaceHandleIn);  
<span class="hljs-keyword">if</span> (re3In != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"声明接收接口失败: %s"</span>, MapErrorCode(re3In));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 发送数据  </span>
unsigned char data[] = {<span class="hljs-number">0x01</span>, <span class="hljs-number">0x02</span>, <span class="hljs-number">0x03</span>, <span class="hljs-number">0x04</span>};  
size_t length = sizeof(data) / sizeof(data[<span class="hljs-number">0</span>]);  
struct UsbDeviceMemMap *devMmap = nullptr;  
size_t bufferLen = length;  
int32_t reMemMap = OH_Usb_CreateDeviceMemMap(deviceId, bufferLen, &devMmap);  
<span class="hljs-keyword">if</span> (reMemMap != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"创建发送内存映射失败: %s"</span>, MapErrorCode(reMemMap));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
memcpy(devMmap->address, data, length);  
struct UsbRequestPipe pipe;  
pipe.interfaceHandle = interfaceHandle;  
pipe.endpoint = endpoint;  
pipe.timeout = <span class="hljs-number">5000</span>;  <span class="hljs-comment">// 增加超时时间  </span>
int32_t reRequest = OH_Usb_SendPipeRequest(&pipe, devMmap);  
<span class="hljs-keyword">if</span> (reRequest != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"发送数据失败: %s"</span>, MapErrorCode(reRequest));  
    OH_Usb_DestroyDeviceMemMap(devMmap);  
    <span class="hljs-keyword">return</span> nullptr;  
}  
OH_Usb_DestroyDeviceMemMap(devMmap);  
<span class="hljs-comment">// 接收数据 - 使用ReadPipeRequest  </span>
struct UsbDeviceMemMap *devMmapIn = nullptr;  
size_t bufferLenIn = maxPktSizeIn;  
int32_t reMemMapIn = OH_Usb_CreateDeviceMemMap(deviceId, bufferLenIn, &devMmapIn);  
<span class="hljs-keyword">if</span> (reMemMapIn != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"创建接收内存映射失败: %s"</span>, MapErrorCode(reMemMapIn));  
    <span class="hljs-keyword">return</span> nullptr;  
}  
struct UsbRequestPipe pipeIn;  
pipeIn.interfaceHandle = interfaceHandleIn;  
pipeIn.endpoint = endpointIn;  
pipeIn.timeout = <span class="hljs-number">5000</span>;  <span class="hljs-comment">// 增加超时时间  </span>
<span class="hljs-comment">// 使用ReadPipeRequest替代SendPipeRequest  </span>
int32_t reRequestIn = OH_Usb_ReadPipeRequest(&pipeIn, devMmapIn);  
<span class="hljs-keyword">if</span> (reRequestIn != <span class="hljs-number">0</span>) {  
    LOGE(<span class="hljs-string">"接收数据失败: %s"</span>, MapErrorCode(reRequestIn));  
    OH_Usb_DestroyDeviceMemMap(devMmapIn);  
    <span class="hljs-keyword">return</span> nullptr;  
}  
<span class="hljs-comment">// 打印接收到的数据  </span>
LOGD(<span class="hljs-string">"接收数据长度: %zu"</span>, devMmapIn->transferedLength);  
<span class="hljs-keyword">for</span> (size_t i = <span class="hljs-number">0</span>; i < devMmapIn->transferedLength; i++) {  
    LOGD(<span class="hljs-string">"接收数据[%zu]: 0x%02X"</span>, i, ((unsigned char*)devMmapIn->address)[i]);  
}  
OH_Usb_DestroyDeviceMemMap(devMmapIn);  
<span class="hljs-comment">// 释放接口  </span>
OH_Usb_ReleaseInterface(interfaceHandle);  
OH_Usb_ReleaseInterface(interfaceHandleIn);  
<span class="hljs-keyword">return</span> nullptr;  
}
  有帮助的话帮忙点个关注哈
有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html
补充一下:
指令的确下发了,从USB分析仪上抓到了下发的数据,且发送的是开灯指令,设备也开灯了;
然后用 [@ohos](/user/ohos).usbManager 接口也是能正常收发,但是接收数据实在是太慢了,从分析仪上看,设备立马回复了指令,但是app要等500ms后才收到数据,所以才考虑用USB DDK去开发。
针对您提出的HarmonyOS 鸿蒙Next USB DDK发送数据成功但无法接收数据的问题,以下是一些可能的原因及解决方案:
- 
检查接收端配置:
- 确保接收端设备已正确配置并处于接收状态。
 - 检查接收端设备的驱动程序是否正确安装且版本兼容。
 
 - 
验证数据格式与参数:
- 确认发送的数据格式与接收端期望的格式一致。
 - 检查USB DDK使用的参数(如端点地址、超时时间等)是否正确。
 
 - 
检查连接稳定性:
- 确保USB连接稳定,无松动或接触不良现象。
 - 检查是否存在其他设备干扰或冲突。
 
 - 
优化代码实现:
- 尝试使用异步回调机制优化数据接收过程。
 - 确保内存映射和缓冲区管理正确无误。
 
 
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。他们将为您提供更专业的技术支持和解决方案。
        
      
                  
                  
                  

