diff --git a/drivers/sensor/default_rtio_sensor.c b/drivers/sensor/default_rtio_sensor.c index 60534c84d28..88d3196181a 100644 --- a/drivers/sensor/default_rtio_sensor.c +++ b/drivers/sensor/default_rtio_sensor.c @@ -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_ 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_ */ 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 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) { diff --git a/drivers/sensor/icm42688/icm42688.c b/drivers/sensor/icm42688/icm42688.c index b8ebef4f147..43fd6a72f47 100644 --- a/drivers/sensor/icm42688/icm42688.c +++ b/drivers/sensor/icm42688/icm42688.c @@ -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; diff --git a/include/zephyr/drivers/sensor.h b/include/zephyr/drivers/sensor.h index 76b65da4880..903acb6f03a 100644 --- a/include/zephyr/drivers/sensor.h +++ b/include/zephyr/drivers/sensor.h @@ -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]; };