💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
结构体hw_module_t和hw_device_t及其相关的其他结构体定义在文件`hardware/libhardware/include/hardware/hardware.h`中。下面我们就分别介绍这些结构体的定义。 **struct hw_module_t** **hardware/libhardware/include/hardware/hardware.h** ~~~ /* * Value for the hw_module_t.tag field */ #define MAKE_TAG_CONSTANT(A,B,C,D) (((A) << 24) | ((B) << 16) | ((C) << 8) | (D)) #define HARDWARE_MODULE_TAG MAKE_TAG_CONSTANT('H', 'W', 'M', 'T') /** * Name of the hal_module_info */ #define HAL_MODULE_INFO_SYM HMI /** * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM * and the fields of this data structure must begin with hw_module_t * followed by module specific information. */ typedef struct hw_module_t { /** tag must be initialized to HARDWARE_MODULE_TAG */ uint32_t tag; /** major version number for the module */ uint16_t version_major; /** minor version number of the module */ uint16_t version_minor; /** Identifier of module */ const char *id; /** Name of this module */ const char *name; /** Author/owner/implementor of the module */ const char *author; /** Modules methods */ struct hw_module_methods_t* methods; /** module's dso */ void* dso; /** padding to 128 bytes, reserved for future use */ uint32_t reserved[32-7]; } hw_module_t; ~~~ 结构体hw_module_t中的每一个成员变量在代码中都有详细的解释,这里不再重复。不过,有五点是需要注意的。 (1)在结构体hw_module_t的定义前面有一段注释,意思是,硬件抽象层中的每一个模块都必须自定义一个硬件抽象层模块结构体,而且它的第一个成员变量的类型必须为hw_module_t。 (2)硬件抽象层中的每一个模块都必须存在一个导出符号HAL_MODULE_IFNO_SYM,即“HMI”,它指向一个自定义的硬件抽象层模块结构体。后面我们在分析硬件抽象层模块的加载过程时,将会看到这个导出符号的意义。 (3)结构体hw_module_t的成员变量tag的值必须设置为HARDWARE_MODULE_TAG,即设置为一个常量值('H'<<24 | 'W'<<16 | 'M'<<8 | 'T'),用来标志这是一个硬件抽象层模块结构体。 (4)结构体hw_module_t的成员变量dso用来保存加载硬件抽象层模块后得到的句柄值。前面提到,每一个硬件抽象层模块都对应有一个动态链接库文件。加载硬件抽象层模块的过程实际上就是调用dlopen函数来加载与其对应的动态链接库文件的过程。在调用dlclose函数来卸载这个硬件抽象层模块时,要用到这个句柄值,因此,我们在加载时需要将它保存起来。 (5)结构体hw_module_t的成员变量methods定义了一个硬件抽象层模块的操作方法列表,它的类型为hw_module_methods_t,接下来我们就介绍它的定义。 **struct hw_module_methods_t** **hardware/libhardware/include/hardware/hardware.h** ~~~ typedef struct hw_module_methods_t { /** Open a specific device */ int (*open)(const struct hw_module_t* module, const char* id, struct hw_device_t** device); } hw_module_methods_t; ~~~ 结构体hw_module_methods_t只有一个成员变量,它是一个函数指针,用来打开硬件抽象层模块中的硬件设备。其中,参数module表示要打开的硬件设备所在的模块;参数id表示要打开的硬件设备的ID;参数device是一个输出参数,用来描述一个已经打开的硬件设备。由于一个硬件抽象层模块可能会包含多个硬件设备,因此,在调用结构体hw_module_methods_t的成员变量open来打开一个硬件设备时,我们需要指定它的ID。硬件抽象层中的硬件设备使用结构体hw_device_t来描述,接下来我们就介绍它的定义。 **struct hw_device_t** **hardware/libhardware/include/hardware/hardware.h** ~~~ #define HARDWARE_DEVICE_TAG MAKE_TAG_CONSTANT('H', 'W', 'D', 'T') /** * Every device data structure must begin with hw_device_t * followed by module specific public methods and attributes. */ typedef struct hw_device_t { /** tag must be initialized to HARDWARE_DEVICE_TAG */ uint32_t tag; /** version number for hw_device_t */ uint32_t version; /** reference to the module this device belongs to */ struct hw_module_t* module; /** padding reserved for future use */ uint32_t reserved[12]; /** Close this device */ int (*close)(struct hw_device_t* device); } hw_device_t; ~~~ 结构体hw_device_t中的每一个成员变量在代码中都有详细的解释,这里不再重复。不过,有三点是需要注意的。 (1)硬件抽象层模块中的每一个硬件设备都必须自定义一个硬件设备结构体,而且它的第一个成员变量的类型必须为hw_device_t。 (2)结构体hw_device_t的成员变量tag的值必须设置为HARDWARE_DEVICE_TAG,即设置为一个常量值('H'<<24 | 'W'<<16 | 'D'<<8 | 'T'),用来标志这是一个硬件抽象层中的硬件设备结构体。 (3)结构体hw_device_t的成员变量close是一个函数指针,它用来关闭一个硬件设备。 注意:硬件抽象层中的硬件设备是由其所在的模块提供接口来打开的,而关闭则是由硬件设备自身提供接口来完成的。 至此,硬件抽象层模块接口的编写规范就介绍完了。接下来,我们就可以为虚拟硬件设备freg编写硬件抽象层模块接口了。