لایه انتزاع سخت‌افزار حسگرها نسخه ۱.۰

میانای Sensors HAL که در sensors.h تعریف شده است، میانای بین چارچوب Android و نرم‌افزار سخت‌افزار ویژه را نشان می‌دهد. پیاده‌سازی HAL باید هر تابع اعلام‌شده در sensors.h را تعریف کند. توابع اصلی عبارتند از:

  • get_sensors_list - فهرست همه حسگرها را برمی‌گرداند.
  • activate - حسگری را شروع یا متوقف می‌کند.
  • batch - پارامترهای حسگر را مثل بسامد نمونه‌برداری و بیشینه تأخیر گزارش‌دهی تنظیم می‌کند.
  • ‫setDelay - فقط در نسخه ۱.۰ «لایه انتزاع سخت‌افزار» استفاده می‌شود. بسامد نمونه‌برداری را برای حسگر معینی تنظیم می‌کند.
  • flush - وقتی این کار انجام شد، FIFO حسگر مشخص‌شده را پاک می‌کند و رویداد تکمیل پاک‌سازی را گزارش می‌کند.
  • poll - رویدادهای حسگر دردسترس را برمی‌گرداند.

پیاده‌سازی باید ایمن باشد و اجازه دهد این توابع از رشته‌های مختلف فراخوانی شوند.

این میانای همچنین چندین نوع را که توسط آن توابع استفاده می‌شود تعریف می‌کند. انواع اصلی عبارت‌اند از:

  • sensors_module_t
  • sensors_poll_device_t
  • sensor_t
  • sensors_event_t

علاوه‌بر بخش‌های زیر، برای کسب اطلاعات بیشتر درباره این انواع، sensors.h را ببینید.

get_sensors_list(list)

int (*get_sensors_list)(struct sensors_module_t* module, struct sensor_t
  const** list);

فهرست حسگرهای پیاده‌سازی‌شده توسط HAL را ارائه می‌دهد. برای جزئیات مربوط به نحوه تعریف حسگرها، sensor_t را ببینید.

ترتیبی که حسگرها در فهرست نشان داده می‌شوند، ترتیبی است که حسگرها به برنامه‌ها گزارش می‌شوند. معمولاً حسگرهای پایه ابتدا نمایش داده می‌شوند و سپس حسگرهای ترکیبی.

اگر چند حسگر نوع حسگر و ویژگی بیدار شدن یکسانی داشته باشند، اولین حسگر در فهرست «حسگر پیش‌فرض» نامیده می‌شود. این همان چیزی است که توسط getDefaultSensor(int sensorType, bool wakeUp) برگردانده شده است.

این تابع تعداد حسگرهای موجود در فهرست را برمی‌گرداند.

فعال کردن(حسگر، درست/غلط)

int (*activate)(struct sensors_poll_device_t *dev, int sensor_handle, int
  enabled);

حسگری را فعال یا غیرفعال می‌کند.

sensor_handle دسته حسگر برای فعال/غیرفعال کردن است. دستگیره حسگر با فیلد handle ساختار sensor_t آن تعریف می‌شود.

enabled روی ۱ تنظیم شده است تا حسگر را فعال کند یا روی ۰ تنظیم شده است تا حسگر را غیرفعال کند.

حسگرهای تک‌شلیک پس‌از دریافت رویداد به‌طور خودکار غیرفعال می‌شوند، و همچنان باید غیرفعال شدن ازطریق تماس با activate(..., enabled=0) را بپذیرند.

حسگرهای غیربیدارکننده هرگز مانع از رفتن SoC به حالت تعلیق نمی‌شوند؛ یعنی HAL نباید ازطرف برنامه‌ها قفل بیداری جزئی نگه دارد.

حسگرهای بیدارباش، هنگام ارائه مداوم رویدادها، می‌توانند از رفتن SoC به حالت تعلیق جلوگیری کنند، اما اگر رویدادی نیاز به ارائه نداشته باشد، قفل بیدارباش جزئی باید آزاد شود.

اگر enabled برابر با ۱ باشد و حسگر ازقبل فعال شده باشد، این تابع عملیاتی انجام نمی‌دهد و موفقیت‌آمیز است.

اگر enabled صفر باشد و حسگر ازقبل غیرفعال شده باشد، این تابع عملیاتی انجام نمی‌دهد و موفقیت‌آمیز است.

این تابع درصورت موفقیت ۰ و درغیراین‌صورت عدد خطای منفی را برمی‌گرداند.

batch(sensor, flags, sampling period, maximum report latency)

int (*batch)(
     struct sensors_poll_device_1* dev,
     int sensor_handle,
     int flags,
     int64_t sampling_period_ns,
     int64_t max_report_latency_ns);

پارامترهای حسگر را تنظیم می‌کند، ازجمله تعداد دفعات نمونه‌برداری و حداکثر تأخیر گزارش. این تابع می‌تواند درحالی‌که حسگر فعال است فراخوانده شود، در این حالت نباید باعث ازدست رفتن اندازه‌گیری‌های حسگر شود: انتقال از یک نرخ نمونه‌برداری به نرخ دیگر نباید باعث ازدست رفتن رویدادها شود، همچنین انتقال از بیشینه تأخیر گزارش بالا به بیشینه تأخیر گزارش پایین نباید باعث ازدست رفتن رویدادها شود.

‫sensor_handle دستگیره حسگر برای پیکربندی است.

درحال‌حاضر از flags استفاده نمی‌شود.

sampling_period_ns دوره نمونه‌برداری است که حسگر باید در آن اجرا شود (برحسب نانوثانیه). برای جزئیات بیشتر، sampling_period_ns را ببینید.

max_report_latency_ns حداکثر زمانی است که رویدادها می‌توانند قبل‌از گزارش شدن ازطریق HAL به‌تأخیر بیفتند، برحسب نانوثانیه. برای جزئیات بیشتر، بخش max_report_latency_ns را ببینید.

این تابع درصورت موفقیت ۰ و درغیراین‌صورت عدد خطای منفی را برمی‌گرداند.

setDelay(sensor, sampling period)

int (*setDelay)(
     struct sensors_poll_device_t *dev,
     int sensor_handle,
     int64_t sampling_period_ns);

پس‌از نسخه HAL 1.0، این تابع منسوخ شده است و هرگز فراخوانی نمی‌شود. درعوض، تابع batch برای تنظیم پارامتر sampling_period_ns فراخوانده می‌شود.

در نسخه 1.0 از HAL، به‌جای دسته‌ای از setDelay برای تنظیم sampling_period_ns استفاده می‌شد.

تخلیه(حسگر)

int (*flush)(struct sensors_poll_device_1* dev, int sensor_handle);

یک رویداد تکمیل پاک‌سازی به انتهای FIFO سخت‌افزار برای حسگر مشخص‌شده اضافه می‌کند و FIFO را پاک‌سازی می‌کند؛ این رویدادها طبق معمول (یعنی: گویی حداکثر تأخیر گزارش‌دهی منقضی شده است) تحویل داده می‌شوند و از FIFO حذف می‌شوند.

شستشو به‌صورت غیرهمگام انجام می‌شود (یعنی این تابع باید بلافاصله برگردد). اگر پیاده‌سازی از یک FIFO برای چندین حسگر استفاده کند، آن FIFO پاک‌سازی می‌شود و رویداد تکمیل پاک‌سازی فقط برای حسگر مشخص‌شده اضافه می‌شود.

اگر حسگر مشخص‌شده FIFO نداشته باشد (بافرینگ ممکن نباشد)، یا اگر FIFO در زمان تماس خالی باشد، flush باید همچنان موفق باشد و رویداد تکمیل تخلیه را برای آن حسگر ارسال کند. این تنظیم برای همه حسگرها به‌جز حسگرهای یک‌باره اعمال می‌شود.

وقتی flush فراخوانده می‌شود، حتی اگر رویداد تخلیه‌ای ازقبل در FIFO برای آن حسگر وجود داشته باشد، باید رویداد تخلیه‌ای دیگری ایجاد شود و به انتهای FIFO اضافه شود و FIFO باید تخلیه شود. تعداد تماس‌های flush باید با تعداد رویدادهای تکمیل پاک‌سازی ایجادشده برابر باشد.

flush برای حسگرهای تک‌ضرب اعمال نمی‌شود؛ اگر sensor_handle به حسگر تک‌ضرب اشاره کند، flush باید -EINVAL را برگرداند و هیچ رویداد فراداده کامل پاک‌سازی تولید نکند.

این تابع درصورت موفقیت ۰، درصورتی‌که حسگر مشخص‌شده یک حسگر تک‌ضرب باشد یا فعال نشده باشد -EINVAL، و درغیراین‌صورت یک عدد خطای منفی را برمی‌گرداند.

نظرسنجی()

int (*poll)(struct sensors_poll_device_t *dev, sensors_event_t* data, int
  count);

با پر کردن آرگومان data، آرایه‌ای از داده‌های حسگر را برمی‌گرداند. این تابع باید تا زمانی که رویدادها دردسترس قرار بگیرند مسدود شود. درصورت موفقیت، تعداد رویدادهای خوانده‌شده را برمی‌گرداند یا درصورت بروز خطا، عدد خطای منفی را برمی‌گرداند.

تعداد رویدادهای برگشتی در data باید کمتر یا مساوی با آرگومان count باشد. این تابع هرگز ۰ (بدون رویداد) برنمی‌گرداند.

توالی تماس‌ها

وقتی دستگاه راه‌اندازی می‌شود، get_sensors_list فراخوانی می‌شود.

وقتی حسگری فعال می‌شود، تابع batch با پارامترهای درخواستی فراخوانده می‌شود و پس‌از آن activate(..., enable=1) فراخوانده می‌شود.

توجه داشته باشید که در نسخه 1_0 از HAL، ترتیب برعکس بود: ابتدا activate و سپس set_delay فراخوانده می‌شد.

وقتی مشخصات درخواست‌شده حسگر درحین فعال بودن آن تغییر می‌کند، تابع batch فراخوانی می‌شود.

هرزمان بخواهید می‌توانید flush را فراخوانی کنید، حتی در حسگرهای فعال‌نشده (در این حالت باید -EINVAL را برگرداند)

وقتی حسگری غیرفعال شود، activate(..., enable=0) فراخوانده می‌شود.

به‌موازات آن تماس‌ها، تابع poll به‌طور مکرر برای درخواست داده فراخوانی خواهد شد. حتی وقتی هیچ حسگری فعال نباشد، می‌توان با poll تماس گرفت.

sensors_module_t

‫sensors_module_t نوعی است که برای ایجاد واحد سخت‌افزار Android برای حسگرها استفاده می‌شود. پیاده‌سازی HAL باید شیء HAL_MODULE_INFO_SYM از این نوع را برای نمایان کردن تابع get_sensors_list تعریف کند. برای اطلاعات بیشتر، تعریف sensors_module_t در sensors.h و تعریف hw_module_t را ببینید.

sensors_poll_device_t / sensors_poll_device_1_t

‫sensors_poll_device_1_t شامل بقیه روش‌های تعریف‌شده در بالا است: activate،‏ batch،‏ flush، و poll. فیلد common آن (از نوع hw_device_t) شماره نسخه HAL را تعریف می‌کند.

sensor_t

sensor_t نشان‌دهنده حسگر Android است. در اینجا برخی‌از فیلدهای مهم آن آمده است:

name: رشته‌ای که کاربر می‌تواند آن را ببیند و نشان‌دهنده حسگر است. این رشته اغلب حاوی نام قطعه حسگر زیرین، نوع حسگر، و اینکه آیا حسگر بیدارکننده است یا نه می‌باشد. برای مثال، «شتاب‌سنج LIS2HH12»، «ژیروسکوپ کالیبره‌نشده MAX21000»، «فشارسنج بیدارباش BMP280»، «بردار چرخش بازی MPU6515»

دستورکار: عدد صحیحی که هنگام ثبت حسگر یا تولید رویداد از آن برای ارجاع به حسگر استفاده می‌شود.

نوع: نوع حسگر. برای جزئیات بیشتر، توضیح نوع حسگر را در حسگرهای Android چیست؟ ببینید و برای انواع رسمی حسگر، انواع حسگر را ببینید. برای انواع حسگر غیررسمی، type باید با SENSOR_TYPE_DEVICE_PRIVATE_BASE شروع شود

stringType: نوع حسگر به‌صورت رشته. وقتی حسگر نوع رسمی دارد، روی SENSOR_STRING_TYPE_* تنظیم کنید. وقتی حسگر نوع خاصی از سازنده دارد، stringType باید با نام دامنه معکوس سازنده شروع شود. برای مثال، حسگری (مثلاً ردیاب تک‌شاخ) که توسط تیم Cool-product در Fictional-Company تعریف شده است می‌تواند از stringType=”com.fictional_company.cool_product.unicorn_detector” استفاده کند. از stringType برای شناسایی منحصربه‌فرد انواع حسگرهای غیررسمی استفاده می‌شود. برای اطلاعات بیشتر درباره انواع و انواع رشته‌ای، به sensors.h مراجعه کنید.

requiredPermission: رشته‌ای که نشان‌دهنده اجازه‌ای است که برنامه‌ها باید داشته باشند تا بتوانند حسگر را ببینند، در آن ثبت‌نام کنند، و داده‌های آن را دریافت کنند. رشته خالی به این معنا است که برنامه‌ها برای دسترسی به این حسگر به هیچ اجازه‌ای نیاز ندارند. برخی‌از انواع حسگر مثل مانیتور ضربان قلب دارای requiredPermission اجباری هستند. همه حسگرهایی که اطلاعات حساس کاربر (مثل ضربان قلب) را ارائه می‌دهند باید با اجازه محافظت شوند.

پرچم‌ها: پرچم‌های این حسگر که حالت گزارش‌دهی حسگر و اینکه آیا حسگر حسگر بیدارباش است یا نه را تعریف می‌کند. برای مثال، حسگر بیدارباش یک‌باره flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP خواهد داشت. بیت‌های پرچمی که در نسخه فعلی HAL استفاده نمی‌شوند باید برابر با ۰ باقی بمانند.

maxRange: حداکثر مقداری که حسگر می‌تواند گزارش کند، با همان واحد مقادیر گزارش‌شده. حسگر باید بتواند مقادیر را بدون اشباع شدن در طول [-maxRange; maxRange] گزارش کند. توجه داشته باشید که این یعنی محدوده کلی حسگر در مفهوم کلی 2*maxRange است. وقتی حسگر مقادیر را در چند محور گزارش می‌کند، محدوده برای هر محور اعمال می‌شود. برای مثال، شتاب‌سنج «+/- 2g» مقدار maxRange = 2*9.81 = 2g را گزارش خواهد کرد.

وضوح: کوچک‌ترین تفاوت در مقداری که حسگر می‌تواند اندازه‌گیری کند. معمولاً براساس maxRange و تعداد بیت‌های اندازه‌گیری محاسبه می‌شود.

power: هزینه انرژی فعال کردن حسگر، برحسب میلی‌آمپر. این مقدار تقریباً همیشه بیشتر از مصرف برق گزارش‌شده در برگه داده حسگر زیربنایی است. برای جزئیات بیشتر، حسگرهای پایه != حسگرهای فیزیکی را ببینید و برای جزئیات نحوه اندازه‌گیری مصرف انرژی حسگر، فرایند اندازه‌گیری انرژی را ببینید. اگر مصرف انرژی حسگر به حرکت دستگاه بستگی داشته باشد، مصرف انرژی درحین حرکت همان مصرفی است که در فیلد power گزارش شده است.

minDelay: برای حسگرهای پیوسته، دوره نمونه‌برداری، برحسب میکروثانیه، متناظر با سریع‌ترین نرخ پشتیبانی‌شده توسط حسگر. برای جزئیات مربوط به نحوه استفاده از این مقدار، sampling_period_ns را ببینید. مراقب باشید که minDelay به میکروثانیه بیان می‌شود درحالی‌که sampling_period_ns به نانوثانیه بیان می‌شود. برای حسگرهای حالت گزارش‌دهی ویژه و هنگام تغییر، مگر اینکه به‌گونه دیگری مشخص شده باشد، minDelay باید ۰ باشد. برای حسگرهای یک‌باره، باید -۱ باشد.

maxDelay: برای حسگرهای پیوسته و تغییرپذیر، دوره نمونه‌برداری، برحسب میکروثانیه، متناظر با کندترین نرخ پشتیبانی‌شده توسط حسگر. برای جزئیات مربوط به نحوه استفاده از این مقدار، sampling_period_ns را ببینید. مراقب باشید که maxDelay به میکروثانیه بیان می‌شود درحالی‌که sampling_period_ns به نانوثانیه بیان می‌شود. برای حسگرهای ویژه و تک‌شات، maxDelay باید ۰ باشد.

fifoReservedEventCount: تعداد رویدادهای رزروشده برای این حسگر در FIFO سخت‌افزار. اگر FIFO اختصاصی برای این حسگر وجود داشته باشد، fifoReservedEventCount اندازه این FIFO اختصاصی است. اگر FIFO با حسگرهای دیگر هم‌رسانی شود، fifoReservedEventCount اندازه بخشی از FIFO است که برای آن حسگر رزرو شده است. در اکثر سیستم‌های مشترک FIFO، و در سیستم‌هایی که FIFO سخت‌افزاری ندارند، این مقدار ۰ است.

fifoMaxEventCount: حداکثر تعداد رویدادهایی که می‌تواند در FIFO برای این حسگر ذخیره شود. این مقدار همیشه بزرگ‌تر یا مساوی با fifoReservedEventCount است. این مقدار برای تخمین سرعت پر شدن FIFO هنگام ثبت در حسگر با نرخ خاصی استفاده می‌شود، با فرض اینکه هیچ حسگر دیگری فعال نشده باشد. در سیستم‌هایی که FIFO سخت‌افزاری ندارند، fifoMaxEventCount برابر با ۰ است. برای جزئیات بیشتر، دسته‌بندی را ببینید.

برای حسگرهایی که نوع حسگر رسمی دارند، برخی‌از فیلدها توسط چارچوب بازنویسی می‌شوند. برای مثال، حسگرهای شتاب‌سنج مجبورند حالت گزارش‌دهی پیوسته داشته باشند و مانیتورهای ضربان قلب مجبورند با اجازه SENSOR_PERMISSION_BODY_SENSORS محافظت شوند.

sensors_event_t

رویدادهای حسگر تولیدشده توسط حسگرهای Android و گزارش‌شده ازطریق تابع نظرسنجی از نوع type sensors_event_t هستند. در اینجا چند فیلد مهم sensors_event_t آمده است:

نسخه: باید sizeof(struct sensors_event_t) باشد

sensor: دسته حسگری که رویداد را تولید کرده است، همان‌طور که توسط sensor_t.handle تعریف شده است.

نوع: نوع حسگر حسگری که رویداد را تولید کرده است، همان‌گونه که در sensor_t.type تعریف شده است.

مُهر زمان: مُهر زمان رویداد در نانوثانیه. این زمان وقوع رویداد است (گامی برداشته شده است یا اندازه‌گیری شتاب‌سنج انجام شده است)، نه زمان گزارش رویداد. timestamp باید با ساعت elapsedRealtimeNano همگام‌سازی شود و درمورد حسگرهای پیوسته، لرزش باید کم باشد. فیلتر کردن مُهر زمان گاهی برای برآورده کردن الزامات CDD ضروری است، زیرا استفاده از تنها زمان وقفه SoC برای تنظیم مُهرهای زمان باعث لرزش بیش‌ازحد می‌شود و استفاده از تنها زمان تراشه حسگر برای تنظیم مُهرهای زمان می‌تواند باعث عدم همگام‌سازی از ساعت elapsedRealtimeNano شود، زیرا ساعت حسگر دچار رانش می‌شود.

داده‌ها و فیلدهای هم‌پوشانی: مقادیر اندازه‌گیری‌شده توسط حسگر. معنی و واحدهای آن فیلدها مختص هر نوع حسگر است. برای شرح فیلدهای داده، sensors.h و تعریف انواع حسگر مختلف را ببینید. برای برخی حسگرها، دقت خوانش‌ها نیز به‌عنوان بخشی از داده‌ها ازطریق فیلد status گزارش می‌شود. این فیلد فقط برای آن انواع حسگر انتخابی ازطریق لوله منتقل می‌شود و در لایه «کیت توسعه نرم‌افزار» به‌عنوان مقدار دقت ظاهر می‌شود. برای این حسگرها، این واقعیت که فیلد وضعیت باید تنظیم شود در تعریف نوع حسگر آن‌ها ذکر شده است.

رویدادهای تکمیل پاک‌سازی فراداده

رویدادهای فراداده همان نوع رویدادهای حسگر عادی را دارند: sensors_event_meta_data_t = sensors_event_t. این رویدادها همراه با رویدادهای حسگر دیگر ازطریق نظرسنجی برگردانده می‌شوند. این فیلدها را دارد:

نسخه: باید META_DATA_VERSION باشد

نوع: باید SENSOR_TYPE_META_DATA باشد

حسگر، رزروشده، و مُهر زمان: باید ۰ باشد

meta_data.what: حاوی نوع فراداده برای این رویداد است. درحال‌حاضر یک نوع فراداده معتبر وجود دارد: META_DATA_FLUSH_COMPLETE.

‫META_DATA_FLUSH_COMPLETE رویداد نشان‌دهنده تکمیل پاک‌سازی حسگر FIFO است. وقتی meta_data.what=META_DATA_FLUSH_COMPLETE، meta_data.sensor باید روی دستگیره حسگری که شستشو داده شده است تنظیم شود. این کدها زمانی تولید می‌شوند که flush در حسگری فراخوانده شود. برای اطلاعات بیشتر، بخش مربوط به تابع flush را ببینید.