لایه انتزاعی سخت افزاری حسگرها (HAL) رابط بین چارچوب حسگر اندروید و حسگرهای دستگاه مانند شتاب سنج یا ژیروسکوپ است. Sensors HAL عملکردهایی را تعریف می کند که باید پیاده سازی شوند تا به چارچوب اجازه دهد تا سنسورها را کنترل کند.
Sensors HAL 2.0 در Android 10 و بالاتر برای دستگاههای جدید و ارتقا یافته موجود است. سنسور HAL 2.0 مبتنی بر حسگر HAL 1.0 است اما چندین تفاوت کلیدی دارد که از سازگاری آن با عقب جلوگیری می کند. Sensors HAL 2.0 از صفهای پیام سریع (FMQ) برای ارسال رویدادهای حسگر از HAL به چارچوب حسگر Android استفاده میکند.
Sensors HAL 2.1 در Android 11 و بالاتر برای دستگاههای جدید و ارتقا یافته موجود است. سنسور HAL 2.1 تکرار سنسور 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
استفاده کنید.
سنسورهای HAL 2.0 و HAL 2.1 را پیاده سازی کنید
برای پیاده سازی Sensors HAL 2.0 یا 2.1، یک شی باید رابط ISensors
گسترش دهد و تمام توابع تعریف شده در 2.0/ISensors.hal
یا 2.1/ISensors.hal
را پیاده سازی کند.
HAL را راه اندازی کنید
Sensors HAL باید قبل از استفاده از چارچوب حسگر Android مقداردهی اولیه شود. این فریم ورک تابع initialize()
را برای HAL 2.0 و تابع initialize_2_1()
را برای HAL 2.1 فراخوانی می کند تا سه پارامتر به Sensors HAL ارائه کند: دو توصیفگر FMQ و یک اشاره گر به یک شی ISensorsCallback
.
HAL از اولین توصیفگر برای ایجاد رویداد FMQ استفاده می کند که برای نوشتن رویدادهای حسگر در چارچوب استفاده می شود. HAL از توصیفگر دوم برای ایجاد Wake Lock FMQ استفاده می کند که برای همگام سازی زمانی که HAL قفل wake خود را برای رویدادهای حسگر WAKE_UP
آزاد می کند، استفاده می کند. HAL باید یک اشاره گر را در شی ISensorsCallback
ذخیره کند تا هر گونه توابع برگشت تماس لازم فراخوانی شود.
تابع initialize()
یا initialize_2_1()
باید اولین تابعی باشد که هنگام مقداردهی اولیه Sensors HAL فراخوانی می شود.
سنسورهای موجود را در معرض دید قرار دهید
برای دریافت لیستی از تمام حسگرهای استاتیک موجود در دستگاه، از تابع getSensorsList()
در HAL 2.0 و تابع getSensorsList_2_1()
در HAL 2.1 استفاده کنید. این تابع فهرستی از حسگرها را برمیگرداند که هر کدام به طور منحصربهفرد توسط دستهاش شناسایی میشوند. هنگام راه اندازی مجدد فرآیند میزبانی سنسور HAL، دسته یک حسگر معین نباید تغییر کند. ممکن است دستهها در بین راهاندازی مجدد دستگاه و راهاندازی مجدد سرور سیستم تغییر کنند.
اگر چندین حسگر از یک نوع حسگر و ویژگی بیدار شدن استفاده می کنند، اولین حسگر در لیست حسگر پیش فرض نامیده می شود و به برنامه هایی که از تابع getDefaultSensor(int sensorType, bool wakeUp)
استفاده می کنند، بازگردانده می شود.
لیست ثبات سنسورها
پس از راهاندازی مجدد Sensors HAL، اگر دادههای بازگردانده شده توسط getSensorsList()
یا getSensorsList_2_1()
نشان دهنده تغییر قابل توجهی در مقایسه با لیست حسگرهای بازیابی شده قبل از راهاندازی مجدد باشد، فریم ورک باعث راهاندازی مجدد زمان اجرا اندروید میشود. تغییرات قابل توجه در لیست حسگرها شامل مواردی است که سنسوری با یک دسته مشخص وجود ندارد یا ویژگیهای آن تغییر کرده است یا سنسورهای جدیدی معرفی میشوند. اگرچه راهاندازی مجدد زمان اجرا اندروید برای کاربر اختلال ایجاد میکند، اما لازم است زیرا چارچوب Android دیگر نمیتواند با قرارداد API Android که حسگرهای ایستا (غیر پویا) در طول عمر برنامه تغییر نمیکنند، مطابقت داشته باشد. این همچنین ممکن است مانع از ایجاد مجدد درخواستهای حسگر فعال توسط برنامهها شود. بنابراین، به فروشندگان HAL توصیه می شود از تغییرات قابل اجتناب لیست حسگرها جلوگیری کنند.
برای اطمینان از پایداری دستههای حسگر، HAL باید به طور قطعی یک حسگر فیزیکی معین در دستگاه را به دسته آن ترسیم کند. اگرچه هیچ پیاده سازی خاصی توسط رابط Sensors HAL اجباری نشده است، توسعه دهندگان تعدادی گزینه برای برآورده کردن این نیاز در دسترس دارند.
به عنوان مثال، فهرست حسگرها را می توان با استفاده از ترکیبی از ویژگی های ثابت هر سنسور، مانند فروشنده، مدل، و نوع حسگر مرتب کرد. گزینه دیگر متکی بر این واقعیت است که مجموعه حسگرهای استاتیک دستگاه در سخت افزار ثابت است، بنابراین HAL باید بداند که همه حسگرهای مورد انتظار قبل از بازگشت از getSensorsList()
یا getSensorsList_2_1()
زمان اولیه سازی را کامل کرده اند. این لیست از حسگرهای مورد انتظار را می توان در باینری HAL کامپایل کرد یا در یک فایل پیکربندی در سیستم فایل ذخیره کرد و از ترتیب ظاهری می توان برای استخراج دسته های پایدار استفاده کرد. اگرچه بهترین راهحل به جزئیات پیادهسازی خاص HAL شما بستگی دارد، اما شرط اصلی این است که دستههای حسگر در راهاندازی مجدد HAL تغییر نکنند.
سنسورها را پیکربندی کنید
قبل از اینکه حسگر فعال شود، حسگر باید با یک دوره نمونهبرداری و حداکثر تأخیر گزارش با استفاده از تابع batch()
پیکربندی شود.
یک حسگر باید بتواند در هر زمان با استفاده از batch()
بدون از دست رفتن دادههای حسگر پیکربندی مجدد شود.
دوره نمونه برداری
دوره نمونه برداری بر اساس نوع سنسوری که در حال پیکربندی است، معنای متفاوتی دارد:
- پیوسته: رویدادهای حسگر با سرعت پیوسته تولید می شوند.
- در حال تغییر: رویدادها سریعتر از دوره نمونهگیری ایجاد نمیشوند و اگر مقدار اندازهگیری شده تغییر نکند، ممکن است با سرعت کمتر از دوره نمونهبرداری ایجاد شوند.
- تک شات: دوره نمونه برداری نادیده گرفته می شود.
- ویژه: برای جزئیات بیشتر، انواع سنسور را ببینید.
برای آشنایی با تعامل بین دوره نمونه برداری و حالت های گزارش سنسور، به حالت های گزارش مراجعه کنید.
حداکثر تأخیر گزارش
حداکثر تأخیر گزارش حداکثر زمانی را بر حسب نانوثانیه تنظیم میکند که رویدادها میتوانند به تأخیر افتاده و در FIFO سختافزاری ذخیره شوند، قبل از اینکه از طریق HAL روی رویداد FMQ نوشته شوند، در حالی که SoC بیدار است.
مقدار صفر نشان می دهد که رویدادها باید به محض اندازه گیری گزارش شوند، یا به طور کلی از FIFO صرفنظر کنید، یا به محض اینکه یک رویداد از سنسور در FIFO وجود دارد، FIFO را خالی کنید.
برای مثال، یک شتابسنج فعال در فرکانس 50 هرتز با حداکثر تأخیر گزارش صفر، هنگامی که SoC بیدار است، 50 بار در ثانیه قطع میشود.
وقتی حداکثر تأخیر گزارش دهی بیشتر از صفر است، رویدادهای حسگر به محض شناسایی نیازی به گزارش ندارند. رویدادها را میتوان بهطور موقت در سختافزار FIFO ذخیره کرد و به صورت دستهای گزارش کرد، تا زمانی که هیچ رویدادی بیش از حداکثر تأخیر گزارش به تأخیر نیفتد. همه رویدادها از دسته قبلی به یکباره ضبط و بازگردانده می شوند. این کار تعداد وقفههای ارسال شده به SoC را کاهش میدهد و به SoC اجازه میدهد تا زمانی که سنسور در حال جمعآوری و جمعآوری دادهها است، به حالت کممصرف تغییر کند.
هر رویداد دارای یک مهر زمانی مرتبط با آن است. به تأخیر انداختن زمانی که یک رویداد در آن گزارش میشود نباید روی مهر زمانی رویداد تأثیر بگذارد. مهر زمانی باید دقیق باشد و مطابق با زمانی باشد که رویداد از نظر فیزیکی رخ داده است، نه زمانی که گزارش شده است.
برای اطلاعات بیشتر و الزامات مربوط به گزارش رویدادهای حسگر با حداکثر تأخیر گزارش غیرصفر، به دسته بندی مراجعه کنید.
سنسورها را فعال کنید
چارچوب با استفاده از تابع activate()
حسگرها را فعال و غیرفعال می کند. قبل از فعال کردن یک سنسور، چارچوب باید ابتدا حسگر را با استفاده از batch()
پیکربندی کند.
پس از غیرفعال شدن یک سنسور، رویدادهای حسگر اضافی از آن سنسور نباید در Event FMQ نوشته شود.
سنسورهای فلاش
اگر یک حسگر برای دستهای دادههای حسگر پیکربندی شده باشد، چارچوب میتواند با فراخوانی flush()
خیساندن فوری رویدادهای حسگر دستهای را مجبور کند. این باعث می شود که رویدادهای حسگر دسته ای برای دسته سنسور مشخص شده بلافاصله در Event FMQ نوشته شود. Sensors HAL باید یک رویداد flush full را به انتهای رویدادهای حسگر که در نتیجه فراخوانی flush()
نوشته شده اند اضافه کند.
فلاش به صورت ناهمزمان اتفاق می افتد (یعنی این تابع باید فوراً برگردد). اگر پیاده سازی از یک FIFO برای چندین سنسور استفاده کند، آن FIFO فلاش می شود و رویداد flush full فقط برای سنسور مشخص شده اضافه می شود.
اگر حسگر مشخص شده FIFO ندارد (بدون بافر امکان پذیر نیست)، یا اگر FIFO در زمان تماس خالی بود، flush()
همچنان باید موفق شود و یک رویداد flush کامل برای آن سنسور ارسال کند. این برای همه سنسورها غیر از سنسورهای تک شات صدق می کند.
اگر flush()
برای یک سنسور یک شات فراخوانی شود، آنگاه flush()
باید BAD_VALUE
را برگرداند و یک رویداد flush کامل ایجاد نکند.
رویدادهای حسگر را در FMQ بنویسید
رویداد FMQ توسط Sensors HAL برای فشار دادن رویدادهای حسگر به چارچوب حسگر Android استفاده می شود.
رویداد FMQ یک FMQ همگامسازی شده است، به این معنی که هر تلاشی برای نوشتن رویدادهای بیشتر از فضای موجود در FMQ منجر به نوشتن ناموفق میشود. در چنین حالتی، HAL باید تعیین کند که آیا مجموعه رویدادهای فعلی را به عنوان دو گروه کوچکتر از رویدادها بنویسد یا زمانی که فضای کافی در دسترس است، همه رویدادها را با هم بنویسد.
هنگامی که Sensors HAL تعداد دلخواه رویدادهای حسگر را در Event FMQ نوشته است، Sensors HAL باید با نوشتن بیت EventQueueFlagBits::READ_AND_PROCESS
در تابع EventFlag::wake
رویداد FMQ به چارچوب اطلاع دهد که رویدادها آماده هستند. EventFlag را می توان از Event FMQ با استفاده از EventFlag::createEventFlag
و تابع getEventFlagWord()
Event FMQ ایجاد کرد.
Sensors HAL 2.0/2.1 از write
و writeBlocking
در Event FMQ پشتیبانی می کند. پیاده سازی پیش فرض مرجعی برای استفاده از write
فراهم می کند. اگر از تابع writeBlocking
استفاده میشود، پرچم readNotification
باید روی EventQueueFlagBits::EVENTS_READ
تنظیم شود، که در هنگام خواندن رویدادها از Event FMQ توسط چارچوب تنظیم میشود. پرچم اعلان نوشتن باید روی EventQueueFlagBits::READ_AND_PROCESS
تنظیم شود، که به چارچوب اطلاع می دهد که رویدادها در Event FMQ نوشته شده اند.
رویدادهای WAKE_UP
رویدادهای WAKE_UP
رویدادهای حسگر هستند که باعث میشوند پردازنده برنامه (AP) بیدار شود و بلافاصله رویداد را مدیریت کند. هر زمان که یک رویداد WAKE_UP
در Event FMQ نوشته می شود، Sensors HAL باید یک قفل بیدار نگه دارد تا اطمینان حاصل شود که سیستم تا زمانی که چارچوب بتواند رویداد را مدیریت کند، بیدار می ماند. پس از دریافت یک رویداد WAKE_UP
، فریم ورک wake lock خود را ایمن می کند و به Sensors HAL اجازه می دهد تا wake lock خود را آزاد کند. برای همگام سازی زمانی که Sensors HAL قفل wake خود را آزاد می کند، از Wake Lock FMQ استفاده کنید.
حسگر HAL باید Wake Lock FMQ را بخواند تا تعداد رویدادهای WAKE_UP
را که فریم ورک مدیریت کرده است تعیین کند. HAL فقط باید قفل wake خود را برای رویدادهای WAKE_UP
آزاد کند که تعداد کل رویدادهای WAKE_UP
کنترل نشده صفر باشد. پس از مدیریت رویدادهای حسگر، چارچوب تعداد رویدادهایی را که به عنوان رویدادهای WAKE_UP
علامتگذاری شدهاند شمارش میکند و این عدد را در Wake Lock FMQ مینویسد.
این فریم ورک اعلان نوشتن WakeLockQueueFlagBits::DATA_WRITTEN
را در Wake Lock FMQ هر زمان که دادهها را روی Wake Lock FMQ مینویسد تنظیم میکند.
سنسورهای دینامیک
سنسورهای پویا حسگرهایی هستند که از نظر فیزیکی بخشی از دستگاه نیستند، اما می توانند به عنوان ورودی دستگاه استفاده شوند، مانند یک صفحه بازی با یک شتاب سنج.
هنگامی که یک سنسور پویا متصل است، تابع onDynamicSensorConnected
در ISensorsCallback
باید از Sensors HAL فراخوانی شود. این چارچوب حسگر پویا جدید را مطلع میکند و اجازه میدهد حسگر از طریق چارچوب کنترل شود و رویدادهای حسگر توسط مشتریان مصرف شود.
به طور مشابه، هنگامی که یک حسگر پویا قطع می شود، تابع onDynamicSensorDisconnected
در ISensorsCallback
باید فراخوانی شود تا چارچوب بتواند هر سنسوری را که دیگر در دسترس نیست حذف کند.
کانال مستقیم
کانال مستقیم یک روش عملیاتی است که در آن رویدادهای حسگر به جای اینکه در FMQ رویداد با دور زدن چارچوب حسگرهای Android در حافظه خاص نوشته شوند. مشتری که یک کانال مستقیم را ثبت می کند باید رویدادهای حسگر را مستقیماً از حافظه ای که برای ایجاد کانال مستقیم استفاده شده است بخواند و رویدادهای حسگر را از طریق چارچوب دریافت نخواهد کرد. تابع configDirectReport()
مشابه batch()
برای عملکرد عادی است و کانال گزارش مستقیم را پیکربندی می کند.
توابع registerDirectChannel()
و unregisterDirectChannel()
یک کانال مستقیم جدید ایجاد یا نابود می کنند.
حالت های عملیات
تابع setOperationMode()
به چارچوب اجازه می دهد تا یک حسگر را پیکربندی کند تا چارچوب بتواند داده های حسگر را به حسگر تزریق کند. این برای آزمایش مفید است، به خصوص برای الگوریتم هایی که در زیر چارچوب وجود دارند.
تابع injectSensorData()
در HAL 2.0 و تابع injectSensorsData_2_1()
در HAL 2.0 معمولاً برای فشار دادن پارامترهای عملیاتی به حسگر HAL استفاده می شود. این تابع همچنین می تواند برای تزریق رویدادهای حسگر به یک سنسور خاص استفاده شود.
اعتبار سنجی
برای تأیید اجرای Sensors HAL، تست های سنسور CTS و VTS را اجرا کنید.
تست های CTS
تستهای سنسور CTS هم در تستهای خودکار CTS و هم در برنامه دستی CTS Verifier وجود دارد.
تست های خودکار در cts/tests/sensor/src/android/hardware/cts قرار دارند. این آزمایشها عملکرد استاندارد حسگرها را تأیید میکنند، مانند سنسورهای فعال، دستهبندی و نرخ رویداد حسگر.
آزمایشهای تأییدکننده CTS در cts/apps/CtsVerifier/src/com/android/cts/verifier/sensors قرار دارند. این آزمایشها به ورودی دستی اپراتور آزمایش نیاز دارند و اطمینان حاصل میکنند که سنسورها مقادیر دقیق را گزارش میکنند.
گذراندن تستهای CTS برای اطمینان از اینکه دستگاه تحت آزمایش تمام الزامات CDD را برآورده میکند، حیاتی است.
تست های VTS
تست های VTS برای سنسورهای HAL 2.0 در سخت افزار/رابط/سنسور/2.0/vts قرار دارند. تست های VTS برای سنسورهای HAL 2.1 در سخت افزار/رابط/حسگر/2.1/vts قرار دارند. این تستها تضمین میکنند که Sensors HAL به درستی پیادهسازی شده است و تمام الزامات موجود در ISensors.hal
و ISensorsCallback.hal
به درستی برآورده شدهاند.
از 2.0 به سنسور HAL 2.1 ارتقا دهید
هنگام ارتقاء به Sensors HAL 2.1 از 2.0، پیاده سازی HAL شما باید شامل متدهای initialize_2_1()
، getSensorsList_2_1()
و injectSensorsData_2_1()
همراه با انواع HAL 2.1 باشد. این روش ها باید همان الزامات ذکر شده برای HAL 2.0 در بالا را برآورده کنند.
از آنجایی که نسخههای کوچک HAL باید از تمام توابع HALهای قبلی پشتیبانی کنند، HALهای 2.1 باید به عنوان HALهای 2.0 مقداردهی اولیه شوند. برای جلوگیری از پیچیدگی پشتیبانی از هر دو نسخه HAL، استفاده از Multi-HAL 2.1 به شدت توصیه می شود.
برای مثالی از نحوه پیاده سازی Sensors 2.1 HAL خود، Sensors.h را ببینید.
از 1.0 به سنسور HAL 2.0 ارتقا دهید
هنگام ارتقا به Sensors HAL 2.0 از 1.0، مطمئن شوید که اجرای HAL شما الزامات زیر را برآورده می کند.
HAL را راه اندازی کنید
تابع initialize()
باید برای ایجاد FMQ بین چارچوب و HAL پشتیبانی شود.
سنسورهای موجود را در معرض دید قرار دهید
در Sensors HAL 2.0، تابع getSensorsList()
باید همان مقدار را در طول راهاندازی یک دستگاه، حتی در سراسر راهاندازی مجدد سنسور HAL، برگرداند. یک نیاز جدید تابع getSensorsList()
این است که باید همان مقدار را در حین راهاندازی یک دستگاه، حتی در راهاندازی مجدد سنسور HAL برگرداند. این به چارچوب اجازه می دهد تا در صورت راه اندازی مجدد سرور سیستم، اتصالات حسگر را دوباره برقرار کند. مقدار بازگشتی توسط getSensorsList()
می تواند پس از راه اندازی مجدد دستگاه تغییر کند.
رویدادهای حسگر را در FMQ بنویسید
در Sensors HAL 2.0، به جای انتظار برای فراخوانی poll()
، Sensors HAL باید هر زمان که رویدادهای حسگر در دسترس هستند، رویدادهای حسگر را فعالانه در Event FMQ بنویسد. HAL همچنین مسئول نوشتن بیت های صحیح در EventFlag
برای خواندن FMQ در چارچوب است.
رویدادهای WAKE_UP
در Sensors HAL 1.0، HAL میتوانست قفل wake خود را برای هر رویداد WAKE_UP
در هر فراخوان بعدی به poll()
پس از ارسال WAKE_UP
به poll()
آزاد کند، زیرا این نشان میدهد که چارچوب تمام رویدادهای حسگر را پردازش کرده و یک نتیجه را به دست آورده است. در صورت لزوم ویک لاک از آنجایی که در Sensors HAL 2.0، HAL دیگر نمی داند که فریم ورک چه زمانی رویدادهای نوشته شده در FMQ را پردازش کرده است، Wake Lock FMQ به فریم ورک اجازه می دهد تا زمانی که رویدادهای WAKE_UP
مدیریت می کند، با HAL ارتباط برقرار کند.
در Sensors HAL 2.0، wake lock محافظت شده توسط Sensors HAL برای رویدادهای WAKE_UP
باید با SensorsHAL_WAKEUP
شروع شود.
سنسورهای دینامیک
حسگرهای پویا با استفاده از تابع poll()
در Sensors HAL 1.0 برگردانده شدند. سنسورهای HAL 2.0 مستلزم این است که onDynamicSensorsConnected
و onDynamicSensorsDisconnected
در ISensorsCallback
هر زمان که اتصالات حسگر پویا تغییر می کنند فراخوانی شوند. این تماس ها به عنوان بخشی از نشانگر ISensorsCallback
که از طریق تابع initialize()
ارائه می شود، در دسترس هستند.
حالت های عملیات
حالت DATA_INJECTION
برای حسگرهای WAKE_UP
باید در Sensors HAL 2.0 پشتیبانی شود.
پشتیبانی از Multi-HAL
Sensors HAL 2.0 و 2.1 از multi-HAL با استفاده از چارچوب Sensors Multi-HAL پشتیبانی می کند. برای جزئیات پیاده سازی، انتقال از حسگر HAL 1.0 را ببینید.