`
coderplay
  • 浏览: 578012 次
  • 性别: Icon_minigender_1
  • 来自: 广州杭州
社区版块
存档分类
最新评论

emulator调试日志: driver篇

阅读更多
--------- driver篇 ---------------
driver一般通过erl_ddll.erl中的load_driver/2函数来实现.
load_driver(Path, Driver) ->
    do_load_driver(Path, Driver, [{driver_options,[kill_ports]}]).
...
do_load_driver(Path, Driver, DriverFlags) ->
    case erl_ddll:try_load(Path, Driver,[{monitor,pending_driver}]++DriverFlags) of
   
注意其中try_load的参数, OptionList为[{monitor,pending_driver}]++DriverFlags, 即 [{monitor,pending_driver}, {driver_options, [kill_ports]}].
详细意义见otp文档的erl_ddll:try_load/3注释.
        ...
由此可以看出最后还是委托到erl_ddll:try_load/3函数. 这个函数由bif实现, 具体实现在emulator/beam/erl_bif_ddll.c:139行
/*
 *    try_load(Path, Name, OptionList) -> {ok,Status} |
 *                                        {ok, PendingStatus, Ref} |
 *                                        {error, ErrorDesc}
 *       Path = Name = string() | atom()
 *     OptionList = [ Option ]
 *     Option = {driver_options, DriverOptionList} |
 *                {monitor,MonitorOption} |
 *                {reload, ReloadOption}
 *     DriverOptionList = [ DriverOption ]
 *     DriverOption = kill_ports
 *     MonitorOption = pending_driver | pending
 *     ReloadOption = pending_driver | pending
 *     Status = loaded | already_loaded | PendingStatus
 *     PendingStatus = pending_driver | pending_process
 *     Ref = ref()
 *     ErrorDesc = ErrorAtom | OpaqueError
 *     ErrorAtom = linked_in_driver | inconsistent |
 *                 permanent | pending
 */
/*
 * Try to load. If the driver is OK, add as LOADED.  If the driver is
 * UNLOAD, possibly change to reload and add as LOADED,
 * there should be no other
 * LOADED tagged pid's.  If the driver is RELOAD then add/increment as
 * LOADED (should be some LOADED pid).  If the driver is not present,
 * really load and add as LOADED {ok,loaded} {ok,pending_driver}
 * {error, permanent} {error,load_error()}
 */
BIF_RETTYPE erl_ddll_try_load_3(Process *p, Eterm path_term,
                Eterm name_term, Eterm options)
以上是定义.
步骤:
    1. 处理options列表, 获取driver名称以及路径.
    2. if ((de = lookup_driver(name)) != NULL) {...} 判断是否存在此driver,如果存在则reload它.
    3.
        3.1 加载driver .
               res = load_driver_entry(&dh, path, name)
                    res = do_load_driver_entry(dh, path, name)
                        res =  erts_sys_ddll_open(path, &(dh->handle)))
                        此函数通过dlopen调用了一个动态链接库*.so,返回操作此so文件的句柄handle. 以example1_drv为例,此处就是/root/erlang/book_code/src/ports/example1_drv.so
        3.2 初始化driver
                           res = erts_sys_ddll_load_driver_init(dh->handle,
                                  &init_handle)
                               res = erts_sys_ddll_sym(handle, "driver_init", &fn)
                               此函数通过 dlsym(handle, func_name)取得了so文件的driver_init函数的函数指针,在此例中即取得了example_lid.c中的
                                   DRIVER_INIT(example_drv) /* must match name in driver_entry */
                                {
                                    return &example_driver_entry;
                                }
                            此函数的指针.
        3.3 调用driver_init函数
                        dp = erts_sys_ddll_call_init(init_handle);
                    在此即返回了&example_driver_entry这个driver_entry结构体,赋给dp. 然后就可以用dp来干活啦.
        3.4 判断driver版本后,把driver加入到driver_list链表中去.
                        erts_add_driver_entry(dp,1); /* io.c */
    4.把当前进程proc加到driver handle的属性中,并重新分配一下堆空间后,再清理些用到的临时资源.返回.

说白了,driver的工作就是调一个*.so,然后找到这个so中的driver_init函数,调用它. 调用后,会返回一driver_entry结构体的实例. 这个结构体定义了driver的启动,停止,处理port command的函数指针, driver名称,超时时间, i/o操作等各种东西.
以后调用driver就是通过这个结构体的属性来指定了.
分享到:
评论

相关推荐

    AndroidAuto Desktop Head Unit Emulator

    Android Auto Desktop Head Unit Emulator(DHU)是谷歌推出的一款强大的工具,专为开发者设计,用于测试和调试针对Android Auto平台的应用程序。Android Auto是一种车载信息娱乐系统,它允许用户在驾驶时安全地与...

    WinCE常用工具16个.rar

    16. **Device Emulator**: 更高级的模拟器,支持多种WinCE设备配置,用于更全面的测试和调试。 这些工具覆盖了WinCE开发的各个方面,从系统构建、应用开发到调试和优化,是WinCE开发者不可或缺的助手。通过熟练掌握...

    virtual serial port driver(虚拟串口vspd).zip

    6. **配置和管理**:掌握如何安装、配置和管理虚拟串口,包括创建、删除、连接和断开虚拟串口,以及查看串口状态和传输日志。 7. **API接口**:对于开发者,了解VSPD可能提供的编程接口,以便在自己的应用中集成...

    qemu-char-android.rar_android_qemu_qemu char driver

    例如,通过模拟串口,开发者可以连接到虚拟Android设备的adb服务,进行远程调试和日志输出。此外,对于硬件加速的图形和GPU支持,QEMU还提供了图形设备驱动,但此处的"qemu_char-android.c"专注于字符设备的模拟。 ...

    appnium示例代码--手机YY

    5. **日志分析与调试**: Appium提供了详细的日志,可以帮助你诊断测试过程中的问题。通过查看日志,可以定位错误或异常的原因。 6. **扩展功能**: Appium支持多种测试框架(如JUnit、TestNG等)集成,可以进行...

    虚拟串口连接工具

    - 常见的虚拟串口工具包括:Com0Com(开源)、VSPM(Virtual Serial Port Driver)、Serial Port Splitter、ComPort Emulator等。 - 安装和使用虚拟串口工具一般步骤是:安装软件、创建虚拟串口对、设置串口参数、...

    Android 自动化框架 appium

    Appium还支持屏幕录制和日志收集,这对于调试自动化测试过程中的问题非常有用。通过设置特定的命令行参数或在代码中启用这些功能,可以在测试执行过程中记录屏幕活动和收集日志信息。 ### 6. 并行测试 Appium支持...

    自动化测试appium

    Appium 还提供了强大的日志记录功能,帮助调试测试脚本和定位问题。同时,它支持模拟用户的各种手势,如滑动、缩放、旋转屏幕等,极大地增强了测试的覆盖率和真实性。 总之,Appium 是一个强大的自动化测试工具,...

    温度测试的源代码(基于wince的)

    驱动程序通常用C或C++编写,遵循Wince驱动模型,如User-Mode Driver Framework (UMDF)或Kernel-Mode Driver Framework (KMDF)。 2. **传感器接口**:驱动程序会暴露API,使得上层应用可以调用来获取温度数据。这些...

    appium

    Appium 是一个开源自动化测试框架,专为移动应用(iOS 和 Android)的自动化测试而设计。...解决这些问题通常需要查看日志、检查配置,甚至调试 Appium 服务器本身。熟悉 Appium 的错误消息和调试技巧是十分重要的。

    appium-tests

    同时,记录详细的日志信息对于调试和问题追踪至关重要。 7. **测试套件与测试框架集成**:Appium 可以与JUnit、TestNG等测试框架集成,构建完整的测试套件,实现测试用例的分类、执行顺序控制以及测试报告的生成。 ...

    JavaAppiumAutomation

    capabilities.setCapability("deviceName", "Android Emulator"); capabilities.setCapability("appPackage", "com.example.app"); capabilities.setCapability("appActivity", ".MainActivity"); // 连接...

Global site tag (gtag.js) - Google Analytics