nuttx/drivers/sensors/bmi270.c
Catalin Visinescu 081e4c478a drivers/: Multiple Drivers Are Registered With World Writable - Part 2
Permissions (Part 2)

Description:

In kernel builds, any unprivileged process running on the NuttX
device can open /dev/efuse and attempt to read/write fuse content.
Reading the fuses may provide valuable information to an attacker
controlling the user process. The write operation, in extreme cases
where the fuse blocks are not locked, may brick the device.

DISCLAIMER: I tried to be strict with the settings, better to relax them
later if it's needed.

This is part of https://github.com/apache/nuttx/issues/19410

See https://github.com/apache/nuttx/issues/19410

Compiles ok.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-07-15 15:27:28 +08:00

246 lines
6.9 KiB
C

/****************************************************************************
* drivers/sensors/bmi270.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/* WARNING for developers:
*
* This driver uses the legacy style of writing sensor drivers for NuttX. The
* project has since decided to adopt a new sensor framework in order to
* have a consistent API and feature-set.
*
* Sensors which use the uORB framework are typically suffixed "_uorb". You
* can also visit the documentation about the new sensor framework to learn
* more.
*/
#warning "This is a deprecated legacy sensor driver."
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdlib.h>
#include <errno.h>
#include <nuttx/debug.h>
#include <nuttx/kmalloc.h>
#include <nuttx/fs/fs.h>
#include <nuttx/sensors/bmi270.h>
#ifdef CONFIG_SENSORS_BMI270_I2C
# include <nuttx/i2c/i2c_master.h>
#else
# include <nuttx/spi/spi.h>
#endif
#include "bmi270_base.h"
/****************************************************************************
* Private Functions
****************************************************************************/
/* Character driver methods */
static int bmi270_open(FAR struct file *filep);
static int bmi270_close(FAR struct file *filep);
static ssize_t bmi270_read(FAR struct file *filep, FAR char *buffer,
size_t len);
static int bmi270_ioctl(FAR struct file *filep, int cmd,
unsigned long arg);
/****************************************************************************
* Private Data
****************************************************************************/
/* This the vtable that supports the character driver interface */
static const struct file_operations g_bmi270fops =
{
bmi270_open, /* open */
bmi270_close, /* close */
bmi270_read, /* read */
NULL, /* write */
NULL, /* seek */
bmi270_ioctl, /* ioctl */
};
/****************************************************************************
* Name: bmi270_open
*
* Description:
* Standard character driver open method.
*
****************************************************************************/
static int bmi270_open(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bmi270_dev_s *priv = inode->i_private;
int ret = OK;
/* Initialization sequence */
ret = bmi270_init_seq(priv);
if (ret != 0)
{
return ret;
}
/* Set normal mode */
bmi270_set_normal_imu(priv);
return OK;
}
/****************************************************************************
* Name: bmi270_close
*
* Description:
* Standard character driver close method.
*
****************************************************************************/
static int bmi270_close(FAR struct file *filep)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bmi270_dev_s *priv = inode->i_private;
/* Disable acquisition of acc and gyro */
bmi270_putreg8(priv, BMI270_PWR_CTRL, 0);
up_mdelay(30);
return OK;
}
/****************************************************************************
* Name: bmi270_read
*
* Description:
* Standard character driver read method.
*
****************************************************************************/
static ssize_t bmi270_read(FAR struct file *filep, FAR char *buffer,
size_t len)
{
FAR struct inode *inode = filep->f_inode;
FAR struct bmi270_dev_s *priv = inode->i_private;
FAR struct accel_gyro_st_s *p = (FAR struct accel_gyro_st_s *)buffer;
if (len < sizeof(struct accel_gyro_st_s))
{
snerr("Expected buffer size is %d\n", sizeof(struct accel_gyro_st_s));
return 0;
}
/* Set sensor_time to the lower 24 bits of SENSORTIME. */
p->sensor_time = 0;
bmi270_getregs(priv, BMI270_DATA_8, (FAR uint8_t *)p, 15);
return len;
}
/****************************************************************************
* Name: bmi270_ioctl
*
* Description:
* Standard character driver ioctl method.
*
****************************************************************************/
static int bmi270_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
return -ENOTTY;
}
/****************************************************************************
* Name: bmi270_register
*
* Description:
* Register the BMI270 character device as 'devpath'
*
* Input Parameters:
* devpath - The full path to the driver to register. E.g., "/dev/imu0"
* dev - An instance of the SPI or I2C interface to use to communicate
* with BMI270
* addr - (I2C only) The I2C address
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_SENSORS_BMI270_I2C
int bmi270_register(FAR const char *devpath, FAR struct i2c_master_s *dev,
uint8_t addr)
#else /* CONFIG_SENSORS_BMI270_SPI */
int bmi270_register(FAR const char *devpath, FAR struct spi_dev_s *dev)
#endif
{
FAR struct bmi270_dev_s *priv;
int ret;
priv = kmm_malloc(sizeof(struct bmi270_dev_s));
if (!priv)
{
snerr("Failed to allocate instance\n");
return -ENOMEM;
}
#ifdef CONFIG_SENSORS_BMI270_I2C
priv->i2c = dev;
priv->addr = addr;
priv->freq = BMI270_I2C_FREQ;
#else /* CONFIG_SENSORS_BMI270_SPI */
priv->spi = dev;
/* BMI270 detects communication bus is SPI by rising edge of CS. */
bmi270_getreg8(priv, 0x00);
bmi270_getreg8(priv, 0x00);
up_udelay(200);
#endif
ret = bmi270_checkid(priv);
if (ret < 0)
{
snerr("Wrong Device ID!\n");
kmm_free(priv);
return ret;
}
/* Register driver */
ret = register_driver(devpath, &g_bmi270fops, 0600, priv);
if (ret < 0)
{
snerr("Failed to register driver: %d\n", ret);
kmm_free(priv);
}
sninfo("BMI270 driver loaded successfully!\n");
return OK;
}