Browse Source

sensors: Fix alignment issues

Add padding to the header and remove unnecessary memset in order to fix
alignment faults in cores such as M0 or ones that support
CONFIG_TRAP_UNALIGNED_ACCESS

Signed-off-by: Yuval Peress <peress@google.com>
pull/63658/head
Yuval Peress 2 years ago committed by Fabio Baltieri
parent
commit
96175fcc47
  1. 27
      drivers/sensor/default_rtio_sensor.c
  2. 5
      drivers/sensor/icm42688/icm42688.c
  3. 5
      include/zephyr/drivers/sensor.h

27
drivers/sensor/default_rtio_sensor.c

@ -12,6 +12,12 @@ @@ -12,6 +12,12 @@
LOG_MODULE_REGISTER(sensor_compat, CONFIG_SENSOR_LOG_LEVEL);
/*
* Ensure that the size of the generic header aligns with the sensor channel enum. If it doesn't,
* then cores that require aligned memory access will fail to read channel[0].
*/
BUILD_ASSERT((sizeof(struct sensor_data_generic_header) % sizeof(enum sensor_channel)) == 0);
static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
static void sensor_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
@ -49,6 +55,21 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_ @@ -49,6 +55,21 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_
return num_samples;
}
/**
* @brief Compute the required header size
*
* This function takes into account alignment of the q31 values that will follow the header.
*
* @param[in] num_output_samples The number of samples to represent
* @return The number of bytes needed for this sample frame's header
*/
static inline uint32_t compute_header_size(int num_output_samples)
{
uint32_t size = sizeof(struct sensor_data_generic_header) +
(num_output_samples * sizeof(enum sensor_channel));
return (size + 3) & ~0x3;
}
/**
* @brief Compute the minimum number of bytes needed
*
@ -57,8 +78,7 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_ @@ -57,8 +78,7 @@ static inline int compute_num_samples(const enum sensor_channel *channels, size_
*/
static inline uint32_t compute_min_buf_len(int num_output_samples)
{
return sizeof(struct sensor_data_generic_header) + (num_output_samples * sizeof(q31_t)) +
(num_output_samples * sizeof(enum sensor_channel));
return compute_header_size(num_output_samples) + (num_output_samples * sizeof(q31_t));
}
/**
@ -121,8 +141,7 @@ static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_s @@ -121,8 +141,7 @@ static void sensor_submit_fallback(const struct device *dev, struct rtio_iodev_s
header->num_channels = num_output_samples;
header->shift = 0;
q31_t *q = (q31_t *)(buf + sizeof(struct sensor_data_generic_header) +
num_output_samples * sizeof(enum sensor_channel));
q31_t *q = (q31_t *)(buf + compute_header_size(num_output_samples));
/* Populate values, update shift, and set channels */
for (size_t i = 0, sample_idx = 0; i < cfg->count; ++i) {

5
drivers/sensor/icm42688/icm42688.c

@ -251,12 +251,11 @@ int icm42688_init(const struct device *dev) @@ -251,12 +251,11 @@ int icm42688_init(const struct device *dev)
}
#endif
memset(&data->cfg, 0, sizeof(struct icm42688_cfg));
data->cfg.accel_mode = ICM42688_ACCEL_LN;
data->cfg.gyro_mode = ICM42688_GYRO_LN;
data->cfg.accel_fs = ICM42688_ACCEL_FS_2G;
data->cfg.gyro_fs = ICM42688_GYRO_FS_125;
data->cfg.accel_odr = ICM42688_ACCEL_ODR_1000;
data->cfg.gyro_mode = ICM42688_GYRO_LN;
data->cfg.gyro_fs = ICM42688_GYRO_FS_125;
data->cfg.gyro_odr = ICM42688_GYRO_ODR_1000;
data->cfg.fifo_en = false;

5
include/zephyr/drivers/sensor.h

@ -801,11 +801,14 @@ struct __attribute__((__packed__)) sensor_data_generic_header { @@ -801,11 +801,14 @@ struct __attribute__((__packed__)) sensor_data_generic_header {
* The number of channels present in the frame. This will be the true number of elements in
* channel_info and in the q31 values that follow the header.
*/
size_t num_channels;
uint32_t num_channels;
/* Shift value for all samples in the frame */
int8_t shift;
/* This padding is needed to make sure that the 'channels' field is aligned */
int8_t _padding[sizeof(enum sensor_channel) - 1];
/* Channels present in the frame */
enum sensor_channel channels[0];
};

Loading…
Cancel
Save