Home | History | Annotate | Download | only in sensorhal
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "sensorlist.h"
     18 
     19 #include <math.h>
     20 
     21 #include "hubdefs.h"
     22 
     23 using namespace android;
     24 
     25 const int kVersion = 1;
     26 
     27 const float kMinSampleRateHzAccel = 6.250f;
     28 const float kMaxSampleRateHzAccel = 400.0f;
     29 
     30 const float kMinSampleRateHzGyro = 6.250f;
     31 const float kMaxSampleRateHzGyro = 400.0f;
     32 
     33 const float kMinSampleRateHzMag = 3.125f;
     34 const float kMaxSampleRateHzMag = 50.0f;
     35 
     36 const float kMinSampleRateHzPolling = 0.1f;
     37 const float kMaxSampleRateHzPolling = 25.0f;
     38 
     39 const float kMinSampleRateHzPressure = 0.1f;
     40 const float kMaxSampleRateHzPressure = 10.0f;
     41 
     42 const float kMinSampleRateHzTemperature = kMinSampleRateHzPolling;
     43 const float kMaxSampleRateHzTemperature = kMaxSampleRateHzPolling;
     44 
     45 const float kMinSampleRateHzProximity = kMinSampleRateHzPolling;
     46 const float kMaxSampleRateHzProximity = 5.0;
     47 
     48 const float kMinSampleRateHzLight = kMinSampleRateHzPolling;
     49 const float kMaxSampleRateHzLight = 5.0;
     50 
     51 const float kMinSampleRateHzOrientation = 12.5f;
     52 const float kMaxSampleRateHzOrientation = 200.0f;
     53 
     54 /*
     55  * The fowllowing max count is determined by the total number of blocks
     56  * avaliable in the shared nanohub buffer and number of samples each type of
     57  * event can hold within a buffer block.
     58  * For marlin's case, there are 239 blocks in the shared sensor buffer and
     59  * each block can hold 30 OneAxis Samples, 15 ThreeAxis Samples or 24
     60  * RawThreeAxies Samples.
     61  */
     62 const int kMaxOneAxisEventCount = 7170;
     63 const int kMaxThreeAxisEventCount = 3585;
     64 const int kMaxRawThreeAxisEventCount = 5736;
     65 
     66 const int kMinFifoReservedEventCount = 20;
     67 
     68 const char SENSOR_STRING_TYPE_INTERNAL_TEMPERATURE[] =
     69     "com.google.sensor.internal_temperature";
     70 const char SENSOR_STRING_TYPE_SYNC[] =
     71     "com.google.sensor.sync";
     72 const char SENSOR_STRING_TYPE_DOUBLE_TWIST[] =
     73     "com.google.sensor.double_twist";
     74 const char SENSOR_STRING_TYPE_DOUBLE_TAP[] =
     75     "com.google.sensor.double_tap";
     76 
     77 extern const sensor_t kSensorList[] = {
     78     {
     79         "TMD4903 Proximity Sensor",
     80         "AMS",
     81         kVersion,
     82         COMMS_SENSOR_PROXIMITY,
     83         SENSOR_TYPE_PROXIMITY,
     84         5.0f,                                          // maxRange (cm)
     85         1.0f,                                          // resolution (cm)
     86         0.0f,                                          // XXX power
     87         (int32_t)(1.0E6f / kMaxSampleRateHzProximity), // minDelay
     88         300,                                           // XXX fifoReservedEventCount
     89         kMaxOneAxisEventCount,                         // XXX fifoMaxEventCount
     90         SENSOR_STRING_TYPE_PROXIMITY,
     91         "",                                            // requiredPermission
     92         (long)(1.0E6f / kMinSampleRateHzProximity),    // maxDelay
     93         SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ON_CHANGE_MODE,
     94         { NULL, NULL }
     95     },
     96     {
     97         "TMD4903 Light Sensor",
     98         "AMS",
     99         kVersion,
    100         COMMS_SENSOR_LIGHT,
    101         SENSOR_TYPE_LIGHT,
    102         43000.0f,                                  // maxRange (lx)
    103         10.0f,                                     // XXX resolution (lx)
    104         0.0f,                                      // XXX power
    105         (int32_t)(1.0E6f / kMaxSampleRateHzLight), // minDelay
    106         kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
    107         kMaxOneAxisEventCount,                     // XXX fifoMaxEventCount
    108         SENSOR_STRING_TYPE_LIGHT,
    109         "",                                        // requiredPermission
    110         (long)(1.0E6f / kMinSampleRateHzLight),    // maxDelay
    111         SENSOR_FLAG_ON_CHANGE_MODE,
    112         { NULL, NULL }
    113     },
    114     {
    115         "BMI160 accelerometer",
    116         "Bosch",
    117         kVersion,
    118         COMMS_SENSOR_ACCEL,
    119         SENSOR_TYPE_ACCELEROMETER,
    120         GRAVITY_EARTH * 8.0f,                      // maxRange
    121         GRAVITY_EARTH * 8.0f / 32768.0f,           // resolution
    122         0.0f,                                      // XXX power
    123         (int32_t)(1.0E6f / kMaxSampleRateHzAccel), // minDelay
    124         3000,                                      // XXX fifoReservedEventCount
    125         kMaxRawThreeAxisEventCount,                // XXX fifoMaxEventCount
    126         SENSOR_STRING_TYPE_ACCELEROMETER,
    127         "",                                        // requiredPermission
    128         (long)(1.0E6f / kMinSampleRateHzAccel),    // maxDelay
    129         SENSOR_FLAG_CONTINUOUS_MODE,
    130         { NULL, NULL }
    131     },
    132     {
    133         "BMI160 gyroscope",
    134         "Bosch",
    135         kVersion,
    136         COMMS_SENSOR_GYRO,
    137         SENSOR_TYPE_GYROSCOPE,
    138         1000.0f * M_PI / 180.0f,                   // maxRange
    139         1000.0f * M_PI / (180.0f * 32768.0f),      // resolution
    140         0.0f,                                      // XXX power
    141         (int32_t)(1.0E6f / kMaxSampleRateHzGyro),  // minDelay
    142         kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
    143         kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
    144         SENSOR_STRING_TYPE_GYROSCOPE,
    145         "",                                        // requiredPermission
    146         (long)(1.0E6f / kMinSampleRateHzGyro),     // maxDelay
    147         SENSOR_FLAG_CONTINUOUS_MODE,
    148         { NULL, NULL }
    149     },
    150     {
    151         "BMI160 gyroscope (uncalibrated)",
    152         "Bosch",
    153         kVersion,
    154         COMMS_SENSOR_GYRO_UNCALIBRATED,
    155         SENSOR_TYPE_GYROSCOPE_UNCALIBRATED,
    156         1000.0f * M_PI / 180.0f,                   // maxRange
    157         1000.0f * M_PI / (180.0f * 32768.0f),      // resolution
    158         0.0f,                                      // XXX power
    159         (int32_t)(1.0E6f / kMaxSampleRateHzGyro),  // minDelay
    160         kMinFifoReservedEventCount,                // XXX fifoReservedEventCount
    161         kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
    162         SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED,
    163         "",                                        // requiredPermission
    164         (long)(1.0E6f / kMinSampleRateHzGyro),     // maxDelay
    165         SENSOR_FLAG_CONTINUOUS_MODE,
    166         { NULL, NULL }
    167     },
    168     {
    169         "AK09915 magnetometer",
    170         "AKM",
    171         kVersion,
    172         COMMS_SENSOR_MAG,
    173         SENSOR_TYPE_MAGNETIC_FIELD,
    174         1300.0f,                                   // XXX maxRange
    175         0.0f,                                      // XXX resolution
    176         0.0f,                                      // XXX power
    177         (int32_t)(1.0E6f / kMaxSampleRateHzMag),   // minDelay
    178         600,                                       // XXX fifoReservedEventCount
    179         kMaxThreeAxisEventCount,                   // XXX fifoMaxEventCount
    180         SENSOR_STRING_TYPE_MAGNETIC_FIELD,
    181         "",                                        // requiredPermission
    182         (long)(1.0E6f / kMinSampleRateHzMag),      // maxDelay
    183         SENSOR_FLAG_CONTINUOUS_MODE,
    184         { NULL, NULL }
    185     },
    186     {
    187         "AK09915 magnetometer (uncalibrated)",
    188         "AKM",
    189         kVersion,
    190         COMMS_SENSOR_MAG_UNCALIBRATED,
    191         SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
    192         1300.0f,                                        // XXX maxRange
    193         0.0f,                                           // XXX resolution
    194         0.0f,                                           // XXX power
    195         (int32_t)(1.0E6f / kMaxSampleRateHzMag),        // minDelay
    196         600,                                            // XXX fifoReservedEventCount
    197         kMaxThreeAxisEventCount,                        // XXX fifoMaxEventCount
    198         SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
    199         "",                                             // requiredPermission
    200         (long)(1.0E6f / kMinSampleRateHzMag),           // maxDelay
    201         SENSOR_FLAG_CONTINUOUS_MODE,
    202         { NULL, NULL }
    203     },
    204     {
    205         "BMP285 pressure",
    206         "Bosch",
    207         kVersion,
    208         COMMS_SENSOR_PRESSURE,
    209         SENSOR_TYPE_PRESSURE,
    210         1100.0f,                                      // maxRange (hPa)
    211         0.005f,                                       // resolution (hPa)
    212         0.0f,                                         // XXX power
    213         (int32_t)(1.0E6f / kMaxSampleRateHzPressure), // minDelay
    214         300,                                          // XXX fifoReservedEventCount
    215         kMaxOneAxisEventCount,                        // XXX fifoMaxEventCount
    216         SENSOR_STRING_TYPE_PRESSURE,
    217         "",                                           // requiredPermission
    218         (long)(1.0E6f / kMinSampleRateHzPressure),    // maxDelay
    219         SENSOR_FLAG_CONTINUOUS_MODE,
    220         { NULL, NULL }
    221     },
    222     {
    223         "BMP285 temperature",
    224         "Bosch",
    225         kVersion,
    226         COMMS_SENSOR_TEMPERATURE,
    227         SENSOR_TYPE_INTERNAL_TEMPERATURE,
    228         85.0f,                                           // maxRange (degC)
    229         0.01,                                            // resolution (degC)
    230         0.0f,                                            // XXX power
    231         (int32_t)(1.0E6f / kMaxSampleRateHzTemperature), // minDelay
    232         kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
    233         kMaxOneAxisEventCount,                           // XXX fifoMaxEventCount
    234         SENSOR_STRING_TYPE_INTERNAL_TEMPERATURE,
    235         "",                                              // requiredPermission
    236         (long)(1.0E6f / kMinSampleRateHzTemperature),    // maxDelay
    237         SENSOR_FLAG_CONTINUOUS_MODE,
    238         { NULL, NULL }
    239     },
    240     {
    241         "Orientation",
    242         "Google",
    243         kVersion,
    244         COMMS_SENSOR_ORIENTATION,
    245         SENSOR_TYPE_ORIENTATION,
    246         360.0f,                                          // maxRange (deg)
    247         1.0f,                                            // XXX resolution (deg)
    248         0.0f,                                            // XXX power
    249         (int32_t)(1.0E6f / kMaxSampleRateHzOrientation), // minDelay
    250         kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
    251         kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
    252         SENSOR_STRING_TYPE_ORIENTATION,
    253         "",                                              // requiredPermission
    254         (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
    255         SENSOR_FLAG_CONTINUOUS_MODE,
    256         { NULL, NULL }
    257     },
    258     {
    259         "BMI160 Step detector",
    260         "Bosch",
    261         kVersion,
    262         COMMS_SENSOR_STEP_DETECTOR,
    263         SENSOR_TYPE_STEP_DETECTOR,
    264         1.0f,                                   // maxRange
    265         1.0f,                                   // XXX resolution
    266         0.0f,                                   // XXX power
    267         0,                                      // minDelay
    268         100,                                    // XXX fifoReservedEventCount
    269         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    270         SENSOR_STRING_TYPE_STEP_DETECTOR,
    271         "",                                     // requiredPermission
    272         0,                                      // maxDelay
    273         SENSOR_FLAG_SPECIAL_REPORTING_MODE,
    274         { NULL, NULL }
    275     },
    276     {
    277         "BMI160 Step counter",
    278         "Bosch",
    279         kVersion,
    280         COMMS_SENSOR_STEP_COUNTER,
    281         SENSOR_TYPE_STEP_COUNTER,
    282         1.0f,                                   // XXX maxRange
    283         1.0f,                                   // resolution
    284         0.0f,                                   // XXX power
    285         0,                                      // minDelay
    286         kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
    287         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    288         SENSOR_STRING_TYPE_STEP_COUNTER,
    289         "",                                     // requiredPermission
    290         0,                                      // maxDelay
    291         SENSOR_FLAG_ON_CHANGE_MODE,
    292         { NULL, NULL }
    293     },
    294     {
    295         "Significant motion",
    296         "Google",
    297         kVersion,
    298         COMMS_SENSOR_SIGNIFICANT_MOTION,
    299         SENSOR_TYPE_SIGNIFICANT_MOTION,
    300         1.0f,                                   // maxRange
    301         1.0f,                                   // XXX resolution
    302         0.0f,                                   // XXX power
    303         -1,                                     // minDelay
    304         0,                                      // XXX fifoReservedEventCount
    305         0,                                      // XXX fifoMaxEventCount
    306         SENSOR_STRING_TYPE_SIGNIFICANT_MOTION,
    307         "",                                     // requiredPermission
    308         0,                                      // maxDelay
    309         SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ONE_SHOT_MODE,
    310         { NULL, NULL }
    311     },
    312     {
    313         "Gravity",
    314         "Google",
    315         kVersion,
    316         COMMS_SENSOR_GRAVITY,
    317         SENSOR_TYPE_GRAVITY,
    318         1000.0f,                                         // maxRange
    319         1.0f,                                            // XXX resolution
    320         0.0f,                                            // XXX power
    321         (int32_t)(1.0E6f / kMaxSampleRateHzOrientation), // minDelay
    322         kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
    323         kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
    324         SENSOR_STRING_TYPE_GRAVITY,
    325         "",                                              // requiredPermission
    326         (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
    327         SENSOR_FLAG_CONTINUOUS_MODE,
    328         { NULL, NULL }
    329     },
    330     {
    331         "Linear Acceleration",
    332         "Google",
    333         kVersion,
    334         COMMS_SENSOR_LINEAR_ACCEL,
    335         SENSOR_TYPE_LINEAR_ACCELERATION,
    336         1000.0f,                                         // maxRange
    337         1.0f,                                            // XXX resolution
    338         0.0f,                                            // XXX power
    339         (int32_t)(1.0E6f / kMaxSampleRateHzOrientation), // minDelay
    340         kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
    341         kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
    342         SENSOR_STRING_TYPE_LINEAR_ACCELERATION,
    343         "",                                              // requiredPermission
    344         (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
    345         SENSOR_FLAG_CONTINUOUS_MODE,
    346         { NULL, NULL }
    347     },
    348     {
    349         "Rotation Vector",
    350         "Google",
    351         kVersion,
    352         COMMS_SENSOR_ROTATION_VECTOR,
    353         SENSOR_TYPE_ROTATION_VECTOR,
    354         1000.0f,                                         // maxRange
    355         1.0f,                                            // XXX resolution
    356         0.0f,                                            // XXX power
    357         (int32_t)(1.0E6f / kMaxSampleRateHzOrientation), // minDelay
    358         kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
    359         kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
    360         SENSOR_STRING_TYPE_ROTATION_VECTOR,
    361         "",                                              // requiredPermission
    362         (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
    363         SENSOR_FLAG_CONTINUOUS_MODE,
    364         { NULL, NULL }
    365     },
    366     {
    367         "Geomagnetic Rotation Vector",
    368         "Google",
    369         kVersion,
    370         COMMS_SENSOR_GEO_MAG,
    371         SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
    372         1000.0f,                                         // maxRange
    373         1.0f,                                            // XXX resolution
    374         0.0f,                                            // XXX power
    375         (int32_t)(1.0E6f / kMaxSampleRateHzOrientation), // minDelay
    376         kMinFifoReservedEventCount,                      // XXX fifoReservedEventCount
    377         kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
    378         SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
    379         "",                                              // requiredPermission
    380         (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
    381         SENSOR_FLAG_CONTINUOUS_MODE,
    382         { NULL, NULL }
    383     },
    384     {
    385         "Game Rotation Vector",
    386         "Google",
    387         kVersion,
    388         COMMS_SENSOR_GAME_ROTATION_VECTOR,
    389         SENSOR_TYPE_GAME_ROTATION_VECTOR,
    390         1000.0f,                                         // maxRange
    391         1.0f,                                            // XXX resolution
    392         0.0f,                                            // XXX power
    393         (int32_t)(1.0E6f / kMaxSampleRateHzOrientation), // minDelay
    394         300,                                             // XXX fifoReservedEventCount
    395         kMaxThreeAxisEventCount,                         // XXX fifoMaxEventCount
    396         SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR,
    397         "",                                              // requiredPermission
    398         (long)(1.0E6f / kMinSampleRateHzOrientation),    // maxDelay
    399         SENSOR_FLAG_CONTINUOUS_MODE,
    400         { NULL, NULL }
    401     },
    402     {
    403         "Tilt Detector",
    404         "Google",
    405         kVersion,
    406         COMMS_SENSOR_TILT,
    407         SENSOR_TYPE_TILT_DETECTOR,
    408         1.0f,                                   // maxRange
    409         1.0f,                                   // XXX resolution
    410         0.0f,                                   // XXX power
    411         0,                                      // minDelay
    412         kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
    413         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    414         SENSOR_STRING_TYPE_TILT_DETECTOR,
    415         "",                                     // requiredPermission
    416         0,                                      // maxDelay
    417         SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_SPECIAL_REPORTING_MODE,
    418         { NULL, NULL }
    419     },
    420     /*
    421     {
    422         "Pickup Gesture",
    423         "Google",
    424         kVersion,
    425         COMMS_SENSOR_GESTURE,
    426         SENSOR_TYPE_PICK_UP_GESTURE,
    427         1.0f,                                   // maxRange
    428         1.0f,                                   // XXX resolution
    429         0.0f,                                   // XXX power
    430         -1,                                     // minDelay
    431         0,                                      // XXX fifoReservedEventCount
    432         0,                                      // XXX fifoMaxEventCount
    433         SENSOR_STRING_TYPE_PICK_UP_GESTURE,
    434         "",                                     // requiredPermission
    435         0,                                      // maxDelay
    436         SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_ONE_SHOT_MODE,
    437         { NULL, NULL }
    438     },
    439     */
    440     {
    441         "Sensors Sync",
    442         "Google",
    443         kVersion,
    444         COMMS_SENSOR_SYNC,
    445         SENSOR_TYPE_SYNC,
    446         1.0f,                                   // maxRange
    447         1.0f,                                   // XXX resolution
    448         0.1f,                                   // XXX power
    449         0,                                      // minDelay
    450         kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
    451         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    452         SENSOR_STRING_TYPE_SYNC,
    453         "",                                     // requiredPermission
    454         0,                                      // maxDelay
    455         SENSOR_FLAG_SPECIAL_REPORTING_MODE,
    456         { NULL, NULL }
    457     },
    458     {
    459         "Double Twist",
    460         "Google",
    461         kVersion,
    462         COMMS_SENSOR_DOUBLE_TWIST,
    463         SENSOR_TYPE_DOUBLE_TWIST,
    464         1.0f,                                   // maxRange
    465         1.0f,                                   // XXX resolution
    466         0.1f,                                   // XXX power
    467         0,                                      // minDelay
    468         kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
    469         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    470         SENSOR_STRING_TYPE_DOUBLE_TWIST,
    471         "",                                     // requiredPermission
    472         0,                                      // maxDelay
    473         SENSOR_FLAG_WAKE_UP | SENSOR_FLAG_SPECIAL_REPORTING_MODE,
    474         { NULL, NULL }
    475     },
    476     {
    477         "Double Tap",
    478         "Google",
    479         kVersion,
    480         COMMS_SENSOR_DOUBLE_TAP,
    481         SENSOR_TYPE_DOUBLE_TAP,
    482         1.0f,                                   // maxRange
    483         1.0f,                                   // XXX resolution
    484         0.1f,                                   // XXX power
    485         0,                                      // minDelay
    486         kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
    487         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    488         SENSOR_STRING_TYPE_DOUBLE_TAP,
    489         "",                                     // requiredPermission
    490         0,                                      // maxDelay
    491         SENSOR_FLAG_SPECIAL_REPORTING_MODE,
    492         { NULL, NULL }
    493     },
    494     {
    495         "Device Orientation",
    496         "Google",
    497         kVersion,
    498         COMMS_SENSOR_WINDOW_ORIENTATION,
    499         SENSOR_TYPE_DEVICE_ORIENTATION,
    500         3.0f,                                   // maxRange
    501         1.0f,                                   // XXX resolution
    502         0.1f,                                   // XXX power
    503         0,                                      // minDelay
    504         kMinFifoReservedEventCount,             // XXX fifoReservedEventCount
    505         kMaxOneAxisEventCount,                  // XXX fifoMaxEventCount
    506         SENSOR_STRING_TYPE_DEVICE_ORIENTATION,
    507         "",                                     // requiredPermission
    508         0,                                      // maxDelay
    509         SENSOR_FLAG_ON_CHANGE_MODE,
    510         { NULL, NULL }
    511     },
    512 };
    513 
    514 extern const size_t kSensorCount = sizeof(kSensorList) / sizeof(sensor_t);
    515