«لایه انتزاعی سختافزار حسگرها» (HAL) رابط بین چارچوب حسگر Android و حسگرهای دستگاه، مثل شتابسنج یا ژیروسکوپ است. «لایه انتزاعی سختافزار حسگرها» عملکردهایی را تعریف میکند که باید پیادهسازی شوند تا چارچوب بتواند حسگرها را کنترل کند.
Sensors HAL 2.0 در Android 10 و بالاتر برای دستگاههای جدید و ارتقایافته دردسترس است. Sensors HAL 2.0 براساس Sensors HAL 1.0 است اما چند تفاوت کلیدی دارد که مانع سازگاری آن با نسخههای قدیمی میشود. Sensors HAL 2.0 از صفهای پیام سریع (FMQ) برای ارسال رویدادهای حسگر از HAL به چارچوب حسگر Android استفاده میکند.
Sensors HAL 2.1 در Android 11 و بالاتر
برای دستگاههای جدید و ارتقایافته دردسترس است. Sensors HAL 2.1 تکراری از Sensors HAL 2.0 است که نوع حسگر
HINGE_ANGLE
را آشکار میکند و روشهای مختلفی را برای پذیرفتن نوع HINGE_ANGLE بهروزرسانی میکند.
میانای HAL 2.1
منبع اصلی مستندات Sensors HAL 2.1 در تعریف HAL در
hardware/interfaces/sensors/2.1/ISensors.hal است.
اگر بین الزامات این صفحه و ISensors.hal تضادی وجود داشته باشد،
از الزامات ISensors.hal استفاده کنید.
میانای HAL 2.0
منبع اصلی مستندات برای Sensors HAL 2.0 در تعریف HAL در
hardware/interfaces/sensors/2.0/ISensors.hal قرار دارد.
اگر بین الزامات این صفحه و ISensors.hal تضادی وجود داشته باشد،
از الزامات ISensors.hal استفاده کنید.
پیادهسازی «لایه انتزاعی سختافزار حسگرها» نسخه ۲.۰ و نسخه ۲.۱
برای پیادهسازی Sensors HAL 2.0 یا 2.1، یک شیء باید میانای ISensors را گسترش دهد و همه توابع تعریفشده در 2.0/ISensors.hal یا 2.1/ISensors.hal را پیادهسازی کند.
مقداردهی اولیه HAL
«لایه انتزاع سختافزاری حسگرها» باید قبلاز استفاده توسط چارچوب حسگر Android مقداردهی اولیه شود. چارچوب تابع initialize() را برای HAL 2.0 و تابع initialize_2_1() را برای HAL 2.1 فرا میخواند تا سه پارامتر را به
Sensors HAL ارائه دهد: دو توصیفگر FMQ و یک اشارهگر به شیء ISensorsCallback
«لایه انتزاعی سختافزار» از اولین توصیفگر برای ایجاد Event FMQ استفاده میکند که برای نوشتن رویدادهای حسگر
در چارچوب استفاده میشود. HAL از توصیفگر دوم برای ایجاد Wake Lock FMQ استفاده میکند که برای همگامسازی زمانی که HAL قفل بیدارباش خود را برای رویدادهای حسگر WAKE_UP آزاد میکند، استفاده میشود. «لایه انتزاع سختافزار» باید اشارهگری به شیء ISensorsCallback ذخیره کند تا
هر تابع برگشتی لازم بتواند فراخوانی شود.
تابع initialize() یا initialize_2_1() باید اولین تابعی باشد که هنگام
مقداردهی اولیه «لایه انتزاع سختافزاری حسگرها» فراخوانی میشود.
نمایش حسگرهای دردسترس
برای دریافت فهرستی از همه حسگرهای ثابت دردسترس در دستگاه، از تابع
getSensorsList() در HAL 2.0 و تابع getSensorsList_2_1() در
HAL 2.1 استفاده کنید. این عملکرد فهرستی از حسگرها را برمیگرداند که هرکدام بهطور منحصربهفرد با
دستگیره خود شناسایی میشوند. وقتی فرایند میزبان Sensors HAL بازراهاندازی میشود، نام کاربری حسگر نباید تغییر کند. دستهها ممکن است در بازراهاندازیهای دستگاه و
بازراهاندازیهای سرور سیستم تغییر کنند.
اگر چند حسگر نوع حسگر و ویژگی بیدار شدن یکسانی داشته باشند،
اولین حسگر در فهرست حسگر پیشفرض نامیده میشود و به برنامههایی که از
عملکرد getDefaultSensor(int sensorType, bool wakeUp)
استفاده میکنند برگردانده میشود.
پایداری فهرست حسگرها
پساز بازراهاندازی Sensors HAL، اگر دادههای برگشتی از getSensorsList() یا
getSensorsList_2_1() در مقایسه با فهرست حسگر
بازیابیشده قبلاز بازراهاندازی تغییر قابلتوجهی را نشان دهد، چارچوب بازراهاندازی زمان اجرای
Android را راهاندازی میکند. تغییرات قابلتوجه در فهرست حسگر شامل مواردی میشود که حسگری با دستگیره معین وجود ندارد یا ویژگیهای آن تغییر کرده است، یا حسگرهای جدیدی معرفی شده است. اگرچه راهاندازی مجدد زمان اجرای Android برای کاربر اختلال ایجاد میکند، اما لازم است زیرا چارچوب Android دیگر نمیتواند قرارداد میانای برنامهسازی کاربردی Android را که حسگرهای ایستا (غیرپویا) درطول عمر برنامه تغییر نمیکنند برآورده کند. این امر همچنین ممکن است مانع از برقراری مجدد درخواستهای حسگر فعال توسط چارچوب شود. بنابراین، به فروشندگان HAL توصیه میشود
از تغییرات قابلاجتناب در فهرست حسگرها جلوگیری کنند.
برای اطمینان از پایداری دستههای حسگر، HAL باید بهطور قطعی یک حسگر فیزیکی معین در دستگاه را به دسته آن نگاشت کند. اگرچه هیچ پیادهسازی خاصی توسط میانای Sensors HAL الزامی نشده است، توسعهدهندگان گزینههای متعددی برای برآورده کردن این الزام دارند.
برای مثال، فهرست حسگر را میتوان بااستفاده از ترکیبی از مشخصههای ثابت هر حسگر، مثل فروشنده، مدل، و نوع حسگر، مرتب کرد. گزینه دیگر به این واقعیت متکی است که مجموعه حسگرهای ثابت دستگاه در سختافزار ثابت است، بنابراین HAL باید بداند چه زمانی همه حسگرهای موردانتظار مقداردهی اولیه را قبلاز بازگشت از getSensorsList() یا getSensorsList_2_1() تکمیل کردهاند. این فهرست حسگرهای
موردانتظار میتواند در باینری HAL گردآوری شود یا در
فایل پیکربندی در سیستم فایل ذخیره شود، و از ترتیب نمایش میتواند
برای استخراج دستههای پایدار استفاده شود. اگرچه بهترین راهکار به جزئیات پیادهسازی خاص HAL شما بستگی دارد، اما الزام اصلی این است که دستههای حسگر درطول راهاندازی مجدد HAL تغییر نکنند.
پیکربندی حسگرها
پیشاز فعال شدن حسگر، حسگر باید با دوره نمونهبرداری و حداکثر تأخیر گزارشدهی بااستفاده از تابع batch() پیکربندی شود.
حسگر باید بتواند در هرزمانی بااستفاده از batch() بدون ازدست دادن دادههای حسگر دوباره پیکربندی شود.
دوره نمونهگیری
دوره نمونهگیری براساس نوع حسگری که پیکربندی میشود معنای متفاوتی دارد:
- پیوسته: رویدادهای حسگر با نرخ پیوسته تولید میشوند.
- On-change: رویدادها سریعتر از دوره نمونهبرداری تولید نمیشوند و اگر مقدار اندازهگیریشده تغییر نکند، ممکن است با نرخی کندتر از دوره نمونهبرداری تولید شوند.
- تکضرب: دوره نمونهگیری نادیده گرفته میشود.
- ویژه: برای جزئیات بیشتر، انواع حسگر را ببینید.
برای آشنایی با تعامل بین دوره نمونهگیری و حالتهای گزارشدهی حسگر، به حالتهای گزارشدهی مراجعه کنید.
حداکثر تأخیر گزارشدهی
حداکثر تأخیر گزارشدهی حداکثر زمان برحسب نانوثانیه را تعیین میکند که رویدادها میتوانند در آن تأخیر داشته باشند و در سختافزار FIFO ذخیره شوند، سپس ازطریق HAL درحالیکه SoC بیدار است در Event FMQ نوشته شوند.
مقدار صفر نشان میدهد که رویدادها باید بهمحض اندازهگیری گزارش شوند، یا بهطور کامل از FIFO صرفنظر شود، یا بهمحض اینکه یک رویداد از حسگر در FIFO وجود داشته باشد، FIFO خالی شود.
برای مثال، شتابسنجی که در ۵۰ هرتز با بیشینه تأخیر گزارشدهی صفر فعال شده است، وقتی SoC بیدار است، ۵۰ بار در ثانیه وقفههایی را راهاندازی میکند.
وقتی بیشینه تأخیر گزارشدهی بزرگتر از صفر باشد، رویدادهای حسگر لازم نیست بهمحض شناسایی گزارش شوند. رویدادها میتوانند بهطور موقت در سختافزار FIFO ذخیره شوند و بهصورت دستهای گزارش شوند، بهشرطی که هیچ رویدادی بیشاز حداکثر تأخیر گزارشدهی تأخیر نداشته باشد. همه رویدادهای پساز دسته قبلی بهطور همزمان ضبط و برگردانده میشوند. این کار تعداد وقفههای ارسالی به SoC را کاهش میدهد و به SoC اجازه میدهد درحالیکه حسگر درحال ضبط و دستهبندی دادهها است به حالت کممصرفتری برود.
هر رویداد یک مُهر زمان منسوب به خود دارد. تأخیر در زمان گزارش رویداد نباید بر مُهر زمان رویداد تأثیر بگذارد. مهر زمان باید دقیق باشد و با زمانی که رویداد بهصورت فیزیکی رخ داده است مطابقت داشته باشد، نه زمانی که گزارش شده است.
برای اطلاعات بیشتر و الزامات گزارش رویدادهای حسگر با بیشینه تأخیر گزارش غیرصفر، به دستهای کردن مراجعه کنید.
فعال کردن حسگرها
این چارچوب بااستفاده از تابع activate() حسگرها را فعال و غیرفعال میکند.
پیشاز فعال کردن حسگر، چارچوب باید ابتدا حسگر را بااستفاده از batch() پیکربندی کند.
پساز غیرفعال شدن حسگر، رویدادهای حسگر اضافی از آن حسگر نباید در «صف پیام رویداد» نوشته شود.
حسگرهای فلاش
اگر حسگری برای دستهای کردن دادههای حسگر پیکربندی شده باشد، چارچوب میتواند با فراخوانی flush()،
حسگر رویدادهای دستهای را مجبور به تخلیه فوری کند. این کار باعث میشود رویدادهای حسگر دستهای برای دستگیره حسگر مشخصشده بلافاصله در FMQ رویداد نوشته شود. «لایه انتزاعی سختافزار حسگرها» باید رویداد تکمیل تخلیه را به انتهای رویدادهای حسگر که درنتیجه فراخوانی flush() نوشته شدهاند اضافه کند.
شستشو بهصورت غیرهمگام انجام میشود (یعنی این تابع باید بلافاصله برگردد). اگر پیادهسازی از یک FIFO برای چند حسگر استفاده کند، آن FIFO پاکسازی میشود و رویداد تکمیل پاکسازی فقط برای حسگر مشخصشده اضافه میشود.
اگر حسگر مشخصشده FIFO نداشته باشد (بافر کردن ممکن نباشد)، یا اگر FIFO در زمان تماس خالی باشد، flush() باید همچنان موفق شود و رویداد تکمیل پاکسازی را برای آن حسگر ارسال کند. این مورد برای همه حسگرها بهجز حسگرهای تکشات اعمال میشود.
اگر flush() برای حسگر یکباره فراخوانده شود، flush() باید
BAD_VALUE را برگرداند و رویداد تکمیل تخلیه تولید نکند.
نوشتن رویدادهای حسگر در FMQ
«صف پیام رویداد» توسط «لایه انتزاعی سختافزار حسگرها» برای انتقال رویدادهای حسگر به چارچوب حسگر Android استفاده میشود.
«صف پیام سریع رویداد» یک «صف پیام سریع» همزمانسازیشده است، به این معنی که هرگونه تلاش برای نوشتن رویدادهای بیشتر در «صف پیام سریع» نسبتبه فضای دردسترس منجر به نوشتن ناموفق میشود. در چنین مواردی، «لایه انتزاع سختافزار» باید تعیین کند که آیا مجموعه فعلی رویدادها را بهعنوان دو گروه کوچکتر از رویدادها بنویسد یا وقتی فضای کافی دردسترس است همه رویدادها را با هم بنویسد.
وقتی «لایه انتزاعی سختافزار حسگرها» تعداد موردنظر رویدادهای حسگر را در
«صف پیام سریع رویداد» نوشت، «لایه انتزاعی سختافزار حسگرها» باید با نوشتن
بیت EventQueueFlagBits::READ_AND_PROCESS در تابع
EventFlag::wake «صف پیام سریع رویداد»، به چارچوب اطلاع دهد که رویدادها آمادهاند. EventFlag را میتوان از Event FMQ
بااستفاده از EventFlag::createEventFlag و تابع getEventFlagWord()
در Event FMQ ایجاد کرد.
Sensors HAL 2.0/2.1 از write و writeBlocking در «صف پیام سریع رویداد» پشتیبانی میکند.
پیادهسازی پیشفرض مرجعی برای استفاده از write ارائه میدهد. اگر از تابع
writeBlocking استفاده شود، پرچم readNotification باید روی
EventQueueFlagBits::EVENTS_READ تنظیم شود، که چارچوب هنگام خواندن
رویدادها از Event FMQ آن را تنظیم میکند. پرچم اعلان نوشتن باید روی
EventQueueFlagBits::READ_AND_PROCESS تنظیم شود، که به چارچوب اطلاع میدهد رویدادها
در Event FMQ نوشته شدهاند.
رویدادهای WAKE_UP
رویدادهای WAKE_UP رویدادهای حسگری هستند که باعث میشوند پردازنده برنامهها (AP)
بیدار شود و فوراً رویداد را مدیریت کند. هرگاه رویداد WAKE_UP نوشته شود
در «صف پیام سریع رویداد»، «لایه انتزاع سختافزاری حسگرها» باید قفل بیداری را ایمن کند تا مطمئن شود
سیستم تا زمانی که چارچوب بتواند رویداد را مدیریت کند بیدار میماند. با دریافت رویداد WAKE_UP، چارچوب قفل بیداری خود را ایمن میکند و به «لایه انتزاعی سختافزار حسگرها» اجازه میدهد قفل بیداری خود را آزاد کند. برای همگامسازی کردن زمانی که Sensors HAL
قفل بیداری را آزاد میکند، از Wake Lock FMQ استفاده کنید.
Sensors HAL باید Wake Lock FMQ را بخواند تا تعداد رویدادهای WAKE_UP را که چارچوب مدیریت کرده است تعیین کند. HAL باید قفل بیدارباش خود را فقط برای رویدادهای WAKE_UP آزاد کند،
اگر تعداد کل رویدادهای WAKE_UP مدیریتنشده صفر باشد.
چارچوب پساز مدیریت رویدادهای حسگر، تعداد رویدادهایی را که بهعنوان رویدادهای WAKE_UP علامتگذاری شدهاند میشمارد و این تعداد را در «صف پیام سریع قفل بیداری» مینویسد.
چارچوب هرگاه دادهای را در Wake Lock FMQ مینویسد، WakeLockQueueFlagBits::DATA_WRITTEN write
notification را در Wake Lock FMQ تنظیم میکند.
حسگرهای پویا
حسگرهای پویا حسگرهایی هستند که ازنظر فیزیکی بخشی از دستگاه نیستند اما میتوانند بهعنوان ورودی دستگاه استفاده شوند، مثل دسته بازی با شتابسنج.
وقتی حسگر پویا متصل باشد، تابع onDynamicSensorConnected در
ISensorsCallback باید از «لایه انتزاع سختافزاری حسگرها» فراخوانده شود. این کار به چارچوب حسگر پویای جدید اطلاع میدهد و اجازه میدهد حسگر ازطریق چارچوب کنترل شود و رویدادهای حسگر توسط کلاینتها مصرف شود.
بههمین ترتیب، وقتی حسگر پویایی قطع میشود، باید تابع
onDynamicSensorDisconnected در ISensorsCallback فراخوانی شود تا چارچوب بتواند هر حسگری را که دیگر دردسترس نیست بردارد.
کانال مستقیم
کانال مستقیم روشی برای عملکرد است که در آن رویدادهای حسگر بهجای «صف پیام رویداد» در حافظه خاصی نوشته میشود و از «چارچوب حسگرهای Android» عبور میکند. کارخواهی که کانال مستقیمی را ثبت میکند باید رویدادهای حسگر را
مستقیماً از حافظهای که برای ایجاد کانال مستقیم استفاده شده است بخواند و
رویدادهای حسگر را ازطریق چارچوب دریافت نخواهد کرد. عملکرد configDirectReport()
مشابه batch() برای عملکرد عادی است و کانال گزارش مستقیم را پیکربندی میکند.
تابعهای registerDirectChannel() و unregisterDirectChannel() کانال مستقیم جدیدی را ایجاد یا تخریب میکنند.
حالتهای عملکرد
تابع setOperationMode() به چارچوب اجازه میدهد حسگر را پیکربندی کند
تا چارچوب بتواند دادههای حسگر را به حسگر تزریق کند. این برای آزمایش کردن مفید است، بهویژه برای الگوریتمهایی که زیر چارچوب وجود دارند.
تابع injectSensorData() در HAL 2.0 و تابع injectSensorsData_2_1() در HAL 2.0 معمولاً برای ارسال پارامترهای عملیاتی به Sensors 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
آزمایشهای VTS برای Sensors HAL 2.0 در
hardware/interfaces/sensors/2.0/vts قرار دارد.
آزمایشهای VTS برای Sensors HAL 2.1 در
hardware/interfaces/sensors/2.1/vts قرار دارد.
این آزمایشها تضمین میکنند که Sensors HAL بهدرستی پیادهسازی شده است و همه
الزامات ISensors.hal و ISensorsCallback.hal بهدرستی برآورده شدهاند.
ارتقا دادن به Sensors HAL 2.1 از 2.0
هنگام ارتقا به Sensors HAL 2.1 از 2.0، پیادهسازی HAL شما باید شامل
روشهای initialize_2_1()، getSensorsList_2_1()، و injectSensorsData_2_1()
بههمراه انواع HAL 2.1 باشد. این روشها باید همان
الزامات ذکرشده برای HAL 2.0 در بالا را داشته باشند.
ازآنجاییکه «سختافزارهای لایه انتزاعی» نسخه فرعی باید از همه عملکردهای «سختافزارهای لایه انتزاعی» قبلی پشتیبانی کنند، «سختافزارهای لایه انتزاعی» نسخه ۲.۱ باید از مقداردهی اولیه بهعنوان «سختافزارهای لایه انتزاعی» نسخه ۲.۰ پشتیبانی کنند. برای جلوگیری از پیچیدگی پشتیبانی از هر دو نسخه HAL، قویاً توصیه میشود از Multi-HAL 2.1 استفاده کنید.
برای نمونهای از نحوه پیادهسازی «لایه انتزاعی سختافزار حسگرها ۲.۱» خودتان، به Sensors.h مراجعه کنید.
ارتقا دادن از Sensors HAL 1.0 به 2.0
هنگام ارتقا دادن به Sensors HAL 2.0 از 1.0، مطمئن شوید پیادهسازی HAL شما الزامات زیر را برآورده میکند.
مقداردهی اولیه HAL
برای ایجاد FMQ بین چارچوب و HAL، باید از تابع initialize() پشتیبانی شود.
نمایش حسگرهای دردسترس
در Sensors HAL 2.0، تابع getSensorsList() باید مقدار یکسانی را
درطول یک بوت دستگاه برگرداند، حتی درصورت بازراهاندازی Sensors HAL. یکی از الزامات جدید تابع getSensorsList() این است که باید درطول
یک راهاندازی دستگاه، حتی درصورت بازراهاندازی «لایه انتزاع سختافزاری حسگرها»، مقدار یکسانی را برگرداند. این کار به چارچوب اجازه میدهد درصورت بازراهاندازی سرور سیستم، برای برقراری مجدد اتصالهای حسگر تلاش کند. مقدار برگشتی از getSensorsList() میتواند پساز بازراهاندازی دستگاه تغییر کند.
نوشتن رویدادهای حسگر در FMQ
بهجای اینکه منتظر بمانید poll() فراخوانی شود، در Sensors HAL 2.0، هرگاه رویدادهای حسگر دردسترس باشد، Sensors HAL باید بهصورت پیشکنشی رویدادهای حسگر را در Event FMQ بنویسد. «لایه انتزاع سختافزار» همچنین مسئول نوشتن بیتهای صحیح در
EventFlag است تا باعث خواندن FMQ در چارچوب شود.
رویدادهای WAKE_UP
در Sensors HAL 1.0، پساز ارسال WAKE_UP به poll()، در هر فراخوانی بعدی به poll()، HAL میتوانست قفل بیداری خود را برای هر رویداد WAKE_UP
آزاد کند زیرا این نشان میداد که چارچوب همه رویدادهای حسگر را پردازش کرده است و درصورت لزوم قفل بیداری را دریافت کرده است. زیرا در «لایه انتزاعی سختافزار حسگرها نسخه ۲.۰»،
لایه انتزاعی سختافزار دیگر نمیداند چارچوب چه زمانی رویدادهای نوشتهشده در
FMQ را پردازش کرده است، «FMQ قفل بیداری» به چارچوب اجازه میدهد وقتی
رویدادهای WAKE_UP را مدیریت کرد با لایه انتزاعی سختافزار ارتباط برقرار کند.
در Sensors HAL 2.0، قفل بیداری که Sensors HAL برای WAKE_UP رویداد ایمن کرده است باید با SensorsHAL_WAKEUP شروع شود.
حسگرهای پویا
حسگرهای پویا بااستفاده از تابع poll() در Sensors HAL 1.0 برگردانده شدند.
Sensors HAL 2.0 ایجاب میکند که هرگاه اتصالات حسگر پویا تغییر میکند، onDynamicSensorsConnected و onDynamicSensorsDisconnected در ISensorsCallback فراخوانی شوند. این توابع برگشتی بهعنوان بخشی از
اشارهگر ISensorsCallback که ازطریق تابع initialize() ارائه میشود دردسترس هستند.
حالتهای عملکرد
حالت DATA_INJECTION برای حسگرهای WAKE_UP باید در Sensors HAL
2.0 پشتیبانی شود.
پشتیبانی از Multi-HAL
Sensors HAL 2.0 و 2.1 بااستفاده از چارچوب Sensors Multi-HAL از چند HAL پشتیبانی میکنند. برای جزئیات پیادهسازی، انتقال از Sensors HAL 1.0 را ببینید.