ToB企服应用市场:ToB评测及商务社交产业平台

标题: 鸿蒙OpenHarmony【外设驱动使用之USB】 子体系 [打印本页]

作者: 天空闲话    时间: 2024-11-20 23:26
标题: 鸿蒙OpenHarmony【外设驱动使用之USB】 子体系
USB

概述

功能简介

USB(Universal Serial Bus)通用串行总线,包含了主机端(Host)和设备端(Device)。主机端负责USB总线中的数据传输及端口管理,设备端则可以毗连各种外设,以是USB驱动开辟又分为主机端驱动开辟和设备端驱动开辟。
OpenHarmony体系USB模块支持USB业务的开辟,提供USB相干的功能,提供用户态第三方功能驱动的USB设备数据读写接口,以及提供创建和删除USB设备,接口的事件获取、打开和关闭等,管道同步异步读写通信,设置USB自界说属性等。
USB DDK(USB DriverDevelop Kit)是HDF驱动框架为开辟者提供的USB驱动程序开辟套件,包括USB Host DDK及USB Device DDK两部门,支持基于用户态开辟USB设备驱动的同时,还提供了丰富的USB驱动开辟本领,让广大开辟者能精准且高效的开辟USB驱动程序。
根本概念


运作机制

USB Host DDK

USB Host DDK为开辟者提供了主机端USB驱动开辟本领,按照功能分为三大类,分别是DDK初始化类、interface对象利用类及request对象利用类。
图1 USB Host驱动模型图


USB Device DDK

USB Device DDK向开辟者提供了设备端USB驱动开辟本领。比方,USB端口动态注册和去注册本领,开辟者可以基于本领实现USB端口的动态添加和组合;动态实例化本领,支持根据动态下发设备、配置、接口及端点描述符创建立备实例及传输通道;用户态的数据发送及接收本领,支持用户态下发送及接收数据;复合设备本领,支持一个物理设备上多个逻辑设备,实现多个逻辑设备间隔离,并支持不同逻辑设备同时被不同的应用历程访问。
图2 USB Device驱动模型图


开辟指导

由于内核态开辟USB驱动较复杂,需要开辟者对USB协议要有较深的了解才华很好的使用,对开辟者的要求相对较高。USB DDK的引入是为了让开辟者能在用户态更方便的开辟USB驱动。
场景介绍

USB Host DDK为开辟者提供了普通模式和专家模式,普通模式下,开辟者可通过USB DDK API直接完成相干USB数据读写利用,不需要过多关注底层的传输细节。专家模式下,开辟者通过USB RAW API直接访问OS平台中USB通道的接口,自界说实现更加复杂的功能。USB Device DDk为开辟者提供了管理USB设备、接口界说及USB数据哀求等功能。下文将介绍相干API。
接口说明

USB主机端驱动程序开辟相干接口(普通模式)如下
表1 USB主机端驱动程序开辟相干接口(普通模式)
接口名称功能描述int32_t UsbInitHostSdk(struct UsbSession **session);
USB主机端驱动开辟工具包初始化struct UsbInterface *UsbClaimInterface(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr, uint8_t interfaceIndex)获取USB接口对象UsbInterfaceHandle *UsbOpenInterface(const struct UsbInterface *interfaceObj);
打开USB对象接口int32_t UsbGetPipeInfo(const UsbInterfaceHandle *interfaceHandle, uint8_t settingIndex, uint8_t pipeId, struct UsbPipeInfo *pipeInfo);
获取指定可选设置的管道信息struct UsbRequest *UsbAllocRequest(const UsbInterfaceHandle *interfaceHandle, int32_t isoPackets , int32_t length);分配哀求对象int32_t UsbFillRequest(const struct UsbRequest *request, const UsbInterfaceHandle *interfaceHandle, const struct UsbRequestParams *params);
添补哀求int32_t UsbSubmitRequestSync(const struct UsbRequest *request);发送同步哀求 USB主机端驱动程序开辟相干接口(专家模式)如下
表2 USB主机端驱动程序开辟相干接口(专家模式)
接口名称功能描述int32_t UsbRawInit(struct UsbSession **session);
USB驱动开辟工具包专家模式初始化UsbRawHandle *UsbRawOpenDevice(const struct UsbSession *session, uint8_t busNum, uint8_t usbAddr);
打开USB设备对象int32_t UsbRawSendControlRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbControlRequestData *requestData);实行同步控制传输int32_t UsbRawSendBulkRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData);实行同步批量传输int32_t UsbRawSendInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRequestData *requestData);实行同步停止传输int32_t UsbRawGetConfigDescriptor(const UsbRawDevice *rawDev, uint8_t configIndex, struct UsbRawConfigDescriptor **config);
获取给定设备指定ID的设备配置描述符int32_t UsbRawFillInterruptRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);添补停止传输哀求所需信息int32_t UsbRawFillIsoRequest(const struct UsbRawRequest *request, const UsbRawHandle *devHandle, const struct UsbRawFillRequestData *fillData);添补同步传输(Isochronous Transfers)哀求所需信息int32_t UsbRawSubmitRequest(const struct UsbRawRequest *request);提交一个传输哀求int32_t UsbRawCancelRequest(const struct UsbRawRequest *request);取消一个传输哀求int32_t UsbRawHandleRequests(const UsbRawHandle *devHandle);传输哀求事件完成处理 USB设备端用于管理USB设备的相干接口如下
表3 USB设备端用于管理USB设备的相干接口
接口名称功能描述const struct UsbFnDevice *UsbFnCreateDevice(const char *udcName, const struct UsbFnDescriptorData *descriptor);创建USB设备int32_t UsbFnRemoveDevice(struct UsbFnDevice *fnDevice);删除USB设备const struct UsbFnDevice *UsbFnGetDevice(const char *udcName);获取USB设备 USB设备端用于USB接口界说的相干接口如下
表4 USB设备端用于USB接口界说的相干接口
接口名称功能描述int32_t UsbFnStartRecvInterfaceEvent(struct UsbFnInterface *interface, uint32_t eventMask, UsbFnEventCallback callback, void *context);开始接受Event事件int32_t UsbFnStopRecvInterfaceEvent(struct UsbFnInterface *interface);停止接受Event事件UsbFnInterfaceHandle UsbFnOpenInterface(struct UsbFnInterface *interface);打开一个接口int32_t UsbFnCloseInterface(UsbFnInterfaceHandle handle);关闭一个接口int32_t UsbFnGetInterfacePipeInfo(struct UsbFnInterface *interface, uint8_t pipeId, struct UsbFnPipeInfo *info);获取管道信息int32_t UsbFnSetInterfaceProp(const struct UsbFnInterface *interface, const char *name, const char *value);设置自界说属性 USB设备端用于管理USB数据哀求的相干接口如下
表5 USB设备端用于管理USB数据哀求的相干接口
接口名称功能描述struct UsbFnRequest *UsbFnAllocCtrlRequest(UsbFnInterfaceHandle handle, uint32_t len);申请一个控制哀求struct UsbFnRequest *UsbFnAllocRequest(UsbFnInterfaceHandle handle, uint8_t pipe, uint32_t len);申请一个数据哀求int32_t UsbFnFreeRequest(struct UsbFnRequest *req);开释一个哀求int32_t UsbFnSubmitRequestAsync(struct UsbFnRequest *req);发送异步哀求int32_t UsbFnSubmitRequestSync(struct UsbFnRequest *req, uint32_t timeout);发送同步哀求int32_t UsbFnCancelRequest(struct UsbFnRequest *req);取消哀求 开辟步骤

USB驱动基于HDF框架、Platform和OSAL基础接口进行开辟,不区分利用体系和芯片平台,为不同USB器件提供同一的驱动模型。此处以串口为例,分别介绍USB Host和USB Device驱动开辟的详细过程。
Host DDK API驱动开辟

Host RAW API驱动开辟

Device DDK API驱动开辟

开辟实例

本实例提供USB串口驱动开辟示例,并简要对具体关键点进行开辟说明。
Host DDK API驱动开辟

  1. #include "usb_serial.h"
  2. #include "hdf_base.h"
  3. #include "hdf_log.h"
  4. #include "hdf_usb_pnp_manage.h"
  5. #include "osal_mem.h"
  6. #include "osal_time.h"
  7. #include "securec.h"
  8. #include "usb_ddk_interface.h"
  9. #define HDF_LOG_TAG USB_HOST_ACM
  10. #define STR_LEN     512
  11. static struct UsbRequest *g_syncRequest = NULL;  // 定义一个USB请求
  12. static struct UsbRequest *g_ctrlCmdRequest = NULL;
  13. static bool g_acmReleaseFlag = false;
  14. static uint8_t *g_acmReadBuffer = NULL;
  15. ...
  16. static int32_t SerialCtrlMsg(struct AcmDevice *acm, uint8_t request, uint16_t value, void *buf, uint16_t len)
  17. {
  18.     int32_t ret;
  19.     if (acm == NULL || buf == NULL || acm->intPipe == NULL) {
  20.         HDF_LOGE("%s:invalid param", __func__);
  21.         return HDF_ERR_IO;
  22.     }
  23.     uint16_t index = acm->intPipe->interfaceId;
  24.     struct UsbControlParams controlParams = {};
  25.     struct UsbRequestParams parmas = {}; // 定义一个USB请求参数对象
  26.     if (acm->ctrlReq == NULL) {
  27.         // 为获取到的UsbInterfaceHandle预先分配待发送的IO Request对象
  28.         acm->ctrlReq = UsbAllocRequest(acm->ctrDevHandle, 0, len);
  29.         if (acm->ctrlReq == NULL) {
  30.             HDF_LOGE("%s: UsbAllocRequest failed", __func__);
  31.             return HDF_ERR_IO;
  32.         }
  33.     }
  34.     controlParams.request = request;
  35.     controlParams.target = USB_REQUEST_TARGET_INTERFACE; // 接口对象
  36.     controlParams.reqType = USB_REQUEST_TYPE_CLASS; // 请求类型
  37.     controlParams.directon = USB_REQUEST_DIR_TO_DEVICE; // 从主机到设备的数据传输
  38.     controlParams.value = value;
  39.     controlParams.index = index;
  40.     controlParams.data = buf;
  41.     controlParams.size = len;
  42.     parmas.interfaceId = USB_CTRL_INTERFACE_ID; // 定义USB控制接口的默认ID
  43.     if (acm->ctrPipe != NULL) {
  44.         parmas.pipeAddress = acm->ctrPipe->pipeAddress;
  45.         parmas.pipeId = acm->ctrPipe->pipeId;
  46.     }
  47.     parmas.requestType = USB_REQUEST_PARAMS_CTRL_TYPE; // 控制类型
  48.     parmas.timeout = USB_CTRL_SET_TIMEOUT; // 设置超时时间
  49.     parmas.ctrlReq = UsbControlSetUp(&controlParams);
  50.     parmas.callback = NULL;
  51.     // 根据params填充预先分配的IO Request
  52.     ret = UsbFillRequest(acm->ctrlReq, acm->ctrDevHandle, &parmas);
  53.     if (ret != HDF_SUCCESS) {
  54.         HDF_LOGE("%s: UsbFillRequest failed, ret = %d ", __func__, ret);
  55.         return ret;
  56.     }
  57.     // 发送同步IO Request
  58.     ret = UsbSubmitRequestSync(acm->ctrlReq);
  59.     if (ret != HDF_SUCCESS) {
  60.         HDF_LOGE("UsbSubmitRequestSync failed, ret = %d ", ret);
  61.         return ret;
  62.     }
  63.     if (!acm->ctrlReq->compInfo.status) {
  64.         HDF_LOGE("%s  status=%d ", __func__, acm->ctrlReq->compInfo.status);
  65.     }
  66.     return HDF_SUCCESS;
  67. }
  68. ...
  69. static struct UsbInterface *GetUsbInterfaceById(const struct AcmDevice *acm, uint8_t interfaceIndex)
  70. {
  71.     // 获取UsbInterface接口对象
  72.     return UsbClaimInterface(acm->session, acm->busNum, acm->devAddr, interfaceIndex);
  73. }
  74. ...
  75. static struct UsbPipeInfo *EnumePipe(
  76.     const struct AcmDevice *acm, uint8_t interfaceIndex, UsbPipeType pipeType, UsbPipeDirection pipeDirection)
  77. {
  78.     struct UsbInterfaceInfo *info = NULL; // 定义一个USB接口信息对象
  79.     UsbInterfaceHandle *interfaceHandle = NULL; // 定义一个USB接口操作句柄,就是void *类型
  80.     if (pipeType == USB_PIPE_TYPE_CONTROL) {
  81.         info = &acm->ctrIface->info;
  82.         interfaceHandle = acm->ctrDevHandle;
  83.     } else {
  84.         // 根据interfaceIndex获取设备句柄
  85.         info = &acm->iface[interfaceIndex]->info;
  86.         interfaceHandle = InterfaceIdToHandle(acm, info->interfaceIndex);
  87.     }
  88.     for (uint8_t i = 0; i <= info->pipeNum; i++) {
  89.         struct UsbPipeInfo p;
  90.         // 获取指定索引为i的pipeInfo信息
  91.         int32_t ret = UsbGetPipeInfo(interfaceHandle, info->curAltSetting, i, &p);
  92.         if (ret < 0) {
  93.             continue;
  94.         }
  95.         if ((p.pipeDirection == pipeDirection) && (p.pipeType == pipeType)) {
  96.             struct UsbPipeInfo *pi = OsalMemCalloc(sizeof(*pi)); // 开辟内存并初始化
  97.             if (pi == NULL) {
  98.                 HDF_LOGE("%s: Alloc pipe failed", __func__);
  99.                 return NULL;
  100.             }
  101.             p.interfaceId = info->interfaceIndex;
  102.             *pi = p;
  103.             return pi;
  104.         }
  105.     }
  106.     return NULL;
  107. }
  108. static struct UsbPipeInfo *GetPipe(const struct AcmDevice *acm, UsbPipeType pipeType, UsbPipeDirection pipeDirection)
  109. {
  110.     uint8_t i;
  111.     if (acm == NULL) {
  112.         HDF_LOGE("%s: invalid param", __func__);
  113.         return NULL;
  114.     }
  115.     for (i = 0; i < acm->interfaceCnt; i++) {
  116.         struct UsbPipeInfo *p = NULL;
  117.         if (!acm->iface[i]) {
  118.             continue;
  119.         }
  120.         // 获取控制pipe的pipeInfo信息
  121.         p = EnumePipe(acm, i, pipeType, pipeDirection);
  122.         if (p == NULL) {
  123.             continue;
  124.         }
  125.         return p;
  126.     }
  127.     return NULL;
  128. }
  129. /* HdfDriverEntry implementations */
  130. static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device)
  131. {
  132.     struct UsbPnpNotifyServiceInfo *info = NULL;
  133.     errno_t err;
  134.     struct AcmDevice *acm = NULL;
  135.     if (device == NULL) {
  136.         HDF_LOGE("%s: device is null", __func__);
  137.         return HDF_ERR_INVALID_OBJECT;
  138.     }
  139.     //开辟内存空间
  140.     acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
  141.     if (acm == NULL) {
  142.         HDF_LOGE("%s: Alloc usb serial device failed", __func__);
  143.         return HDF_FAILURE;
  144.     }
  145.     // 初始化互斥锁,&acm->lock表示指向互斥量的指针
  146.     if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
  147.         HDF_LOGE("%s:%d OsalMutexInit failed", __func__, __LINE__);
  148.         goto ERROR;
  149.     }
  150.     info = (struct UsbPnpNotifyServiceInfo *)device->priv;
  151.     if (info != NULL) {
  152.         HDF_LOGD("%s:%d busNum=%d,devAddr=%d,interfaceLength=%d", __func__, __LINE__, info->busNum, info->devNum,
  153.             info->interfaceLength);
  154.         acm->busNum = (uint8_t)info->busNum;
  155.         acm->devAddr = (uint8_t)info->devNum;
  156.         acm->interfaceCnt = info->interfaceLength;
  157.         err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber,
  158.             info->interfaceLength);
  159.         if (err != EOK) {
  160.             HDF_LOGE("%s:%d memcpy_s failed err = %d", __func__, __LINE__, err);
  161.             goto LOCK_ERROR;
  162.         }
  163.     } else {
  164.         HDF_LOGE("%s:%d info is null!", __func__, __LINE__);
  165.         goto LOCK_ERROR;
  166.     }
  167.     acm->device = device;
  168.     device->service = &(acm->service);
  169.     acm->device->service->Dispatch = UsbSerialDeviceDispatch;
  170.     HDF_LOGD("UsbSerialDriverBind=========================OK");
  171.     return HDF_SUCCESS;
  172. LOCK_ERROR:
  173.     if (OsalMutexDestroy(&acm->lock)) {
  174.         HDF_LOGE("%s:%d OsalMutexDestroy failed", __func__, __LINE__);
  175.     }
  176. ERROR:
  177.     OsalMemFree(acm);
  178.     acm = NULL;
  179.     return HDF_FAILURE;
  180. }
  181. ...
  182. static int32_t AcmAllocReadRequests(struct AcmDevice *acm)
  183. {
  184.     int32_t ret;
  185.     struct UsbRequestParams readParmas = {};
  186.     for (int32_t i = 0; i < ACM_NR; i++) {
  187.         // 分配待发送的readReq IO Request对象
  188.         acm->readReq[i] = UsbAllocRequest(InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), 0, acm->readSize);
  189.         if (!acm->readReq[i]) {
  190.             HDF_LOGE("readReq request failed\n");
  191.             goto ERROR;
  192.         }
  193.         readParmas.userData = (void *)acm;
  194.         readParmas.pipeAddress = acm->dataInPipe->pipeAddress;
  195.         readParmas.pipeId = acm->dataInPipe->pipeId;
  196.         readParmas.interfaceId = acm->dataInPipe->interfaceId;
  197.         readParmas.callback = AcmReadBulk;
  198.         readParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE; /* Data type */
  199.         readParmas.timeout = USB_CTRL_SET_TIMEOUT;
  200.         readParmas.dataReq.numIsoPackets = 0;
  201.         readParmas.dataReq.directon = (((uint8_t)acm->dataInPipe->pipeDirection) >> USB_PIPE_DIR_OFFSET) & 0x1;
  202.         readParmas.dataReq.length = (int)acm->readSize;
  203.         // 根据readParams填充预先分配待发送的readReq IO Request对象
  204.         ret = UsbFillRequest(acm->readReq[i], InterfaceIdToHandle(acm, acm->dataInPipe->interfaceId), &readParmas);
  205.         if (ret != HDF_SUCCESS) {
  206.             HDF_LOGE("%s: UsbFillRequest failed, ret=%d \n", __func__, ret);
  207.             goto ERROR;
  208.         }
  209.     }
  210.     return HDF_SUCCESS;
  211. ERROR:
  212.     AcmFreeReadRequests(acm);
  213.     return HDF_ERR_MALLOC_FAIL;
  214. }
  215. static int32_t AcmAllocNotifyRequest(struct AcmDevice *acm)
  216. {
  217.     int32_t ret;
  218.     struct UsbRequestParams intParmas = {};
  219.     // 分配待发送的中断IO Request对象
  220.     acm->notifyReq = UsbAllocRequest(InterfaceIdToHandle(acm, acm->intPipe->interfaceId), 0, acm->intSize);
  221.     if (!acm->notifyReq) {
  222.         HDF_LOGE("notifyReq request failed.\n");
  223.         return HDF_ERR_MALLOC_FAIL;
  224.     }
  225.     intParmas.userData = (void *)acm;
  226.     intParmas.pipeAddress = acm->intPipe->pipeAddress;
  227.     intParmas.pipeId = acm->intPipe->pipeId;
  228.     intParmas.interfaceId = acm->intPipe->interfaceId;
  229.     intParmas.callback = AcmCtrlIrq;
  230.     intParmas.requestType = USB_REQUEST_PARAMS_DATA_TYPE;
  231.     intParmas.timeout = USB_CTRL_SET_TIMEOUT;
  232.     intParmas.dataReq.numIsoPackets = 0;
  233.     intParmas.dataReq.directon = (((uint8_t)acm->intPipe->pipeDirection) >> USB_PIPE_DIR_OFFSET) & DIRECTION_MASK;
  234.     intParmas.dataReq.length = (int)acm->intSize;
  235.     // 填充预先分配的中断IO Request
  236.     ret = UsbFillRequest(acm->notifyReq, InterfaceIdToHandle(acm, acm->intPipe->interfaceId), &intParmas);
  237.     if (ret != HDF_SUCCESS) {
  238.         HDF_LOGE("%s: UsbFillRequest failed, ret = %d", __func__, ret);
  239.         goto ERROR;
  240.     }
  241.     return HDF_SUCCESS;
  242. ERROR:
  243.     AcmFreeNotifyReqeust(acm);
  244.     return ret;
  245. }
  246. static void AcmReleaseInterfaces(struct AcmDevice *acm)
  247. {
  248.     for (uint8_t i = 0; i < acm->interfaceCnt; i++) {
  249.         if (acm->iface[i]) {
  250.             // 释放一个USB接口对象
  251.             UsbReleaseInterface(acm->iface[i]);
  252.             acm->iface[i] = NULL;
  253.         }
  254.     }
  255.     if (acm->ctrIface) {
  256.         UsbReleaseInterface(acm->ctrIface);
  257.         acm->ctrIface = NULL;
  258.     }
  259. }
  260. static int32_t AcmClaimInterfaces(struct AcmDevice *acm)
  261. {
  262.     for (uint8_t i = 0; i < acm->interfaceCnt; i++) {
  263.         // 获取UsbInterface接口对象
  264.         acm->iface[i] = GetUsbInterfaceById((const struct AcmDevice *)acm, acm->interfaceIndex[i]);
  265.         if (acm->iface[i] == NULL) {
  266.             HDF_LOGE("%s: interface%d is null", __func__, acm->interfaceIndex[i]);
  267.             goto ERROR;
  268.         }
  269.     }
  270.         // 获取控制接口对应的UsbInterface接口对象
  271.     acm->ctrIface = GetUsbInterfaceById((const struct AcmDevice *)acm, USB_CTRL_INTERFACE_ID);
  272.     if (acm->ctrIface == NULL) {
  273.         HDF_LOGE("%s: GetUsbInterfaceById null", __func__);
  274.         goto ERROR;
  275.     }
  276.     return HDF_SUCCESS;
  277. ERROR:
  278.     // 根据acm->interfaceCnt循环释放接口对象
  279.     AcmReleaseInterfaces(acm);
  280.     return HDF_FAILURE;
  281. }
  282. static void AcmCloseInterfaces(struct AcmDevice *acm)
  283. {
  284.     for (uint8_t i = 0; i < acm->interfaceCnt; i++) {
  285.         if (acm->devHandle[i]) {
  286.             // 关闭一个USB设备对象
  287.             UsbCloseInterface(acm->devHandle[i]);
  288.             acm->devHandle[i] = NULL;
  289.         }
  290.     }
  291.     if (acm->ctrDevHandle) {
  292.         UsbCloseInterface(acm->ctrDevHandle);
  293.         acm->ctrDevHandle = NULL;
  294.     }
  295. }
  296. static int32_t AcmOpenInterfaces(struct AcmDevice *acm)
  297. {
  298.     for (uint8_t i = 0; i < acm->interfaceCnt; i++) {
  299.         if (acm->iface[i]) {
  300.             // 打开获取到的UsbInterface接口对象
  301.             acm->devHandle[i] = UsbOpenInterface(acm->iface[i]);
  302.             if (acm->devHandle[i] == NULL) {
  303.                 HDF_LOGE("%s: UsbOpenInterface null", __func__);
  304.                 goto ERROR;
  305.             }
  306.         }
  307.     }
  308.     acm->ctrDevHandle = UsbOpenInterface(acm->ctrIface);
  309.     if (acm->ctrDevHandle == NULL) {
  310.         HDF_LOGE("%s: ctrDevHandle UsbOpenInterface null", __func__);
  311.         goto ERROR;
  312.     }
  313.     return HDF_SUCCESS;
  314. ERROR:
  315.     // 关闭所有UsbInterface接口对象
  316.     AcmCloseInterfaces(acm);
  317.     return HDF_FAILURE;
  318. }
  319. static int32_t AcmGetPipes(struct AcmDevice *acm)
  320. {
  321.     // 获取dataInPipe的pipeInfo信息
  322.     acm->dataInPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_IN);
  323.     if (acm->dataInPipe == NULL) {
  324.         HDF_LOGE("dataInPipe is null");
  325.         goto ERROR;
  326.     }
  327.         // 获取dataOutPipe的pipeInfo信息
  328.     acm->dataOutPipe = GetPipe(acm, USB_PIPE_TYPE_BULK, USB_PIPE_DIRECTION_OUT);
  329.     if (acm->dataOutPipe == NULL) {
  330.         HDF_LOGE("dataOutPipe is null");
  331.         goto ERROR;
  332.     }
  333.         // 获取控制pipe的pipeInfo信息
  334.     acm->ctrPipe = EnumePipe(acm, acm->ctrIface->info.interfaceIndex, USB_PIPE_TYPE_CONTROL, USB_PIPE_DIRECTION_OUT);
  335.     if (acm->ctrPipe == NULL) {
  336.         HDF_LOGE("ctrPipe is null");
  337.         goto ERROR;
  338.     }
  339.     // 获取中断pipe的pipeInfo信息
  340.     acm->intPipe = GetPipe(acm, USB_PIPE_TYPE_INTERRUPT, USB_PIPE_DIRECTION_IN);
  341.     if (acm->intPipe == NULL) {
  342.         HDF_LOGE("intPipe is null");
  343.         goto ERROR;
  344.     }
  345.     acm->readSize = acm->dataInPipe->maxPacketSize;
  346.     acm->writeSize = acm->dataOutPipe->maxPacketSize;
  347.     acm->ctrlSize = acm->ctrPipe->maxPacketSize;
  348.     acm->intSize = acm->intPipe->maxPacketSize;
  349.     return HDF_SUCCESS;
  350. ERROR:
  351.     // 释放设备中所有的管道信息
  352.     AcmFreePipes(acm);
  353.     return HDF_FAILURE;
  354. }
  355. static void AcmFreeRequests(struct AcmDevice *acm)
  356. {
  357.     if (g_syncRequest != NULL) {
  358.         UsbFreeRequest(g_syncRequest);
  359.         g_syncRequest = NULL;
  360.     }
  361.     AcmFreeReadRequests(acm);
  362.     AcmFreeNotifyReqeust(acm);
  363.     AcmFreeWriteRequests(acm);
  364.     AcmWriteBufFree(acm);
  365. }
  366. static int32_t AcmAllocRequests(const struct AcmDevice *acm)
  367. {
  368.     int32_t ret;
  369.     if (AcmWriteBufAlloc(acm) < 0) {
  370.         HDF_LOGE("%s: AcmWriteBufAlloc failed", __func__);
  371.         return HDF_ERR_MALLOC_FAIL;
  372.     }
  373.     for (int32_t i = 0; i < ACM_NW; i++) {
  374.         struct AcmWb *snd = (struct AcmWb *)&(acm->wb[i]);
  375.         // 分配待发送的IO Request对象
  376.         snd->request = UsbAllocRequest(
  377.             InterfaceIdToHandle((struct AcmDevice *)acm, acm->dataOutPipe->interfaceId), 0, acm->writeSize);
  378.         snd->instance = (struct AcmDevice *)acm;
  379.         if (snd->request == NULL) {
  380.             HDF_LOGE("%s:%d snd request fail", __func__, __LINE__);
  381.             goto ERROR_ALLOC_WRITE_REQ;
  382.         }
  383.     }
  384.     ret = AcmAllocNotifyRequest((struct AcmDevice *)acm); // 分配并填充中断IO Request对象
  385.     if (ret != HDF_SUCCESS) {
  386.         HDF_LOGE("%s:%d AcmAllocNotifyRequest fail", __func__, __LINE__);
  387.         goto ERROR_ALLOC_INT_REQ;
  388.     }
  389.     ret = AcmAllocReadRequests((struct AcmDevice *)acm); // 分配并填充readReq IO Request对象
  390.     if (ret) {
  391.         HDF_LOGE("%s:%d AcmAllocReadRequests fail", __func__, __LINE__);
  392.         goto ERROR_ALLOC_READ_REQ;
  393.     }
  394.     return HDF_SUCCESS;
  395. ERROR_ALLOC_READ_REQ:
  396.     AcmFreeNotifyReqeust((struct AcmDevice *)acm);
  397. ERROR_ALLOC_INT_REQ:
  398.     AcmFreeWriteRequests((struct AcmDevice *)acm);
  399. ERROR_ALLOC_WRITE_REQ:
  400.     AcmWriteBufFree((struct AcmDevice *)acm);
  401.     return HDF_FAILURE;
  402. }
  403. static int32_t AcmInit(struct AcmDevice *acm)
  404. {
  405.     int32_t ret;
  406.     if (acm->initFlag) {
  407.         HDF_LOGE("%{public}s: initFlag is true", __func__);
  408.         return HDF_SUCCESS;
  409.     }
  410.         // 初始化Host DDK
  411.     ret = UsbInitHostSdk(NULL);
  412.     if (ret != HDF_SUCCESS) {
  413.         HDF_LOGE("%{public}s: UsbInitHostSdk failed", __func__);
  414.         return HDF_ERR_IO;
  415.     }
  416.     acm->session = NULL;
  417.         // 根据acm->interfaceIndex[i]分别获取UsbInterface接口对象
  418.     ret = AcmClaimInterfaces(acm);
  419.     if (ret != HDF_SUCCESS) {
  420.         HDF_LOGE("%{public}s: AcmClaimInterfaces failed", __func__);
  421.         goto ERROR_CLAIM_INTERFACES;
  422.     }
  423.     // 根据acm->iface[i]分别打开UsbInterface接口对象
  424.     ret = AcmOpenInterfaces(acm);
  425.     if (ret != HDF_SUCCESS) {
  426.         HDF_LOGE("%{public}s: AcmOpenInterfaces failed", __func__);
  427.         goto ERROR_OPEN_INTERFACES;
  428.     }
  429.     // 获取管道信息的指针
  430.     ret = AcmGetPipes(acm);
  431.     if (ret != HDF_SUCCESS) {
  432.         HDF_LOGE("%{public}s: AcmGetPipes failed", __func__);
  433.         goto ERROR_GET_PIPES;
  434.     }
  435.     ret = AcmAllocRequests(acm);
  436.     if (ret != HDF_SUCCESS) {
  437.         HDF_LOGE("%{public}s: AcmAllocRequests failed", __func__);
  438.         goto ERROR_ALLOC_REQS;
  439.     }
  440.     acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE);
  441.     acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
  442.     acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
  443.     acm->lineCoding.bDataBits = DATA_BITS_LENGTH;
  444.     acm->initFlag = true;
  445.     return HDF_SUCCESS;
  446. ERROR_ALLOC_REQS:
  447.     AcmFreePipes(acm);
  448. ERROR_GET_PIPES:
  449.     // 关闭所有UsbInterface接口对象
  450.     AcmCloseInterfaces(acm);
  451. ERROR_OPEN_INTERFACES:
  452.     // 释放所有UsbInterface接口对象
  453.     AcmReleaseInterfaces(acm);
  454. ERROR_CLAIM_INTERFACES:
  455.     // 在主机端退出USB DDK,acm->session代表指向会话上下文的指针
  456.     UsbExitHostSdk(acm->session);
  457.     acm->session = NULL;
  458.     return ret;
  459. }
  460. static void AcmRelease(struct AcmDevice *acm)
  461. {
  462.     if (!(acm->initFlag)) {
  463.         HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
  464.         return;
  465.     }
  466.     AcmCloseInterfaces(acm);
  467.     AcmReleaseInterfaces(acm);
  468.     AcmFreeRequests(acm);
  469.     AcmFreePipes(acm);
  470.     // 在主机端退出USB DDK
  471.     UsbExitHostSdk(acm->session);
  472.     acm->session = NULL;
  473.     acm->initFlag = false;
  474. }
  475. static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device)
  476. {
  477.     int32_t ret;
  478.     struct AcmDevice *acm = NULL;
  479.     if (device == NULL) {
  480.         HDF_LOGE("%s: device is null", __func__);
  481.         return HDF_ERR_INVALID_OBJECT;
  482.     }
  483.     acm = (struct AcmDevice *)device->service;
  484.     // 初始化互斥锁,&acm->readLock表示指向互斥量的指针
  485.     if (acm == NULL) {
  486.         return HDF_ERR_INVALID_OBJECT;
  487.     }
  488.     OsalMutexInit(&acm->readLock);
  489.     OsalMutexInit(&acm->writeLock);
  490.     HDF_LOGD("%s:%d busNum = %d,devAddr = %d", __func__, __LINE__, acm->busNum, acm->devAddr);
  491.     // 给USB串口设备信息开辟空间并赋值
  492.     ret = UsbSerialDeviceAlloc(acm);
  493.     if (ret != HDF_SUCCESS) {
  494.         HDF_LOGE("%s: Serial Device alloc failed", __func__);
  495.     }
  496.     acm->initFlag = false;
  497.     g_acmReleaseFlag = false;
  498.     HDF_LOGD("%s:%d init ok!", __func__, __LINE__);
  499.     return ret;
  500. }
  501. static void UsbSerialDriverRelease(struct HdfDeviceObject *device)
  502. {
  503.     struct AcmDevice *acm = NULL;
  504.     if (device == NULL) {
  505.         HDF_LOGE("%s: device is null", __func__);
  506.         return;
  507.     }
  508.     acm = (struct AcmDevice *)device->service;
  509.     if (acm == NULL) {
  510.         HDF_LOGE("%s: acm is null", __func__);
  511.         return;
  512.     }
  513.     g_acmReleaseFlag = true;
  514.     if (acm->initFlag) {
  515.         HDF_LOGE("%s:%d AcmRelease", __func__, __LINE__);
  516.         AcmRelease(acm);
  517.     }
  518.     // 释放usb串口设备信息
  519.     UsbSeriaDevicelFree(acm);
  520.     // 释放互斥锁
  521.     OsalMutexDestroy(&acm->writeLock);
  522.     OsalMutexDestroy(&acm->readLock);
  523.     OsalMutexDestroy(&acm->lock);
  524.     OsalMemFree(acm);
  525.     acm = NULL;
  526.     HDF_LOGD("%s:%d exit", __func__, __LINE__);
  527. }
  528. // 驱动的Bind、Init、及Release操作
  529. struct HdfDriverEntry g_usbSerialDriverEntry = {
  530.     .moduleVersion = 1,
  531.     .moduleName = "usbhost_acm", // 驱动模块名称,必须与hcs文件中配置的名称一致
  532.     .Bind = UsbSerialDriverBind,
  533.     .Init = UsbSerialDriverInit,
  534.     .Release = UsbSerialDriverRelease,
  535. };
  536. HDF_INIT(g_usbSerialDriverEntry); // 驱动入口
复制代码
Host RAW API驱动开辟

  1. root {
  2.     module = "usb_pnp_device";
  3.     usb_pnp_config {
  4.         match_attr = "usb_pnp_match";
  5.         usb_pnp_device_id = "UsbPnpDeviceId";
  6.         UsbPnpDeviceId {
  7.             idTableList = [
  8.                 "host_acm_rawapi_table"
  9.             ];
  10.             host_acm_rawapi_table {    // 驱动配置匹配表信息
  11.                 // 驱动模块名,该字段的值必须和驱动入口结构的moduleName一致
  12.                 moduleName = "usbhost_acm_rawapi";
  13.                 // 驱动对外发布服务的名称,必须唯一
  14.                 serviceName = "usbhost_acm_rawapi_service";
  15.                 // 驱动私有数据匹配关键字
  16.                 deviceMatchAttr = "usbhost_acm_rawapi_matchAttr";
  17.                 // 从该字段开始(包含该字段)之后数据长度,以byte为单位
  18.                 length = 21;
  19.                 // USB驱动匹配规则vendorId+productId+interfaceSubClass+interfaceProtocol+interfaceNumber
  20.                 matchFlag = 0x0303;
  21.                 // 厂商编号
  22.                 vendorId = 0x12D1;
  23.                 // 产品编号
  24.                 productId = 0x5000;
  25.                 // 设备出厂编号,低16位
  26.                 bcdDeviceLow = 0x0000;
  27.                 // 设备出厂编号,高16位
  28.                 bcdDeviceHigh = 0x0000;
  29.                 // USB分配的设备类代码
  30.                 deviceClass = 0;
  31.                 // USB分配的子类代码
  32.                 deviceSubClass = 0;
  33.                 // USB分配的设备协议代码
  34.                 deviceProtocol = 0;
  35.                 // 接口类型,根据实际需要可填写多个
  36.                 interfaceClass = [0];
  37.                 // 接口子类型,根据实际需要可填写多个
  38.                 interfaceSubClass = [2, 0];
  39.                 // 接口所遵循的协议,根据实际需要可填写多个
  40.                 interfaceProtocol = [1, 2];
  41.                 // 接口的编号,根据实际需要可填写多个
  42.                 interfaceNumber = [2, 3];
  43.             }
  44.         }
  45.     }
  46. }
复制代码
  1. #include <unistd.h>
  2. #include "hdf_base.h"
  3. #include "hdf_log.h"
  4. #include "hdf_usb_pnp_manage.h"
  5. #include "osal_mem.h"
  6. #include "osal_time.h"
  7. #include "securec.h"
  8. #include "usb_serial_rawapi.h"
  9. #define HDF_LOG_TAG                   USB_HOST_ACM_RAW_API
  10. #define USB_CTRL_REQ_SIZE             64
  11. #define USB_IO_THREAD_STACK_SIZE      8192
  12. #define USB_RAW_IO_SLEEP_MS_TIME      100
  13. #define USB_RAW_IO_STOP_WAIT_MAX_TIME 3
  14. static struct UsbRawRequest *g_syncRequest = NULL;
  15. static UsbRawIoProcessStatusType g_stopIoStatus = USB_RAW_IO_PROCESS_RUNNING;
  16. struct OsalMutex g_stopIoLock;
  17. static bool g_rawAcmReleaseFlag = false;
  18. ...
  19. static int32_t UsbGetConfigDescriptor(UsbRawHandle *devHandle, struct UsbRawConfigDescriptor **config)
  20. {
  21.     UsbRawDevice *dev = NULL;
  22.     int32_t activeConfig;
  23.     int32_t ret;
  24.     if (devHandle == NULL) {
  25.         HDF_LOGE("%s:%d devHandle is null", __func__, __LINE__);
  26.         return HDF_ERR_INVALID_PARAM;
  27.     }
  28.     // 获取主用设备配置
  29.     ret = UsbRawGetConfiguration(devHandle, &activeConfig);
  30.     if (ret) {
  31.         HDF_LOGE("%s:%d UsbRawGetConfiguration failed, ret = %d", __func__, __LINE__, ret);
  32.         return HDF_FAILURE;
  33.     }
  34.     HDF_LOGE("%s:%d activeConfig = %d", __func__, __LINE__, activeConfig);
  35.     // 根据指定的设备句柄获取设备指针
  36.     dev = UsbRawGetDevice(devHandle);
  37.     if (dev == NULL) {
  38.         HDF_LOGE("%s:%d UsbRawGetDevice failed", __func__, __LINE__);
  39.         return HDF_FAILURE;
  40.     }
  41.     // 根据指定的设备ID获取设备配置描述符
  42.     ret = UsbRawGetConfigDescriptor(dev, activeConfig, config);
  43.     if (ret) {
  44.         HDF_LOGE("UsbRawGetConfigDescriptor failed, ret = %d\n", ret);
  45.         return HDF_FAILURE;
  46.     }
  47.     return HDF_SUCCESS;
  48. }
  49. ...
  50.     static int32_t UsbAllocWriteRequests(struct AcmDevice *acm)
  51. {
  52.     int32_t i;
  53.     for (i = 0; i < ACM_NW; i++) {
  54.         struct AcmWb *snd = &acm->wb[i];
  55.         // 分配一个具有指定数目的同步传输分组描述符的传输请求
  56.         snd->request = UsbRawAllocRequest(acm->devHandle, 0, acm->dataOutEp->maxPacketSize);
  57.         snd->instance = acm;
  58.         if (snd->request == NULL) {
  59.             HDF_LOGE("%s: UsbRawAllocRequest failed", __func__);
  60.             return HDF_ERR_MALLOC_FAIL;
  61.         }
  62.     }
  63.     return HDF_SUCCESS;
  64. }
  65. ...
  66. /* HdfDriverEntry implementations */
  67. static int32_t UsbSerialDriverBind(struct HdfDeviceObject *device)
  68. {
  69.     struct AcmDevice *acm = NULL;
  70.     struct UsbPnpNotifyServiceInfo *info = NULL;
  71.     errno_t err;
  72.     if (device == NULL) {
  73.         HDF_LOGE("%s: device is null", __func__);
  74.         return HDF_ERR_INVALID_OBJECT;
  75.     }
  76.     acm = (struct AcmDevice *)OsalMemCalloc(sizeof(*acm));
  77.     if (acm == NULL) {
  78.         HDF_LOGE("%s: Alloc usb serial device failed", __func__);
  79.         return HDF_FAILURE;
  80.     }
  81.     if (OsalMutexInit(&acm->lock) != HDF_SUCCESS) {
  82.         HDF_LOGE("%s:%d OsalMutexInit fail", __func__, __LINE__);
  83.         goto ERROR;
  84.     }
  85.     info = (struct UsbPnpNotifyServiceInfo *)device->priv;
  86.     if (info != NULL) {
  87.         acm->busNum = (uint8_t)info->busNum;
  88.         acm->devAddr = (uint8_t)info->devNum;
  89.         acm->interfaceCnt = info->interfaceLength;
  90.         err = memcpy_s((void *)(acm->interfaceIndex), USB_MAX_INTERFACES, (const void *)info->interfaceNumber,
  91.             info->interfaceLength);
  92.         if (err != EOK) {
  93.             HDF_LOGE("%s:%d memcpy_s failed err=%d", __func__, __LINE__, err);
  94.             goto LOCK_ERROR;
  95.         }
  96.     } else {
  97.         HDF_LOGE("%s:%d info is NULL!", __func__, __LINE__);
  98.         goto LOCK_ERROR;
  99.     }
  100.     device->service = &(acm->service);
  101.     device->service->Dispatch = UsbSerialDeviceDispatch;
  102.     acm->device = device;
  103.     HDF_LOGD("UsbSerialDriverBind=========================OK");
  104.     return HDF_SUCCESS;
  105. LOCK_ERROR:
  106.     if (OsalMutexDestroy(&acm->lock)) {
  107.         HDF_LOGE("%s:%d OsalMutexDestroy fail", __func__, __LINE__);
  108.     }
  109. ERROR:
  110.     OsalMemFree(acm);
  111.     acm = NULL;
  112.     return HDF_FAILURE;
  113. }
  114. ...
  115. static int32_t UsbAllocReadRequests(struct AcmDevice *acm)
  116. {
  117.     struct UsbRawFillRequestData reqData;
  118.     uint32_t size = acm->dataInEp->maxPacketSize;
  119.     for (int32_t i = 0; i < ACM_NR; i++) {
  120.         // 分配一个具有指定数目的同步传输分组描述符的传输请求
  121.         acm->readReq[i] = UsbRawAllocRequest(acm->devHandle, 0, size);
  122.         if (!acm->readReq[i]) {
  123.             HDF_LOGE("readReq request failed\n");
  124.             return HDF_ERR_MALLOC_FAIL;
  125.         }
  126.         reqData.endPoint = acm->dataInEp->addr;
  127.         reqData.numIsoPackets = 0;
  128.         reqData.callback = AcmReadBulkCallback;
  129.         reqData.userData = (void *)acm;
  130.         reqData.timeout = USB_CTRL_SET_TIMEOUT;
  131.         reqData.length = size;
  132.         // 在批量传输请求中填写所需信息
  133.         int32_t ret = UsbRawFillBulkRequest(acm->readReq[i], acm->devHandle, &reqData);
  134.         if (ret != HDF_SUCCESS) {
  135.             HDF_LOGE("%s: FillBulkRequest failed, ret=%d\n", __func__, ret);
  136.             return HDF_FAILURE;
  137.         }
  138.     }
  139.     return HDF_SUCCESS;
  140. }
  141. ...
  142. static int32_t UsbAllocNotifyRequest(struct AcmDevice *acm)
  143. {
  144.     struct UsbRawFillRequestData fillRequestData;
  145.     uint32_t size = acm->notifyEp->maxPacketSize;
  146.     int32_t ret;
  147.     // 分配一个具有指定数目的同步传输分组描述符的传输请求
  148.     acm->notifyReq = UsbRawAllocRequest(acm->devHandle, 0, size);
  149.     if (!acm->notifyReq) {
  150.         HDF_LOGE("notifyReq request fail\n");
  151.         return HDF_ERR_MALLOC_FAIL;
  152.     }
  153.     fillRequestData.endPoint = acm->notifyEp->addr;
  154.     fillRequestData.length = size;
  155.     fillRequestData.numIsoPackets = 0;
  156.     fillRequestData.callback = AcmNotifyReqCallback;
  157.     fillRequestData.userData = (void *)acm;
  158.     fillRequestData.timeout = USB_CTRL_SET_TIMEOUT;
  159.     // 在中断传输请求中填充所需的信息
  160.     ret = UsbRawFillInterruptRequest(acm->notifyReq, acm->devHandle, &fillRequestData);
  161.     if (ret) {
  162.         HDF_LOGE("%s: FillInterruptRequest failed, ret=%d", __func__, ret);
  163.         return HDF_FAILURE;
  164.     }
  165.     return HDF_SUCCESS;
  166. }
  167. ...
  168. static int32_t UsbSerialInit(struct AcmDevice *acm)
  169. {
  170.     struct UsbSession *session = NULL;
  171.     UsbRawHandle *devHandle = NULL;
  172.     int32_t ret;
  173.     if (acm->initFlag) {
  174.         HDF_LOGE("%s:%d: initFlag is true", __func__, __LINE__);
  175.         return HDF_SUCCESS;
  176.     }
  177.     // 以专家模式初始化USB DDK
  178.     ret = UsbRawInit(NULL);
  179.     if (ret) {
  180.         HDF_LOGE("%s:%d UsbRawInit failed", __func__, __LINE__);
  181.         return HDF_ERR_IO;
  182.     }
  183.     acm->session = session;
  184.     // 打开一个USB设备对象
  185.     devHandle = UsbRawOpenDevice(session, acm->busNum, acm->devAddr);
  186.     if (devHandle == NULL) {
  187.         HDF_LOGE("%s:%d UsbRawOpenDevice failed", __func__, __LINE__);
  188.         ret = HDF_FAILURE;
  189.         goto ERR_OPEN_DEVICE;
  190.     }
  191.     acm->devHandle = devHandle;
  192.     // 获取主用设备配置、设备指针及配置描述符
  193.     ret = UsbGetConfigDescriptor(devHandle, &acm->config);
  194.     if (ret) {
  195.         HDF_LOGE("%s:%d UsbGetConfigDescriptor failed", __func__, __LINE__);
  196.         ret = HDF_FAILURE;
  197.         goto ERR_GET_DESC;
  198.     }
  199.     ret = UsbParseConfigDescriptor(acm, acm->config);
  200.     if (ret != HDF_SUCCESS) {
  201.         HDF_LOGE("%s:%d UsbParseConfigDescriptor failed", __func__, __LINE__);
  202.         ret = HDF_FAILURE;
  203.         goto ERR_PARSE_DESC;
  204.     }
  205.     ret = AcmWriteBufAlloc(acm);
  206.     if (ret < 0) {
  207.         HDF_LOGE("%s:%d AcmWriteBufAlloc failed", __func__, __LINE__);
  208.         ret = HDF_FAILURE;
  209.         goto ERR_ALLOC_WRITE_BUF;
  210.     }
  211.     ret = UsbAllocWriteRequests(acm);
  212.     if (ret < 0) {
  213.         HDF_LOGE("%s:%d UsbAllocWriteRequests failed", __func__, __LINE__);
  214.         ret = HDF_FAILURE;
  215.         goto ERR_ALLOC_WRITE_REQS;
  216.     }
  217.     ret = UsbAllocNotifyRequest(acm);
  218.     if (ret) {
  219.         HDF_LOGE("%s:%d UsbAllocNotifyRequests failed", __func__, __LINE__);
  220.         goto ERR_ALLOC_NOTIFY_REQ;
  221.     }
  222.     ret = UsbAllocReadRequests(acm);
  223.     if (ret) {
  224.         HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
  225.         goto ERR_ALLOC_READ_REQS;
  226.     }
  227.     ret = UsbStartIo(acm);
  228.     if (ret) {
  229.         HDF_LOGE("%s:%d UsbAllocReadRequests failed", __func__, __LINE__);
  230.         goto ERR_START_IO;
  231.     }
  232.     acm->lineCoding.dwDTERate = CPU_TO_LE32(DATARATE);
  233.     acm->lineCoding.bCharFormat = USB_CDC_1_STOP_BITS;
  234.     acm->lineCoding.bParityType = USB_CDC_NO_PARITY;
  235.     acm->lineCoding.bDataBits = DATA_BITS_LENGTH;
  236.     ret = UsbRawSubmitRequest(acm->notifyReq);
  237.     if (ret) {
  238.         HDF_LOGE("%s:%d UsbRawSubmitRequest failed", __func__, __LINE__);
  239.         goto ERR_SUBMIT_REQ;
  240.     }
  241.     acm->initFlag = true;
  242.     HDF_LOGD("%s:%d=========================OK", __func__, __LINE__);
  243.     return HDF_SUCCESS;
  244. ERR_SUBMIT_REQ:
  245.     UsbStopIo(acm); // 停止IO线程并释放所有资源
  246. ERR_START_IO:
  247.     UsbFreeReadRequests(acm);
  248. ERR_ALLOC_READ_REQS:
  249.     UsbFreeNotifyReqeust(acm);
  250. ERR_ALLOC_NOTIFY_REQ:
  251.     UsbFreeWriteRequests(acm);
  252. ERR_ALLOC_WRITE_REQS:
  253.     AcmWriteBufFree(acm);
  254. ERR_ALLOC_WRITE_BUF:
  255.     UsbReleaseInterfaces(acm);
  256. ERR_PARSE_DESC:
  257.     UsbRawFreeConfigDescriptor(acm->config);
  258.     acm->config = NULL;
  259. ERR_GET_DESC:
  260.     (void)UsbRawCloseDevice(devHandle); // 关闭USB设备对象
  261. ERR_OPEN_DEVICE:
  262.     UsbRawExit(acm->session); // 退出USB DDK的专家模式
  263.     return ret;
  264. }
  265. ...
  266. static void UsbSerialRelease(struct AcmDevice *acm)
  267. {
  268.     if (!(acm->initFlag)) {
  269.         HDF_LOGE("%s:%d: initFlag is false", __func__, __LINE__);
  270.         return;
  271.     }
  272.     /* stop io thread and release all resources */
  273.     UsbStopIo(acm);
  274.     if (g_syncRequest != NULL) {
  275.         UsbRawFreeRequest(g_syncRequest);
  276.         g_syncRequest = NULL;
  277.     }
  278.     UsbFreeReadRequests(acm);
  279.     UsbFreeNotifyReqeust(acm);
  280.     UsbFreeWriteRequests(acm);
  281.     AcmWriteBufFree(acm);
  282.     UsbReleaseInterfaces(acm);
  283.     (void)UsbRawCloseDevice(acm->devHandle);
  284.     UsbRawFreeConfigDescriptor(acm->config);
  285.     acm->config = NULL;
  286.     // 退出USB DDK的专家模式
  287.     UsbRawExit(acm->session);
  288.     acm->initFlag = false;
  289. }
  290. static int32_t UsbSerialDriverInit(struct HdfDeviceObject *device)
  291. {
  292.     struct AcmDevice *acm = NULL;
  293.     int32_t ret;
  294.     if (device == NULL) {
  295.         HDF_LOGE("%s:%d device is null", __func__, __LINE__);
  296.         return HDF_ERR_INVALID_OBJECT;
  297.     }
  298.     acm = (struct AcmDevice *)device->service;
  299.     if (acm == NULL) {
  300.         return HDF_ERR_INVALID_OBJECT;
  301.     }
  302.     OsalMutexInit(&acm->readLock);
  303.     OsalMutexInit(&acm->writeLock);
  304.         // 设备申请连续的内存
  305.     ret = UsbSerialDeviceAlloc(acm);
  306.     if (ret != HDF_SUCCESS) {
  307.         HDF_LOGE("%s:%d UsbSerialDeviceAlloc failed", __func__, __LINE__);
  308.     }
  309.     acm->initFlag = false;
  310.     g_rawAcmReleaseFlag = false;
  311.     HDF_LOGD("%s:%d init ok!", __func__, __LINE__);
  312.     return ret;
  313. }
  314. static void UsbSerialDriverRelease(struct HdfDeviceObject *device)
  315. {
  316.     struct AcmDevice *acm = NULL;
  317.     if (device == NULL) {
  318.         HDF_LOGE("%s: device is null", __func__);
  319.         return;
  320.     }
  321.     acm = (struct AcmDevice *)device->service;
  322.     if (acm == NULL) {
  323.         HDF_LOGE("%s: acm is null", __func__);
  324.         return;
  325.     }
  326.     g_rawAcmReleaseFlag = true;
  327.     if (acm->initFlag) {
  328.         HDF_LOGE("%s:%d UsbSerialRelease", __func__, __LINE__);
  329.         UsbSerialRelease(acm);
  330.     }
  331.     UsbSeriaDevicelFree(acm);
  332.     OsalMutexDestroy(&acm->writeLock);
  333.     OsalMutexDestroy(&acm->readLock);
  334.     OsalMutexDestroy(&acm->lock);
  335.     OsalMemFree(acm);
  336.     acm = NULL;
  337.     HDF_LOGD("%s:%d exit", __func__, __LINE__);
  338. }
  339. struct HdfDriverEntry g_usbSerialRawDriverEntry = {
  340.     .moduleVersion = 1,
  341.     .moduleName = "usbhost_acm_rawapi", // 驱动模块名称,必须与hcs文件中配置的名称一致
  342.     .Bind = UsbSerialDriverBind,
  343.     .Init = UsbSerialDriverInit,
  344.     .Release = UsbSerialDriverRelease,
  345. };
  346. HDF_INIT(g_usbSerialRawDriverEntry);
复制代码
Device DDK API驱动开辟

USB ACM设备焦点代码路径为drivers\peripheral\usb\gadget\function\acm\cdcacm.c。其使用示比方下所示,起首根据描述符创建立备,然后获取接口,打开接口,获取Pipe信息,接收Event事件,接着进行USB通信(读写等),设备卸载时候,关闭接口,停止Event接收,删除设备。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4