센서 하드웨어 추상화 계층(HAL)은 Android 센서 프레임워크와 가속도계 또는 자이로스코프 같은 기기의 센서 사이의 인터페이스입니다. 센서 HAL은 프레임워크가 센서를 제어하기 위해 구현해야 하는 함수를 정의합니다.
Android 10 이상에서는 새 기기와 업그레이드된 기기에 사용할 수 있는 센서 HAL 2.0이 제공됩니다. 센서 HAL 2.0은 센서 HAL 1.0에 기반하지만 이전 버전과의 호환성이 차단되는 몇 가지 중요한 차이점이 있습니다. 센서 HAL 2.0은 FMQ(Fast Message Queues)를 사용하여 HAL의 센서 이벤트를 Android 센서 프레임워크로 전송합니다.
Android 11 이상에서는 새 기기와 업그레이드된 기기에 사용할 수 있는 센서 HAL 2.1이 제공됩니다. 센서 HAL 2.1은 HINGE_ANGLE 센서 유형을 노출하고 HINGE_ANGLE
유형을 수용하도록 다양한 메서드를 업데이트하는 센서 HAL 2.0의 반복입니다.
HAL 2.1 인터페이스
센서 HAL 2.1의 주요 문서 자료는 hardware/interfaces/sensors/2.1/ISensors.hal의 HAL 정의에 있습니다.
이 페이지와 ISensors.hal
간에 요구사항이 충돌하는 경우 ISensors.hal
의 요구사항을 사용하세요.
HAL 2.0 인터페이스
센서 HAL 2.0의 주요 문서 자료는 hardware/interfaces/sensors/2.0/ISensors.hal의 HAL 정의에 있습니다.
이 페이지와 ISensors.hal
간에 요구사항이 충돌하는 경우 ISensors.hal
의 요구사항을 사용하세요.
센서 HAL 2.0 및 HAL 2.1 구현
센서 HAL 2.0 또는 2.1을 구현하려면 객체가 ISensors
인터페이스를 확장하고 2.0/ISensors.hal
또는 2.1/ISensors.hal
에 정의된 모든 함수를 구현해야 합니다.
HAL 초기화
센서 HAL은 사용 가능하려면 Android 센서 프레임워크로 초기화해야 합니다. 이 프레임워크는 HAL 2.0의 경우에는 initialize()
함수를, HAL 2.1의 경우에는 initialize_2_1()
함수를 호출하여 3개의 매개변수(FMQ 설명자 2개와 ISensorsCallback
객체 포인터 한 개)를 센서 HAL에 제공합니다.
HAL은 첫 번째 설명자를 사용하여 센서 이벤트를 프레임워크에 작성하는 데 사용되는 이벤트 FMQ를 생성합니다. HAL은 두 번째 설명자를 사용하여 HAL이 WAKE_UP
센서 이벤트의 wake lock을 해제할 때 동기화하는 데 사용되는 Wake Lock FMQ를 생성합니다. HAL은 필요한 콜백 함수가 호출되도록 ISensorsCallback
객체의 포인터를 저장해야 합니다.
initialize()
또는 initialize_2_1()
함수가 센서 HAL을 초기화할 때 처음으로 호출되어야 합니다.
사용할 수 있는 센서 노출
기기에서 사용 가능한 모든 정적 센서 목록을 가져오려면 HAL 2.0에서는 getSensorsList()
함수를, HAL 2.1에서는 getSensorsList_2_1()
함수를 사용하세요. 이 함수는 각각 핸들로 고유하게 식별되는 센서 목록을 반환합니다. 지정된 센서의 핸들은 센서 HAL을 호스팅하는 프로세스가 다시 시작될 때 변경되어서는 안 됩니다. 핸들은 기기 재부팅 및 시스템 서버 다시 시작 시 변경될 수 있습니다.
여러 센서가 같은 센서 유형과 wake-up 속성을 공유하는 경우 목록의 첫 번째 센서가 기본 센서로 선언되고 getDefaultSensor(int sensorType, bool wakeUp)
함수를 활용하는 앱에 반환됩니다.
센서 목록의 안정성
센서 HAL이 다시 시작된 후, 다시 시작하기 전에 가져온 센서 목록과 비교하여 중요한 변경사항이 있다는 내용이 getSensorsList()
또는 getSensorsList_2_1()
에 의해 반환된 데이터에 표시되는 경우 프레임워크는 Android 런타임이 다시 시작하도록 트리거합니다. 지정된 핸들을 갖는 센서가 누락되었거나 그 센서의 속성이 변경되었거나 새 센서가 도입된 경우가 센서 목록의 중요한 변경사항입니다. Android 런타임을 다시 시작하면 사용자가 지장을 받을 수 있지만, 이는 필수입니다. 앱의 전체 기간 동안에 정적(비동적) 센서가 변경되지 않는다는 Android API 계약을 Android 프레임워크가 더 이상 충족할 수 없기 때문입니다. 그리고 이로 인해 앱의 활성 센서 요청을 프레임워크가 다시 설정하지 못할 수도 있습니다. 따라서 HAL 공급업체는 피할 수 있는 센서 목록 변경을 예방하는 것이 좋습니다.
안정적인 센서 핸들을 보장하려면 HAL은 기기의 실제 센서를 핸들에 확실히 매핑해야 합니다. 센서 HAL 인터페이스에서 요구하는 구체적인 구현은 없지만 개발자에게는 이러한 요구사항을 충족할 수 있는 여러 옵션이 주어집니다.
예를 들어 센서 목록은 각 센서의 고정 속성(예: 공급업체, 모델 및 센서 유형) 조합을 사용하여 정렬할 수 있습니다. 또 다른 옵션은 기기의 정적 센서가 하드웨어에 고정되어 있다는 사실에 기반합니다. 따라서 HAL은 필요한 모든 센서가 getSensorsList()
또는 getSensorsList_2_1()
에서 반환되기 전에 초기화를 완료한 시점을 알아야 합니다. 필요한 센서 목록은 HAL 바이너리로 컴파일하거나 파일 시스템의 구성 파일에 저장할 수 있으며, 표시 순서는 안정된 핸들을 파생하는 데 사용할 수 있습니다. 최고의 해결 방법은 HAL의 구체적인 구현 세부정보에 따라 다르지만 핵심 요구사항은 센서 핸들이 HAL 다시 시작 시 변경되지 않아야 한다는 점입니다.
센서 구성
센서는 활성화되기 전에 batch()
함수를 통해 샘플링 기간 및 최대 보고 지연 시간으로 구성해야 합니다.
센서는 센서 데이터의 손실 없이 batch()
를 통해 언제든지 재구성 가능해야 합니다.
샘플링 기간
샘플링 기간은 구성 중인 센서 유형에 따라 다른 의미를 지닙니다.
- 연속: 센서 이벤트가 연속 속도로 생성됩니다.
- 온체인지: 이벤트가 샘플링 기간보다 더 빠르게 생성되지 않으며, 측정된 값이 변경되지 않을 경우 샘플링 기간보다 더 느리게 생성될 수 있습니다.
- 원샷: 샘플링 기간이 무시됩니다.
- 특수: 자세한 내용은 센서 유형을 참고하세요.
샘플링 기간과 센서 보고 모드 간의 상호작용에 관한 자세한 내용은 보고 모드를 참고하세요.
최대 보고 지연 시간
최대 보고 지연 시간은 SoC가 활성화된 상태에서 이벤트가 HAL을 통해 이벤트 FMQ에 작성되기 전에 지연되고 하드웨어 FIFO에 저장될 수 있는 최대 시간(나노초)을 설정합니다.
값이 0인 경우 이벤트를 측정되는 즉시 보고하고, 센서의 한 이벤트가 FIFO에 존재하면 즉시 FIFO를 아예 건너뛰거나 비워야 함을 의미합니다.
예를 들어 가속도계가 최대 보고 지연 시간 0으로 50Hz에서 활성화된 경우 SoC가 활성화되면 인터럽트가 초당 50회 트리거됩니다.
최대 보고 지연 시간이 0보다 큰 경우에는 센서 이벤트를 감지하는 즉시 보고할 필요가 없습니다. 이벤트는 하드웨어 FIFO에 임시 보관하여 일괄 보고할 수 있습니다. 단, 이벤트가 최대 보고 지연 시간보다 길게 지연되면 안 됩니다. 이전 배치 이후의 모든 이벤트는 한 번에 기록 및 반환됩니다. 이렇게 하면 SoC로 전송되는 인터럽트 수가 감소하며, 센서가 데이터를 캡처하고 일괄 처리하는 동안 SoC가 저전력 모드로 전환될 수 있습니다.
각 이벤트에는 타임스탬프가 연결되어 있습니다. 이벤트가 보고되는 시간을 지연할 때 이벤트 타임스탬프가 영향을 받으면 안 됩니다. 타임스탬프는 정확해야 하며 이벤트가 보고된 시간이 아니라 이벤트가 실제로 발생한 시간과 일치해야 합니다.
최대 보고 지연 시간이 0이 아닌 센서 이벤트를 보고하는 과정에 관한 추가 정보와 요구사항은 일괄 처리를 참고하세요.
센서 활성화
프레임워크는 activate()
함수를 통해 센서를 사용 설정하고 중지합니다.
프레임워크는 센서를 활성화하기 전에 먼저 batch()
를 통해 센서를 구성해야 합니다.
센서가 비활성화된 후에는 그 센서의 추가 센서 이벤트를 이벤트 FMQ에 작성해서는 안 됩니다.
센서 플러시
센서가 센서 데이터를 일괄 처리하도록 구성된 경우 프레임워크는 flush()
를 호출하여 일괄 처리된 센서 이벤트를 강제로 즉각 플러시할 수 있습니다. 이렇게 하면 지정된 센서 핸들에 일괄 처리된 센서 이벤트가 이벤트 FMQ에 즉시 작성됩니다. 센서 HAL은 flush()
호출의 결과로 작성된 센서 이벤트 끝에 플러시 완료 이벤트를 추가해야 합니다.
플러시는 비동기식으로 발생합니다(즉, 이 함수가 즉시 반환되어야 함). 구현에서 몇몇 센서에 단일 FIFO가 사용되는 경우 그 FIFO가 플러시되고 플러시 완료 이벤트는 지정된 센서와 관련해서만 추가됩니다.
지정된 센서에 FIFO가 없거나(버퍼링 불가) 호출 시점에 FIFO가 비어 있던 경우 flush()
는 계속 이어져야 하고 그 센서와 관련해 플러시 완료 이벤트를 전송해야 합니다. 이는 원샷 센서를 제외한 모든 센서에 적용됩니다.
원샷 센서에 flush()
가 호출되면 flush()
는 BAD_VALUE
를 반환해야 하고 플러시 완료 이벤트를 생성해서는 안 됩니다.
센서 이벤트를 FMQ에 작성
이벤트 FMQ는 센서 HAL이 센서 이벤트를 Android 센서 프레임워크로 푸시하기 위한 용도로 사용됩니다.
이벤트 FMQ는 동기화된 FMQ입니다. 즉, 가용 공간을 초과하는 이벤트를 FMQ에 작성하려고 시도할 경우 작성에 실패합니다. 이 경우 HAL은 현재의 이벤트 집합을 2개의 소규모 이벤트 그룹으로 작성할지, 아니면 충분한 공간이 확보되었을 때 모든 이벤트를 함께 작성할지 결정해야 합니다.
센서 HAL이 원하는 수의 센서 이벤트를 이벤트 FMQ에 작성하면 센서 HAL은 이벤트 FMQ의 EventFlag::wake
함수에 EventQueueFlagBits::READ_AND_PROCESS
비트를 작성하여 이벤트가 준비되었음을 프레임워크에 알려야 합니다. EventFlag는 EventFlag::createEventFlag
및 이벤트 FMQ의 getEventFlagWord()
함수를 사용하여 이벤트 FMQ에서 생성할 수 있습니다.
센서 HAL 2.0/2.1은 이벤트 FMQ에서 write
와 writeBlocking
를 모두 지원합니다.
기본 구현에서는 write
를 사용하기 위한 참조를 제공합니다. writeBlocking
함수를 사용하는 경우 readNotification
플래그를 EventQueueFlagBits::EVENTS_READ
로 설정해야 합니다. 이 플래그는 프레임워크가 이벤트 FMQ에서 이벤트를 읽어올 때 설정하는 것입니다. 쓰기 알림 플래그는 EventQueueFlagBits::READ_AND_PROCESS
로 설정해야 합니다. 그러면 이벤트가 이벤트 FMQ에 작성되었다는 알림이 프레임워크에 전송됩니다.
WAKE_UP 이벤트
WAKE_UP
이벤트는 애플리케이션 프로세서(AP)가 활성화되어 즉시 이벤트를 처리하도록 하는 센서 이벤트입니다. WAKE_UP
이벤트가 이벤트 FMQ에 작성될 때마다 센서 HAL은 프레임워크에서 이벤트를 처리할 수 있을 때까지 시스템이 절전모드를 해제하도록 wake lock을 확보해야 합니다. WAKE_UP
이벤트를 수신한 프레임워크는 센서 HAL이 wake lock을 해제할 수 있도록 자체 wake lock을 확보합니다. 센서 HAL이 wake lock을 해제할 때 동기화하려면 Wake Lock FMQ를 사용하세요.
센서 HAL은 Wake Lock FMQ를 읽어 프레임워크에서 처리한 WAKE_UP
이벤트 수를 파악해야 합니다. HAL은 처리되지 않은 WAKE_UP
이벤트의 총개수가 0인 경우에만 WAKE_UP
이벤트의 wake lock을 해제해야 합니다.
프레임워크는 센서 이벤트를 처리한 후 WAKE_UP
이벤트로 표시된 이벤트 수를 계산하고 이 수치를 다시 Wake Lock FMQ에 작성합니다.
프레임워크는 Wake Lock FMQ에 데이터를 작성할 때마다 Wake Lock FMQ에 WakeLockQueueFlagBits::DATA_WRITTEN
쓰기 알림을 설정합니다.
동적 센서
동적 센서는 기기의 물리적 요소는 아니지만 가속도계가 포함된 게임패드 같은 기기의 입력으로 사용할 수 있는 센서입니다.
동적 센서가 연결되면 ISensorsCallback
에서 onDynamicSensorConnected
함수가 센서 HAL에서 호출되어야 합니다. 그러면 프레임워크가 새로운 동적 센서에 관한 알림을 수신하게 됩니다. 또한 센서가 프레임워크를 통해 제어 가능하며 클라이언트에서 사용할 센서 이벤트를 가질 수 있습니다.
마찬가지로 동적 센서가 연결 해제되면 프레임워크가 더 이상 사용할 수 없는 모든 센서를 없앨 수 있도록 ISensorsCallback
에서 onDynamicSensorDisconnected
함수가 호출되어야 합니다.
직접 채널
직접 채널은 센서 이벤트가 Android 센서 프레임워크를 우회하여 이벤트 FMQ에 작성되는 대신 구체적인 메모리에 작성되는 연산 방식입니다. 직접 채널을 등록하는 클라이언트는 직접 채널을 생성하는 데 사용된 메모리에서 직접 센서 이벤트를 읽어야 하며, 프레임워크를 통해 센서 이벤트를 수신하지 않습니다. configDirectReport()
함수는 일반 연산의 경우 batch()
와 유사하며 직접 보고 채널을 구성합니다.
registerDirectChannel()
및 unregisterDirectChannel()
함수는 새 직접 채널을 만들거나 삭제합니다.
연산 모드
setOperationMode()
함수를 사용하면 프레임워크가 센서 데이터를 센서에 삽입할 수 있도록 센서를 구성할 수 있습니다. 이는 테스트, 특히 프레임워크 아래에 존재하는 알고리즘에 유용합니다.
HAL 2.0의 injectSensorData()
함수와 HAL 2.0의 injectSensorsData_2_1()
함수가 일반적으로 연산 매개변수를 센서 HAL로 푸시하는 데 사용됩니다. 이 함수는 센서 이벤트를 특정 센서에 삽입하는 데에도 사용할 수 있습니다.
유효성 검사
센서 HAL 구현의 유효성을 검사하려면 센서 CTS 및 VTS 테스트를 실행하세요.
CTS 테스트
센서 CTS 테스트는 자동화된 CTS 테스트와 수동 CTS 인증 도구 앱에 모두 존재합니다.
자동화된 테스트는 cts/tests/sensor/src/android/hardware/cts에 있습니다. 이 테스트는 센서 활성화, 일괄 처리 및 센서 이벤트 비율과 같은 센서의 일반적인 기능을 검증합니다.
CTS 인증 도구 테스트는 cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors에 있습니다. 이 테스트에는 테스트 운영자의 수동 입력이 필요하며, 센서가 정확한 값을 보고하는지 확인합니다.
테스트 대상 기기는 CTS 테스트에 합격해야만 모든 CDD 요구사항을 충족할 수 있습니다.
VTS 테스트
센서 HAL 2.0 관련 VTS 테스트는 hardware/interfaces/sensors/2.0/vts에 있습니다.
센서 HAL 2.1 관련 VTS 테스트는 hardware/interfaces/sensors/2.1/vts에 있습니다.
이러한 테스트는 센서 HAL이 제대로 구현되었는지, ISensors.hal
및 ISensorsCallback.hal
내의 모든 요구사항을 제대로 충족하는지 확인합니다.
센서 HAL 2.0에서 2.1로 업그레이드
센서 HAL 2.0에서 2.1로 업그레이드할 경우 HAL 구현에는 initialize_2_1()
, getSensorsList_2_1()
, injectSensorsData_2_1()
메서드를 HAL 2.1 유형과 함께 포함해야 합니다. 이러한 메서드는 위 HAL 2.0과 관련해 설명된 동일한 요구사항을 충족해야 합니다.
부 버전 HAL이 이전 HAL의 모든 함수를 지원해야 하므로 2.1 HAL은 2.0 HAL로 초기화가 가능해야 합니다. 두 HAL 버전을 모두 지원하는 복잡성을 피하려면 다중 HAL 2.1을 사용하는 것이 좋습니다.
자체적인 센서 2.1 HAL을 구현하는 방법의 예는 Sensors.h를 참고하세요.
센서 HAL 1.0에서 2.0으로 업그레이드
센서 HAL 1.0에서 2.0으로 업그레이드할 때는 HAL 구현이 다음 요구사항을 충족하는지 확인해야 합니다.
HAL 초기화
프레임워크와 HAL 간의 FMQ를 설정하는 데 initialize()
함수를 사용할 수 있어야 합니다.
사용할 수 있는 센서 노출
센서 HAL 2.0에서 getSensorsList()
함수는 센서 HAL이 다시 시작되는 중이더라도 단일 기기 부팅 시 동일한 값을 반환해야 합니다. 센서 HAL이 다시 시작되는 중이더라도 단일 기기 부팅 시 getSensorsList()
함수가 동일한 값을 반환해야 한다는 요구사항이 새로 추가되었습니다. 그러면 시스템 서버가 다시 시작되면 프레임워크가 센서 연결을 다시 시도할 수 있습니다. getSensorsList()
에서 반환된 값은 기기가 재부팅한 후에 변경 가능합니다.
센서 이벤트를 FMQ에 작성
센서 HAL 2.0에서 센서 HAL은 poll()
가 호출되기를 기다리는 센서 이벤트가 사용 가능할 때마다 미리 이벤트 FMQ에 센서 이벤트를 작성해야 합니다 또한 HAL은 프레임워크 내에서 FMQ 읽기가 발생하도록 올바른 비트를 EventFlag
에 작성하는 역할도 합니다.
WAKE_UP 이벤트
센서 HAL 1.0에서 HAL은 WAKE_UP
이 poll()
에 게시된 이후에 poll()
에 관한 모든 후속 호출에서 WAKE_UP
이벤트의 wake lock을 해제할 수 있었습니다. 이는 프레임워크가 모든 센서 이벤트를 처리했고 필요한 경우 wake lock을 획득했다는 의미이기 때문입니다. 센서 HAL 2.0에서는 프레임워크가 FMQ에 작성된 이벤트를 처리했을 때 HAL이 더 이상 이를 알지 못합니다. 이 때문에 Wake Lock FMQ는 프레임워크가 WAKE_UP
이벤트를 처리하면 이를 HAL에 알릴 수 있도록 허용합니다.
센서 HAL 2.0에서는 WAKE_UP
이벤트와 관련하여 센서 HAL이 확보한 wake lock은 SensorsHAL_WAKEUP
으로 시작해야 합니다.
동적 센서
센서 HAL 1.0에서는 동적 센서가 poll()
함수를 사용하여 반환되었습니다.
센서 HAL 2.0에서는 동적 센서 연결이 변경될 때마다 ISensorsCallback
에 onDynamicSensorsConnected
및 onDynamicSensorsDisconnected
가 호출되어야 합니다. 이러한 콜백은 initialize()
함수를 통해 제공되는 ISensorsCallback
포인터의 일부로 사용할 수 있습니다.
연산 모드
WAKE_UP
센서의 DATA_INJECTION
모드가 센서 HAL 2.0에서 지원되어야 합니다.
다중 HAL 지원
센서 HAL 2.0 및 2.1은 센서 다중 HAL 프레임워크를 사용하는 다중 HAL을 지원합니다. 구현 세부정보는 센서 HAL 1.0에서 포팅을 참고하세요.