مستشعرات AIDL HAL

طبقة تجريد أجهزة الاستشعار (HAL) هي الواجهة بين إطار عمل مستشعر Android وأجهزة استشعار الجهاز، مثل مقياس التسارع أو الجيروسكوب. تحدد أجهزة الاستشعار HAL الوظائف التي يجب تنفيذها للسماح للإطار بالتحكم في أجهزة الاستشعار.

تتوفر أجهزة الاستشعار AIDL HAL في نظام التشغيل Android 13 والإصدارات الأحدث للأجهزة الجديدة والمحدثة. تستخدم أجهزة الاستشعار AIDL HAL، التي تعتمد على أجهزة الاستشعار HAL 2.1 ، واجهة AIDL HAL وتكشف عن أجهزة تعقب الرأس وأنواع أجهزة استشعار IMU ذات المحور المحدود.

واجهة AIDL HAL

المصدر الرئيسي للتوثيق الخاص بـ Sensors AIDL HAL يقع ضمن تعريف HAL ​​على hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

تنفيذ أجهزة الاستشعار AIDL HAL

لتنفيذ Sensors AIDL HAL، يجب على الكائن توسيع واجهة ISensors وتنفيذ جميع الوظائف المحددة في hardware/interfaces/sensors/aidl/android/hardware/sensors/ISensors.aidl .

تهيئة HAL

يجب تهيئة أجهزة الاستشعار HAL بواسطة إطار عمل مستشعر Android قبل استخدامها. يستدعي إطار العمل وظيفة initialize() لتوفير ثلاث معلمات لـ HAL لأجهزة الاستشعار: واصفان FMQ ومؤشر واحد لكائن ISensorsCallback .

يستخدم HAL الواصف الأول لإنشاء Event FMQ المستخدم لكتابة أحداث المستشعر إلى إطار العمل. يستخدم HAL الواصف الثاني لإنشاء Wake Lock FMQ المستخدم للمزامنة عندما تقوم HAL بتحرير قفل التنشيط الخاص به لأحداث مستشعر WAKE_UP . يجب أن يقوم HAL بحفظ مؤشر إلى كائن ISensorsCallback بحيث يمكن استدعاء أية وظائف رد اتصال ضرورية.

يجب أن تكون وظيفة initialize() هي الوظيفة الأولى التي يتم استدعاؤها عند تهيئة جهاز الاستشعار HAL.

فضح أجهزة الاستشعار المتاحة

للحصول على قائمة بجميع أجهزة الاستشعار الثابتة المتوفرة في الجهاز، استخدم الدالة getSensorsList() . تقوم هذه الوظيفة بإرجاع قائمة من أجهزة الاستشعار، والتي يتم تحديد كل منها بشكل فريد من خلال المقبض الخاص بها. يجب ألا يتغير المقبض الخاص بمستشعر معين عند إعادة تشغيل عملية استضافة أجهزة الاستشعار HAL. قد تتغير المقابض عبر عمليات إعادة تشغيل الجهاز، وعبر عمليات إعادة تشغيل خادم النظام.

إذا كانت عدة أجهزة استشعار تشترك في نفس نوع المستشعر وخاصية التنبيه، فإن المستشعر الأول في القائمة يسمى المستشعر الافتراضي ويتم إرجاعه إلى التطبيقات التي تستخدم وظيفة getDefaultSensor(int sensorType, bool wakeUp) .

استقرار قائمة أجهزة الاستشعار

بعد إعادة تشغيل أجهزة الاستشعار HAL، إذا كانت البيانات التي تم إرجاعها بواسطة getSensorsList() تشير إلى تغيير كبير مقارنة بقائمة أجهزة الاستشعار التي تم استردادها قبل إعادة التشغيل، فسيقوم إطار العمل بتشغيل إعادة تشغيل وقت تشغيل Android. تتضمن التغييرات المهمة في قائمة المستشعرات الحالات التي يكون فيها المستشعر ذو المقبض المحدد مفقودًا أو تم تغيير سماته، أو حيث يتم تقديم مستشعرات جديدة. على الرغم من أن إعادة تشغيل وقت تشغيل Android يعد أمرًا مزعجًا للمستخدم، إلا أنه مطلوب لأن إطار عمل Android لم يعد قادرًا على تلبية عقد Android API الذي لا تتغير فيه المستشعرات الثابتة (غير الديناميكية) أثناء عمر التطبيق. قد يمنع هذا أيضًا إطار العمل من إعادة إنشاء طلبات المستشعر النشطة التي تقدمها التطبيقات. لذلك، يُنصح بائعي HAL بمنع تغييرات قائمة المستشعرات التي يمكن تجنبها.

لضمان ثبات مقابض المستشعر، يجب على HAL تعيين مستشعر مادي معين في الجهاز بشكل حاسم إلى المقبض الخاص به. على الرغم من عدم وجود تنفيذ محدد من خلال واجهة Sensors HAL، إلا أن المطورين لديهم عدد من الخيارات المتاحة لتلبية هذا المطلب.

على سبيل المثال، يمكن فرز قائمة المستشعرات باستخدام مجموعة من السمات الثابتة لكل مستشعر، مثل البائع والطراز ونوع المستشعر. يعتمد خيار آخر على حقيقة أن مجموعة أجهزة الاستشعار الثابتة الخاصة بالجهاز مثبتة في الأجهزة، لذلك يحتاج HAL إلى معرفة متى تكتمل جميع أجهزة الاستشعار المتوقعة من التهيئة قبل العودة من getSensorsList() . يمكن تجميع قائمة المستشعرات المتوقعة هذه في ثنائي HAL أو تخزينها في ملف تكوين في نظام الملفات، ويمكن استخدام ترتيب المظهر لاشتقاق مقابض مستقرة. على الرغم من أن الحل الأفضل يعتمد على تفاصيل التنفيذ المحددة لـ HAL، فإن المتطلب الأساسي هو عدم تغيير مقابض المستشعر خلال عمليات إعادة تشغيل HAL.

تكوين أجهزة الاستشعار

قبل تنشيط المستشعر، يجب تكوين المستشعر بفترة أخذ العينات والحد الأقصى لزمن وصول التقارير باستخدام الدالة batch() .

يجب أن يكون المستشعر قادرًا على إعادة تكوينه في أي وقت باستخدام batch() دون فقدان بيانات المستشعر.

فترة أخذ العينات

فترة أخذ العينات لها معنى مختلف بناءً على نوع المستشعر الذي يتم تكوينه:

  • مستمر: يتم إنشاء أحداث الاستشعار بمعدل مستمر.
  • عند التغيير: لا يتم إنشاء الأحداث بشكل أسرع من فترة أخذ العينات وقد يتم إنشاؤها بمعدل أبطأ من فترة أخذ العينات إذا لم تتغير القيمة المقاسة.
  • طلقة واحدة: يتم تجاهل فترة أخذ العينات.
  • خاص: لمزيد من التفاصيل، راجع أنواع أجهزة الاستشعار .

للتعرف على التفاعل بين فترة أخذ العينات وأوضاع إعداد التقارير الخاصة بالمستشعر، راجع أوضاع إعداد التقارير .

الحد الأقصى لزمن وصول التقارير

يحدد الحد الأقصى لزمن انتقال التقارير الحد الأقصى للوقت بالنانو ثانية الذي يمكن فيه تأخير الأحداث وتخزينها في جهاز FIFO قبل كتابتها إلى Event FMQ من خلال HAL عندما تكون SoC نشطة.

تشير القيمة صفر إلى أنه يجب الإبلاغ عن الأحداث بمجرد قياسها، إما بتخطي ما يصرف أولاً (FIFO) تمامًا، أو إفراغ ما يصرف أولاً (FIFO) بمجرد وجود حدث واحد من المستشعر في ما يصرف أولاً (FIFO).

على سبيل المثال، يقوم مقياس التسارع الذي يتم تنشيطه عند 50 هرتز مع الحد الأقصى لزمن وصول التقارير وهو صفر بتشغيل المقاطعات 50 مرة في الثانية عندما تكون شركة نفط الجنوب في وضع التنشيط.

عندما يكون الحد الأقصى لزمن وصول التقارير أكبر من الصفر، فلن يلزم الإبلاغ عن أحداث المستشعر بمجرد اكتشافها. يمكن تخزين الأحداث مؤقتًا في جهاز FIFO والإبلاغ عنها على دفعات، طالما لم يتم تأخير أي حدث بأكثر من الحد الأقصى لزمن انتقال التقارير. يتم تسجيل جميع الأحداث منذ الدفعة السابقة وإعادتها مرة واحدة. يؤدي ذلك إلى تقليل عدد المقاطعات المرسلة إلى SoC ويسمح لـ SoC بالتبديل إلى وضع طاقة أقل أثناء قيام المستشعر بالتقاط البيانات وتجميعها.

كل حدث له طابع زمني مرتبط به. يجب ألا يؤثر تأخير الوقت الذي يتم فيه الإبلاغ عن الحدث على الطابع الزمني للحدث. يجب أن يكون الطابع الزمني دقيقًا ويتوافق مع الوقت الذي حدث فيه الحدث فعليًا، وليس وقت الإبلاغ عنه.

للحصول على معلومات ومتطلبات إضافية بشأن الإبلاغ عن أحداث المستشعر مع الحد الأقصى لزمن وصول التقارير غير الصفري، راجع التجميع .

تفعيل أجهزة الاستشعار

يقوم الإطار بتمكين وتعطيل أجهزة الاستشعار باستخدام وظيفة activate() . قبل تنشيط المستشعر، يجب على الإطار أولاً تكوين المستشعر باستخدام batch() .

بعد إلغاء تنشيط المستشعر، يجب عدم كتابة أحداث المستشعر الإضافية من هذا المستشعر إلى Event FMQ.

أجهزة استشعار فلوش

إذا تم تكوين المستشعر لبيانات المستشعر المجمعة، فيمكن لإطار العمل فرض تدفق فوري لأحداث المستشعر المجمعة عن طريق استدعاء flush() . يؤدي هذا إلى كتابة أحداث المستشعر المجمعة لمقبض المستشعر المحدد على الفور إلى Event FMQ. يجب أن يقوم جهاز Sensors HAL بإلحاق حدث تدفق كامل بنهاية أحداث المستشعر التي تمت كتابتها كنتيجة لاستدعاء flush() .

يحدث التدفق بشكل غير متزامن (أي أن هذه الوظيفة يجب أن تعود على الفور). إذا كان التنفيذ يستخدم FIFO واحدًا للعديد من أجهزة الاستشعار، فسيتم مسح هذا FIFO وتتم إضافة حدث اكتمال التدفق للمستشعر المحدد فقط.

إذا كان المستشعر المحدد لا يحتوي على FIFO (لا يوجد تخزين مؤقت محتمل)، أو إذا كان FIFO فارغًا في وقت الاتصال، فيجب أن ينجح flush() ويرسل حدث تدفق كامل لهذا المستشعر. وينطبق هذا على جميع أجهزة الاستشعار بخلاف أجهزة الاستشعار ذات الطلقة الواحدة.

إذا تم استدعاء الدالة flush() ‎ لمستشعر اللقطة الواحدة، فيجب أن تقوم flush() بإرجاع BAD_VALUE وعدم إنشاء حدث تدفق كامل.

كتابة أحداث الاستشعار إلى FMQ

يتم استخدام Event FMQ بواسطة Sensors HAL لدفع أحداث المستشعر إلى إطار عمل مستشعر Android.

إن Event FMQ عبارة عن FMQ متزامن، مما يعني أن أي محاولة لكتابة المزيد من الأحداث إلى FMQ أكبر من المساحة المتوفرة ستؤدي إلى فشل الكتابة. في مثل هذه الحالة، يجب أن يحدد HAL ما إذا كان سيتم كتابة مجموعة الأحداث الحالية كمجموعتين أصغر من الأحداث أو كتابة كافة الأحداث معًا عند توفر مساحة كافية.

عندما تقوم طبقة ترحيل أجهزة الاستشعار بكتابة العدد المطلوب من أحداث المستشعر إلى حدث FMQ، يجب على طبقة ترحيل أجهزة الاستشعار إخطار إطار العمل بأن الأحداث جاهزة عن طريق كتابة بت EventQueueFlagBits::READ_AND_PROCESS إلى وظيفة EventFlag::wake الخاصة بـ Event FMQ. يمكن إنشاء EventFlag من Event FMQ باستخدام EventFlag::createEventFlag ووظيفة getEventFlagWord() الخاصة بـ Event FMQ.

تدعم أجهزة الاستشعار AIDL HAL كلاً من write writeBlocking في حدث FMQ. يوفر التنفيذ الافتراضي مرجعًا لاستخدام write . إذا تم استخدام وظيفة writeBlocking ، فيجب تعيين علامة readNotification على EventQueueFlagBits::EVENTS_READ ، والتي يتم تعيينها بواسطة إطار العمل عندما يقرأ الأحداث من Event FMQ. يجب تعيين علامة إعلام الكتابة على EventQueueFlagBits::READ_AND_PROCESS ، والتي تُعلم إطار العمل بأن الأحداث قد تمت كتابتها إلى Event FMQ.

أحداث WAKE_UP

أحداث WAKE_UP هي أحداث استشعار تتسبب في تنبيه معالج التطبيق (AP) والتعامل مع الحدث على الفور. عندما تتم كتابة حدث WAKE_UP إلى Event FMQ، يجب على أجهزة الاستشعار HAL تأمين قفل التنبيه لضمان بقاء النظام نشطًا حتى يتمكن إطار العمل من التعامل مع الحدث. عند تلقي حدث WAKE_UP ، يقوم إطار العمل بتأمين قفل التنشيط الخاص به، مما يسمح لأجهزة الاستشعار HAL بتحرير قفل التنشيط الخاص به. للمزامنة عندما تقوم أجهزة الاستشعار HAL بتحرير قفل التنشيط الخاص بها، استخدم Wake Lock FMQ.

يجب أن تقوم أجهزة الاستشعار HAL بقراءة Wake Lock FMQ لتحديد عدد أحداث WAKE_UP التي قام إطار العمل بمعالجتها. يجب أن تقوم طبقة HAL بتحرير قفل التنبيه الخاص بها لأحداث WAKE_UP فقط إذا كان العدد الإجمالي لأحداث WAKE_UP التي لم تتم معالجتها يساوي صفرًا. بعد التعامل مع أحداث المستشعر، يحسب إطار العمل عدد الأحداث التي تم وضع علامة عليها كأحداث WAKE_UP ويكتب هذا الرقم مرة أخرى إلى Wake Lock FMQ.

يقوم الإطار بتعيين إشعار الكتابة WakeLockQueueFlagBits::DATA_WRITTEN على Wake Lock FMQ عندما يكتب البيانات إلى Wake Lock FMQ.

أجهزة الاستشعار الديناميكية

المستشعرات الديناميكية هي مستشعرات ليست فعليًا جزءًا من الجهاز ولكن يمكن استخدامها كمدخل للجهاز، مثل لوحة الألعاب المزودة بمقياس تسارع.

عندما يتم توصيل مستشعر ديناميكي، يجب استدعاء وظيفة onDynamicSensorConnected في ISensorsCallback من طبقة أجهزة الاستشعار HAL. يقوم هذا بإعلام إطار عمل المستشعر الديناميكي الجديد ويسمح بالتحكم في المستشعر من خلال الإطار واستهلاك أحداث المستشعر من قبل العملاء.

وبالمثل، عند قطع اتصال المستشعر الديناميكي، يجب استدعاء وظيفة onDynamicSensorDisconnected في ISensorsCallback حتى يتمكن الإطار من إزالة أي مستشعر لم يعد متاحًا.

قناة مباشرة

القناة المباشرة هي طريقة تشغيل تتم فيها كتابة أحداث المستشعر إلى ذاكرة محددة بدلاً من حدث FMQ لتجاوز Android Sensors Framework. يجب على العميل الذي يسجل قناة مباشرة أن يقرأ أحداث المستشعر مباشرة من الذاكرة التي تم استخدامها لإنشاء القناة المباشرة ولن يستقبل أحداث المستشعر من خلال إطار العمل. تشبه وظيفة configDirectReport() وظيفة batch() للتشغيل العادي وتقوم بتكوين قناة التقرير المباشر.

تعمل الدالتان registerDirectChannel() و unregisterDirectChannel() على إنشاء قناة مباشرة جديدة أو تدميرها.

وسائط التشغيل

تسمح وظيفة setOperationMode() للإطار بتكوين المستشعر بحيث يمكن للإطار إدخال بيانات المستشعر في المستشعر. وهذا مفيد للاختبار، خاصة للخوارزميات الموجودة أسفل الإطار.

عادةً ما يتم استخدام وظيفة injectSensorData() لدفع المعلمات التشغيلية إلى أجهزة الاستشعار HAL. يمكن أيضًا استخدام الوظيفة لإدخال أحداث المستشعر في مستشعر معين.

تصديق

للتحقق من صحة تنفيذك لـ Sensors HAL، قم بتشغيل اختبارات CTS وVTS الخاصة بالمستشعر.

اختبارات سي تي إس

توجد اختبارات مستشعر CTS في كل من اختبارات CTS الآلية وتطبيق CTS Verifier اليدوي.

توجد الاختبارات الآلية في cts/tests/sensor/src/android/hardware/cts . تتحقق هذه الاختبارات من الوظائف القياسية لأجهزة الاستشعار، مثل تنشيط أجهزة الاستشعار، والتجميع، ومعدلات أحداث أجهزة الاستشعار.

توجد اختبارات CTS Verifier في cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors . تتطلب هذه الاختبارات إدخالاً يدويًا من مشغل الاختبار وتضمن قيام المستشعرات بالإبلاغ عن قيم دقيقة.

يعد اجتياز اختبارات CTS أمرًا بالغ الأهمية لضمان أن الجهاز قيد الاختبار يلبي جميع متطلبات CDD.

اختبارات VTS

توجد اختبارات VTS لأجهزة الاستشعار AIDL HAL في الأجهزة/الواجهات/أجهزة الاستشعار/aidl/vts/ . تضمن هذه الاختبارات تنفيذ HAL لأجهزة الاستشعار بشكل صحيح وأن جميع المتطلبات داخل ISensors.aidl و ISensorsCallback.aidl قد تم استيفاؤها بشكل صحيح.

تهيئة HAL

يجب دعم وظيفة initialize() لإنشاء FMQs بين إطار العمل وHAL.

فضح أجهزة الاستشعار المتاحة

في Sensors AIDL HAL، يجب أن تقوم الدالة getSensorsList() بإرجاع نفس القيمة أثناء تشغيل جهاز واحد، حتى عبر إعادة تشغيل Sensors HAL. أحد المتطلبات الجديدة لوظيفة getSensorsList() هو أنه يجب أن تُرجع نفس القيمة أثناء تشغيل جهاز واحد، حتى عند إعادة تشغيل أجهزة الاستشعار HAL. يسمح هذا لإطار العمل بمحاولة إعادة إنشاء اتصالات المستشعر في حالة إعادة تشغيل خادم النظام. يمكن أن تتغير القيمة التي يتم إرجاعها بواسطة getSensorsList() بعد قيام الجهاز بإعادة التشغيل.

كتابة أحداث الاستشعار إلى FMQ

بدلاً من انتظار استدعاء poll() ، في شريحة AIDL للمستشعرات، يجب على طبقة HAL للمستشعرات كتابة أحداث المستشعر بشكل استباقي إلى Event FMQ عندما تكون أحداث المستشعر متاحة. يعد HAL أيضًا مسؤولاً عن كتابة البتات الصحيحة إلى EventFlag لقراءة FMQ داخل إطار العمل.

أحداث WAKE_UP

في Sensors HAL 1.0، تمكنت HAL من تحرير قفل التنشيط الخاص بها لأي حدث WAKE_UP في أي استدعاء لاحق إلى poll() بعد نشر WAKE_UP إلى poll() لأن هذا يشير إلى أن إطار العمل قد عالج جميع أحداث المستشعر وحصل على قفل التنبيه، إذا لزم الأمر. نظرًا لأنه في أجهزة الاستشعار AIDL HAL، لم يعد يتم إخطار HAL عندما يقوم إطار العمل بمعالجة الأحداث المكتوبة إلى FMQ، فإن Wake Lock FMQ يسمح لإطار العمل بالاتصال بـ HAL عندما يتعامل مع أحداث WAKE_UP .

في أجهزة الاستشعار AIDL HAL، يجب أن يبدأ قفل التنبيه المضمون بواسطة أجهزة الاستشعار HAL لأحداث WAKE_UP بـ SensorsHAL_WAKEUP .

أجهزة الاستشعار الديناميكية

تم إرجاع المستشعرات الديناميكية باستخدام وظيفة poll() في Sensors HAL 1.0. تتطلب أجهزة الاستشعار AIDL HAL أن يتم استدعاء onDynamicSensorsConnected و onDynamicSensorsDisconnected في ISensorsCallback عندما تتغير اتصالات المستشعر الديناميكي. تتوفر عمليات الاسترجاعات هذه كجزء من مؤشر ISensorsCallback الذي يتم توفيره من خلال وظيفة initialize() .

وسائط التشغيل

يجب دعم وضع DATA_INJECTION لأجهزة استشعار WAKE_UP .

دعم متعدد HAL

تدعم أجهزة الاستشعار AIDL HAL تقنية HAL المتعددة باستخدام إطار عمل أجهزة الاستشعار Multi-HAL . للحصول على تفاصيل التنفيذ، راجع النقل من أجهزة الاستشعار HAL 2.1 .