HAL 架构
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; typedef struct hw_module_t { uint32_t tag; uint16_t module_api_version; uint16_t hal_api_version; /** 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; /** * Every device data structure must begin with hw_device_t * followed by module specific public methods and attributes. */ typedef struct hw_device_t { uint32_t tag; 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); // 该设备的关闭函数指针,可以看做硬件的close方法 } hw_device_t;
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
每一个硬件都通过hw_module_t来描述,我们称之为一个硬件对象。你可以去“继承”这个hw_module_t,然后扩展自己的属性,硬件对象必须定义为一个固定的名字:HMI,即:Hardware Module Information的简写,每一个硬件对象里都封装了一个函数指针open用于打开该硬件,我们理解为硬件对象的open方法,open调用后返回这个硬件对应的Operation interface。
硬件对象hw_module_t的open方法返回该硬件的Operation interface,它由hw_device_t结构体来描述,我们称之为:该硬件的操作接口
-------------------------------------------------------------------------
下面以audio模块为例子来说明如何实现。
hardware/libhardware/include/hardware/audio.h struct audio_module { struct hw_module_t common; //看来audio_module没啥特殊的,沿用hw_module_t 而且audio_hw_device->common中就保存了这个字段。直接强转就行了 }; struct audio_hw_device { /** * Common methods of the audio device. This *must* be the first member of audio_hw_device * as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts * where it's known the hw_device_t references an audio_hw_device. */ struct hw_device_t common; //保存的一些基本信息,任何一个硬件模块都会有这个 uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); int (*init_check)(const struct audio_hw_device *dev); int (*set_voice_volume)(struct audio_hw_device *dev, float volume); int (*set_master_volume)(struct audio_hw_device *dev, float volume); int (*get_master_volume)(struct audio_hw_device *dev, float *volume); int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode); int (*set_mic_mute)(struct audio_hw_device *dev, bool state); int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state); int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs); char * (*get_parameters)(const struct audio_hw_device *dev, const char *keys); size_t (*get_input_buffer_size)(const struct audio_hw_device *dev, const struct audio_config *config); int (*open_output_stream)(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, audio_output_flags_t flags, struct audio_config *config, struct audio_stream_out **stream_out, const char *address); void (*close_output_stream)(struct audio_hw_device *dev, struct audio_stream_out* stream_out); int (*open_input_stream)(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, struct audio_config *config, struct audio_stream_in **stream_in, audio_input_flags_t flags, const char *address, audio_source_t source); void (*close_input_stream)(struct audio_hw_device *dev, struct audio_stream_in *stream_in); int (*dump)(const struct audio_hw_device *dev, int fd); int (*set_master_mute)(struct audio_hw_device *dev, bool mute); int (*get_master_mute)(struct audio_hw_device *dev, bool *mute); int (*create_audio_patch)(struct audio_hw_device *dev, unsigned int num_sources, const struct audio_port_config *sources, unsigned int num_sinks, const struct audio_port_config *sinks, audio_patch_handle_t *handle); int (*release_audio_patch)(struct audio_hw_device *dev, audio_patch_handle_t handle); int (*get_audio_port)(struct audio_hw_device *dev, struct audio_port *port); int (*set_audio_port_config)(struct audio_hw_device *dev, const struct audio_port_config *config); }; typedef struct audio_hw_device audio_hw_device_t; // common audio stream parameters and operations // audio_stream_out和audio_stream_in的公共模块 //大概C语言没有继承的说法,也就只有这种方式来达到代码复用 struct audio_stream { uint32_t (*get_sample_rate)(const struct audio_stream *stream); int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate); size_t (*get_buffer_size)(const struct audio_stream *stream); audio_channel_mask_t (*get_channels)(const struct audio_stream *stream); audio_format_t (*get_format)(const struct audio_stream *stream); int (*set_format)(struct audio_stream *stream, audio_format_t format); int (*standby)(struct audio_stream *stream); int (*dump)(const struct audio_stream *stream, int fd); audio_devices_t (*get_device)(const struct audio_stream *stream); int (*set_device)(struct audio_stream *stream, audio_devices_t device); int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs); char * (*get_parameters)(const struct audio_stream *stream, const char *keys); int (*add_audio_effect)(const struct audio_stream *stream, effect_handle_t effect); int (*remove_audio_effect)(const struct audio_stream *stream, effect_handle_t effect); }; struct audio_stream_out { /** * Common methods of the audio stream out. This *must* be the first member of audio_stream_out * as users of this structure will cast a audio_stream to audio_stream_out pointer in contexts * where it's known the audio_stream references an audio_stream_out. */ struct audio_stream common; // Return the audio hardware driver estimated latency in milliseconds. uint32_t (*get_latency)(const struct audio_stream_out *stream); int (*set_volume)(struct audio_stream_out *stream, float left, float right); ssize_t (*write)(struct audio_stream_out *stream, const void* buffer, size_t bytes); /* return the number of audio frames written by the audio dsp to DAC since * the output has exited standby */ int (*get_render_position)(const struct audio_stream_out *stream, uint32_t *dsp_frames); int (*get_next_write_timestamp)(const struct audio_stream_out *stream, int64_t *timestamp); /** * set the callback function for notifying completion of non-blocking * write and drain. * Calling this function implies that all future write() and drain() * must be non-blocking and use the callback to signal completion. */ int (*set_callback)(struct audio_stream_out *stream, stream_callback_t callback, void *cookie); int (*pause)(struct audio_stream_out* stream); int (*resume)(struct audio_stream_out* stream); int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type ); int (*flush)(struct audio_stream_out* stream); }; typedef struct audio_stream_out audio_stream_out_t; struct audio_stream_in { /** * Common methods of the audio stream in. This *must* be the first member of audio_stream_in * as users of this structure will cast a audio_stream to audio_stream_in pointer in contexts * where it's known the audio_stream references an audio_stream_in. */ struct audio_stream common; // set the input gain for the audio driver. This method is for future use int (*set_gain)(struct audio_stream_in *stream, float gain); ssize_t (*read)(struct audio_stream_in *stream, void* buffer, size_t bytes); uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream); };
再看audio_hw.c,这文件命名,没看出规律来。
hardware/qcom/audio/hal/audio_hw.c static int adev_open(const hw_module_t *module, const char *name, hw_device_t **device) { int i, ret; ALOGD("%s: enter", __func__); if (strcmp(name, AUDIO_HARDWARE_INTERFACE) != 0) return -EINVAL; pthread_mutex_lock(&adev_init_lock); if (audio_device_ref_count != 0){ *device = &adev->device.common; audio_device_ref_count++; ALOGD("%s: returning existing instance of adev", __func__); ALOGD("%s: exit", __func__); pthread_mutex_unlock(&adev_init_lock); return 0; } adev = calloc(1, sizeof(struct audio_device)); pthread_mutex_init(&adev->lock, (const pthread_mutexattr_t *) NULL); adev->device.common.tag = HARDWARE_DEVICE_TAG; adev->device.common.version = AUDIO_DEVICE_API_VERSION_2_0; adev->device.common.module = (struct hw_module_t *)module; adev->device.common.close = adev_close; adev->device.init_check = adev_init_check; adev->device.set_voice_volume = adev_set_voice_volume; adev->device.set_master_volume = adev_set_master_volume; adev->device.get_master_volume = adev_get_master_volume; adev->device.set_master_mute = adev_set_master_mute; adev->device.get_master_mute = adev_get_master_mute; adev->device.set_mode = adev_set_mode; adev->device.set_mic_mute = adev_set_mic_mute; adev->device.get_mic_mute = adev_get_mic_mute; adev->device.set_parameters = adev_set_parameters; adev->device.get_parameters = adev_get_parameters; adev->device.get_input_buffer_size = adev_get_input_buffer_size; adev->device.open_output_stream = adev_open_output_stream; adev->device.close_output_stream = adev_close_output_stream; adev->device.open_input_stream = adev_open_input_stream; adev->device.close_input_stream = adev_close_input_stream; adev->device.dump = adev_dump; /* Set the default route before the PCM stream is opened */ adev->mode = AUDIO_MODE_NORMAL; adev->active_input = NULL; adev->primary_output = NULL; adev->out_device = AUDIO_DEVICE_NONE; adev->bluetooth_nrec = true; adev->acdb_settings = TTY_MODE_OFF; /* adev->cur_hdmi_channels = 0; by calloc() */ adev->snd_dev_ref_cnt = calloc(SND_DEVICE_MAX, sizeof(int)); voice_init(adev); list_init(&adev->usecase_list); adev->cur_wfd_channels = 2; pthread_mutex_init(&adev->snd_card_status.lock, (const pthread_mutexattr_t *) NULL); adev->snd_card_status.state = SND_CARD_STATE_OFFLINE; /* Loads platform specific libraries dynamically */ adev->platform = platform_init(adev); if (!adev->platform) { free(adev->snd_dev_ref_cnt); free(adev); ALOGE("%s: Failed to init platform data, aborting.", __func__); *device = NULL; pthread_mutex_unlock(&adev_init_lock); return -EINVAL; } adev->snd_card_status.state = SND_CARD_STATE_ONLINE; //................. *device = &adev->device.common; audio_device_ref_count++; pthread_mutex_unlock(&adev_init_lock); ALOGV("%s: exit", __func__); return 0; } static struct hw_module_methods_t hal_module_methods = { .open = adev_open, //用这个方法初始化 };
//HAL_MODULE_INFO_SYM存储了audio模块所有相关信息
//可能有个audio_hw_device记录了这个信息 struct audio_module HAL_MODULE_INFO_SYM = { //HAL_MODULE_INFO_SYM 这个名字是固定死的 .common = { .tag = HARDWARE_MODULE_TAG, .module_api_version = AUDIO_MODULE_API_VERSION_0_1, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = AUDIO_HARDWARE_MODULE_ID, .name = "QCOM Audio HAL", .author = "The Linux Foundation", .methods = &hal_module_methods, }, };
----------------------------------------------------------
上层如何实现 可以参考http://www.cnblogs.com/muhe221/articles/4462320.html 这里只做简要说明
AudioPolicyInterface  AudioPolicyClientInterface //这两个一个是服务端,一个是客户端。他们没有共同的接口
audio_policy          			audio_policy_service_ops 
两组互相对应
//frameworks/av/services/audiopolicy/AudioPolicyManager.h
class AudioPolicyManager: public AudioPolicyInterface {
    AudioPolicyManager(AudioPolicyClientInterface *clientInterface);  //构造函数
    //................
    AudioPolicyClientInterface *mpClientInterface;
}
//hardware/libhardware_legacy/audio/AudioPolicyCompatClient.h
class AudioPolicyCompatClient : public AudioPolicyClientInterface {
      AudioPolicyCompatClient(struct audio_policy_service_ops *serviceOps, void *service) : mServiceOps(serviceOps) , mService(service) {}
private:
    struct audio_policy_service_ops* mServiceOps;
    void* mService;
  //......
}
hardware/libhardware/include/hardware/audio_policy.h typedef struct audio_policy_module { struct hw_module_t common; //hw_module_t => audio_module => audio_policy_module(audio_policy_module_t)都是同一类型。 } audio_policy_module_t; struct audio_policy_device { //又封装了一层 /** * Common methods of the audio policy device. This *must* be the first member of * audio_policy_device as users of this structure will cast a hw_device_t to * audio_policy_device pointer in contexts where it's known the hw_device_t references an * audio_policy_device. */ struct hw_device_t common; int (*create_audio_policy)(const struct audio_policy_device *device, struct audio_policy_service_ops *aps_ops, void *service, struct audio_policy **ap); int (*destroy_audio_policy)(const struct audio_policy_device *device, struct audio_policy *ap); };
 
                    
                
                
            
        
浙公网安备 33010602011771号