> 文档中心 > openharmony标准系统移植之适配hdc功能

openharmony标准系统移植之适配hdc功能

openharmony上有一个重要的调试工具HDC,作为移植上的一点现进行一点适配记录。我们设备端主要运行的代码路径为developtools/hdc_standard/src/daemon,为啥是这个目录见下图,官方给的说明。
openharmony标准系统移植之适配hdc功能
所以能很轻松的找到函数入口,入口为developtools/hdc_standard/src/daemon/main.cpp文件里面的main函数,接下来就是分析执行流程。

展示的是去掉了相关判断的部分代码,并不是完整代码void SetLogCache(bool enable){g_logCache = enable;}int main(int argc, const char *argv[]){Hdc::Base::SetLogCache(false); //设置 g_logCache = false;    Hdc::Base::RemoveLogFile(); //因为g_logCache  = false,所以不执行任何操作    ForkChildCheck(argc, argv); //设置 g_enableUsb = true;g_enableUart = true;    NeedDropPriv();    umask(0);    signal(SIGPIPE, SIG_IGN);    signal(SIGCHLD, SIG_IGN);    signal(SIGALRM, SIG_IGN);    WRITE_LOG(LOG_DEBUG, "HdcDaemon main run");    HdcDaemon daemon(false); //执行函数 HdcDaemon::HdcDaemon 和 HdcSessionBase::HdcSessionBase    daemon.InitMod(g_enableTcp, g_enableUsb, g_enableUart); //执行  HdcDaemon::InitMod(0,1,1)    daemon.WorkerPendding(); //执行 HdcSessionBase::WorkerPendding,这里因为运行了loop循环,s所以下面的无法执行,所以不做分析    return 0;}HdcDaemon::HdcDaemon(bool serverOrDaemonIn)    : HdcSessionBase(serverOrDaemonIn){    clsTCPServ = nullptr;    clsUSBServ = nullptr;    clsUARTServ = nullptr;    clsJdwp = nullptr;    enableSecure = false;}HdcSessionBase::HdcSessionBase(bool serverOrDaemonIn){    // print version pid    WRITE_LOG(LOG_INFO, "Program running. %s Pid:%u", Base::GetVersion().c_str(), getpid());    // server/daemon common initialization code    threadPoolCount = SIZE_THREAD_POOL;    string uvThreadEnv("UV_THREADPOOL_SIZE");    string uvThreadVal = std::to_string(threadPoolCount);     setenv(uvThreadEnv.c_str(), uvThreadVal.c_str(), 1); //用来改变或增加环境变量的内容 UV_THREADPOOL_SIZE = 16    uv_loop_init(&loopMain);    WRITE_LOG(LOG_DEBUG, "loopMain init");    uv_rwlock_init(&mainAsync);    uv_async_init(&loopMain, &asyncMainLoop, MainAsyncCallback);    uv_rwlock_init(&lockMapSession);    serverOrDaemon = false;    ctxUSB = nullptr;    wantRestart = false;    threadSessionMain = uv_thread_self();}void HdcDaemon::InitMod(bool bEnableTCP, bool bEnableUSB, [[maybe_unused]] bool bEnableUART){    WRITE_LOG(LOG_DEBUG, "HdcDaemon InitMod");    WRITE_LOG(LOG_DEBUG, "bEnableTCP:%d,bEnableUSB:%d", bEnableTCP, bEnableUSB);    if (bEnableUSB) { // usb clsUSBServ = new(std::nothrow) HdcDaemonUSB(false, this); //执行HdcDaemonUSB::HdcDaemonUSB和 HdcUSBBase::HdcUSBBase函数 if (clsUSBServ == nullptr) {     WRITE_LOG(LOG_FATAL, "InitMod new clsUSBServ failed");     return; } ((HdcDaemonUSB *)clsUSBServ)->Initial(); // 执行 HdcDaemonUSB::Initial函数    }    WRITE_LOG(LOG_DEBUG, "bEnableUART:%d", bEnableUART);    if (bEnableUART) { // UART clsUARTServ = new(std::nothrow) HdcDaemonUART(*this); if (clsUARTServ == nullptr) {     WRITE_LOG(LOG_FATAL, "InitMod new clsUARTServ failed");     return; } ((HdcDaemonUART *)clsUARTServ)->Initial();    }    clsJdwp = new(std::nothrow) HdcJdwp(&loopMain);    if (clsJdwp == nullptr) { WRITE_LOG(LOG_FATAL, "InitMod new clsJdwp failed"); return;    }    ((HdcJdwp *)clsJdwp)->Initial();    // enable security    string secure;    SystemDepend::GetDevItem("ro.hdc.secure", secure);    enableSecure = (Base::Trim(secure) == "1");}void HdcSessionBase::WorkerPendding(){    uv_run(&loopMain, UV_RUN_DEFAULT);    ClearInstanceResource();}int HdcDaemonUSB::Initial(){    // after Linux-3.8,kernel switch to the USB Function FS    // Implement USB hdc function in user space    WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB init");    basePath = GetDevPath(USB_FFS_BASE); // constexpr auto USB_FFS_BASE = "/dev/usb-ffs/";    if (access((basePath + "/ep0").c_str(), F_OK) != 0) { WRITE_LOG(LOG_DEBUG, "Only support usb-ffs, make sure kernel3.8+ and usb-ffs enabled, usbmode disabled"); return ERR_API_FAIL;    }    ctxRecv.thisClass = this;    ctxRecv.bufSizeMax = Base::GetUsbffsBulkSize();    ctxRecv.buf = new uint8_t[ctxRecv.bufSizeMax]();    if (!ctxRecv.buf) { WRITE_LOG(LOG_FATAL, "Init alloc memory failed"); return ERR_BUF_ALLOC;    }    HdcDaemon *daemon = (HdcDaemon *)clsMainBase;    WRITE_LOG(LOG_DEBUG, "HdcDaemonUSB::Initiall");    uv_timer_init(&daemon->loopMain, &checkEP); // 初始化一个定时器,初始化定时器句柄    checkEP.data = this;    uv_timer_start(&checkEP, WatchEPTimer, 0, 1000);  //constexpr uint16_t TIME_BASE = 1000;    //设置定时器  checkEP: 定时器句柄;WatchEPTimer : 回调函数,定时时间到的时候会调用这个函数;0 : 在 uv_run() 之后多久启动定时器,单位是毫秒;TIME_BASE : 定时器循环定时的时间,也就是重复调用的时间,单位是毫秒    return 0;}

运行结果如下图,可以看到重复调用了WatchEPTimer这个函数
openharmony标准系统移植之适配hdc功能
所以会一直执行如下函数去读取数据

nt HdcDaemonUSB::LoopUSBRead(HUSB hUSB, int readMaxWanted){    int ret = ERR_GENERIC;    HdcDaemon *daemon = reinterpret_cast<HdcDaemon *>(clsMainBase);    uv_buf_t iov;    ctxRecv.data = hUSB;    ctxRecv.bufSize = readMaxWanted;    ctxRecv.req = {};    uv_fs_t *req = &ctxRecv.req;    req->data = &ctxRecv;    iov = uv_buf_init(reinterpret_cast<char *>(ctxRecv.buf), ctxRecv.bufSize);    ret = uv_fs_read(&daemon->loopMain, req, hUSB->bulkOut, &iov, 1, -1, OnUSBRead);    if (ret < 0) { WRITE_LOG(LOG_FATAL, "uv_fs_read < 0"); return ERR_API_FAIL;    }    ctxRecv.atPollQueue = true;    return RET_SUCCESS;}