HALs legados

Uma HAL define uma interface padrão para os fornecedores de hardware implementarem, o que permite que o Android seja agnóstico sobre implementações de driver de nível inferior. O uso de um HAL permite implementar funcionalidades sem afetar ou modificar o sistema de nível superior. Esta página descreve a arquitetura mais antiga, que não é mais compatível a partir do Android 8.0. Para Android 8.0 e superior, consulte Tipos de HAL .

Componentes HAL

Figura 1. Componentes HAL

Você deve implementar o HAL (e driver) correspondente para o hardware específico que seu produto fornece. As implementações de HAL geralmente são incorporadas a módulos de biblioteca compartilhada (arquivos .so ), mas como o Android não exige uma interação padrão entre uma implementação de HAL e drivers de dispositivo, você pode fazer o que for melhor para sua situação. No entanto, para permitir que o sistema Android interaja corretamente com seu hardware, você deve cumprir o contrato definido em cada interface HAL específica de hardware.

Para garantir que os HALs tenham uma estrutura previsível, cada interface HAL específica de hardware possui propriedades definidas em hardware/libhardware/include/hardware/hardware.h . Essa interface permite que o sistema Android carregue versões corretas de seus módulos HAL de maneira consistente. Uma interface HAL consiste em dois componentes: módulos e dispositivos.

Módulos HAL

Um módulo representa sua implementação HAL empacotada, que é armazenada como uma biblioteca compartilhada ( .so file ). O arquivo de cabeçalho hardware/libhardware/include/hardware/hardware.h define uma estrutura ( hw_module_t ) que representa um módulo e contém metadados como versão, nome e autor do módulo. O Android usa esses metadados para encontrar e carregar o módulo HAL corretamente.

Além disso, a estrutura hw_module_t contém um ponteiro para outra estrutura, hw_module_methods_t , que contém um ponteiro para uma função aberta para o módulo. Esta função aberta é usada para iniciar a comunicação com o hardware para o qual o HAL está servindo como uma abstração. Cada HAL específico de hardware geralmente estende a estrutura genérica hw_module_t com informações adicionais para aquela peça específica de hardware. Por exemplo, no HAL da câmera, a estrutura camera_module_t contém uma estrutura hw_module_t junto com outros ponteiros de função específicos da câmera:

typedef struct camera_module {
    hw_module_t common;
    int (*get_number_of_cameras)(void);
    int (*get_camera_info)(int camera_id, struct camera_info *info);
} camera_module_t;

Ao implementar um HAL e criar a estrutura do módulo, você deve nomeá-lo HAL_MODULE_INFO_SYM . Exemplo do HAL de áudio do Nexus 9:

struct audio_module 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 = "NVIDIA Tegra Audio HAL",
        .author = "The Android Open Source Project",
        .methods = &hal_module_methods,
    },
};

Dispositivos HAL

Um dispositivo abstrai o hardware do seu produto. Por exemplo, um módulo de áudio pode conter um dispositivo de áudio principal, um dispositivo de áudio USB ou um dispositivo de áudio Bluetooth A2DP.

Um dispositivo é representado pela estrutura hw_device_t . Semelhante a um módulo, cada tipo de dispositivo define uma versão detalhada do hw_device_t genérico que contém ponteiros de função para recursos específicos do hardware. Por exemplo, o tipo de estrutura audio_hw_device_t contém ponteiros de função para operações do dispositivo de áudio:

struct audio_hw_device {
    struct hw_device_t common;

    /**
     * used by audio flinger to enumerate what devices are supported by
     * each audio_hw_device implementation.
     *
     * Return value is a bitmask of 1 or more values of audio_devices_t
     */
    uint32_t (*get_supported_devices)(const struct audio_hw_device *dev);
  ...
};
typedef struct audio_hw_device audio_hw_device_t;

Além dessas propriedades padrão, cada interface HAL específica de hardware pode definir mais recursos e requisitos próprios. Para obter detalhes, consulte a documentação de referência do HAL , bem como as instruções individuais para cada HAL.

Construindo módulos HAL

As implementações de HAL são incorporadas a arquivos de módulos ( .so ) e são vinculadas dinamicamente pelo Android quando apropriado. Você pode construir seus módulos criando arquivos Android.mk para cada uma de suas implementações de HAL e apontando para seus arquivos de origem. Em geral, suas bibliotecas compartilhadas devem ser nomeadas em um formato específico para que possam ser encontradas e carregadas corretamente. O esquema de nomenclatura varia um pouco de módulo para módulo, mas segue o padrão geral de: <module_type>.<device_name> .