سنسور HAL 1.0

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

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

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

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

  • sensors_module_t
  • sensors_poll_device_t
  • sensor_t
  • sensors_event_t

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

دریافت_سنسورها_لیست(لیست)

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 برابر با ۰ باشد و سنسور از قبل غیرفعال شده باشد، این عملکرد غیرفعال بوده و با موفقیت اجرا می‌شود.

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

دسته (سنسور، پرچم‌ها، دوره نمونه‌برداری، حداکثر تأخیر گزارش)

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(سنسور، دوره نمونه‌برداری)

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

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

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

فلاش (سنسور)

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

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

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

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

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

flush برای حسگرهای تک‌مرحله‌ای (one-shot) اعمال نمی‌شود؛ اگر sensor_handle به یک حسگر تک‌مرحله‌ای اشاره داشته باشد، flush باید -EINVAL برگرداند و هیچ رویداد فراداده‌ای برای flush complete ایجاد نکند.

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

نظرسنجی()

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

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

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

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

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

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

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

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

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

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

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

ماژول_حسگرها

sensors_module_t نوعی است که برای ایجاد ماژول سخت‌افزار اندروید برای حسگرها استفاده می‌شود. پیاده‌سازی 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 نشان دهنده یک سنسور اندروید است. در اینجا برخی از فیلدهای مهم آن آورده شده است:

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

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

نوع: نوع حسگر. برای جزئیات بیشتر به توضیح نوع حسگر در «سنسورهای اندروید چیستند؟» مراجعه کنید و برای انواع حسگرهای رسمی به «انواع حسگر» مراجعه کنید. برای انواع حسگرهای غیررسمی، 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 گزارش می‌شود.

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

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

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

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

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

سنسورها_رویداد_تی

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

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

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

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

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

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

رویدادهای تکمیل‌شده‌ی مربوط به داده‌های متادیتا

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

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

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

سنسور، رزرو شده و برچسب زمانی : باید 0 باشد

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

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