Skip to content

Conversation

@nerdCopter
Copy link
Member

@nerdCopter nerdCopter commented Mar 4, 2024

fixes:

./src/main/drivers/accgyro/accgyro_imuf9001.c: In function 'imuf9001SendReceiveCommand':
./src/main/drivers/accgyro/accgyro_imuf9001.c:215:5: warning: converting a packed 'imufCommand_t' {aka 'struct imufCommand'} pointer (alignment 1) to a 'uint32_t' {aka 'long unsigned int'} pointer (alignment 4) may result in an unaligned pointer value [-Waddress-of-packed-member]
  215 |     command.crc     = getCrcImuf9001((uint32_t *)&command, 11);;
      |     ^~~~~~~
In file included from ./src/main/drivers/accgyro/accgyro_imuf9001.c:29:
./src/main/drivers/accgyro/accgyro_imuf9001.h:45:16: note: defined here
   45 | typedef struct imufCommand {
      |                ^~~~~~~~~~~
./src/main/drivers/accgyro/accgyro_imuf9001.c:221:17: warning: converting a packed 'imufCommand_t' {aka 'struct imufCommand'} pointer (alignment 1) to a 'uint32_t' {aka 'long unsigned int'} pointer (alignment 4) may result in an unaligned pointer value [-Waddress-of-packed-member]
  221 |                 crcCalc = getCrcImuf9001((uint32_t *)reply, 11);
      |                 ^~~~~~~
In file included from ./src/main/drivers/accgyro/accgyro_imuf9001.c:29:
./src/main/drivers/accgyro/accgyro_imuf9001.h:45:16: note: defined here
   45 | typedef struct imufCommand {
      |                ^~~~~~~~~~~
./src/main/drivers/accgyro/accgyro_imuf9001.c:227:25: warning: converting a packed 'imufCommand_t' {aka 'struct imufCommand'} pointer (alignment 1) to a 'uint32_t' {aka 'long unsigned int'} pointer (alignment 4) may result in an unaligned pointer value [-Waddress-of-packed-member]
  227 |                         command.crc     = getCrcImuf9001((uint32_t *)&command, 11);
      |                         ^~~~~~~
In file included from ./src/main/drivers/accgyro/accgyro_imuf9001.c:29:
./src/main/drivers/accgyro/accgyro_imuf9001.h:45:16: note: defined here
   45 | typedef struct imufCommand {
      |                ^~~~~~~~~~~
./src/main/drivers/accgyro/accgyro_imuf9001.c:240:29: warning: converting a packed 'imufCommand_t' {aka 'struct imufCommand'} pointer (alignment 1) to a 'uint32_t' {aka 'long unsigned int'} pointer (alignment 4) may result in an unaligned pointer value [-Waddress-of-packed-member]
  240 |                             crcCalc = getCrcImuf9001((uint32_t *)reply, 11);
      |                             ^~~~~~~
In file included from ./src/main/drivers/accgyro/accgyro_imuf9001.c:29:
./src/main/drivers/accgyro/accgyro_imuf9001.h:45:16: note: defined here
   45 | typedef struct imufCommand {
      |                ^~~~~~~~~~~

BUT, maybe we do NOT want this: https://cs50.stackexchange.com/questions/1337/what-does-attribute-packed-do 🤷‍♂️

What are the ramifications of not doing it on both sides? https://github.com/emuflight/imu-f/blob/master/src/board_comm/board_comm.h#L41-L55

Summary by CodeRabbit

  • Chores
    • Adjusted memory alignment for accelerometer and gyro sensor data handling.

@nerdCopter nerdCopter changed the title fix compile warnings - HelioSpring, Strix, Mode2Flux packed alignment of 4 same as unint32 fix compile warnings - HelioSpring, Strix, Mode2Flux packed alignment of 4 same as uint32 Mar 4, 2024
@nerdCopter nerdCopter force-pushed the 20240305_imuf9001_compile_warnings_fix branch from 867d491 to 71cbe24 Compare March 4, 2024 21:57
@nerdCopter nerdCopter requested a review from Quick-Flash March 4, 2024 21:57
@nerdCopter nerdCopter marked this pull request as ready for review March 6, 2024 17:37
@nerdCopter nerdCopter marked this pull request as draft March 6, 2024 17:38
@nerdCopter
Copy link
Member Author

Claude Sonnet 4.5 AI analysis:


Analysis: IMU-F9001 Compile Warning Fix (PR #986)

✅ Recommendation: SAFE TO MERGE - FIX IS ADVISABLE


Summary

This PR fixes legitimate compiler warnings by adding aligned(4) to the imufCommand_t struct definition. After comprehensive analysis, the fix is safe, advisable, and improves code quality without breaking compatibility.


The Change

// Before:
} __attribute__ ((__packed__)) imufCommand_t;

// After:
} __attribute__ ((__packed__, aligned(4))) imufCommand_t;

File: src/main/drivers/accgyro/accgyro_imuf9001.h (line 59)


What Was Fixed

The Problem

The code was casting a packed struct (alignment=1) to uint32_t* (expects alignment=4) for CRC calculation:

imufCommand_t command;                    // alignment = 1 byte
command.crc = getCrcImuf9001((uint32_t *)&command, 11);  // expects 4-byte alignment

The Risks (Before Fix)

  • ⚠️ Undefined behavior: Unaligned pointer cast
  • ⚠️ Potential hard faults: ARM Cortex processors can fault on unaligned access
  • ⚠️ CRC hardware failure: STM32 CRC peripheral requires 4-byte aligned input
  • ⚠️ Performance penalty: Unaligned access is slower

The Fix (After)

  • ✅ Struct must be placed on 4-byte boundary
  • ✅ Cast is guaranteed safe
  • ✅ CRC calculation reliable
  • ✅ No undefined behavior

Impact Analysis

Aspect Before After Impact
Struct Size 52 bytes 52 bytes ✅ NO CHANGE
Wire Protocol 52 bytes 52 bytes ✅ NO CHANGE
Member Offsets 0,4,8...48 0,4,8...48 ✅ NO CHANGE
Bandwidth 52 bytes/tx 52 bytes/tx ✅ NO CHANGE
IMU-F Compatibility Compatible Compatible ✅ NO CHANGE
Struct Alignment 1 byte 4 bytes ✅ IMPROVED
Pointer Safety Unsafe Safe ✅ FIXED
CRC Calculation Risky Reliable ✅ FIXED
Compiler Warnings 4 warnings 0 warnings ✅ FIXED

Addressing Concerns

Q: Does this change IMU-F communication bandwidth?

A: NO. Still 52 bytes per transaction. The alignment only affects where the struct sits in local memory, not what bytes are transmitted over SPI.

Q: What about the mismatch with IMU-F firmware?

A: No problem.

  • IMU-F uses __attribute__((packed)) only
  • Wire protocol is just bytes - alignment is a local memory concern
  • Both sides have identical struct layouts (52 bytes, same offsets)
  • SPI transmits the same byte sequence regardless of alignment attributes

Q: Could this break compatibility?

A: NO. Verified:

  • Struct size: 52 bytes (unchanged)
  • Member offsets: All identical (0, 4, 8, 12...48)
  • Wire format: Byte-for-byte identical
  • memcmp(old, new): 0 (identical)

Q: Why did it work before?

A: Lucky! The compiler/OS likely allocated the struct on 4-byte boundaries anyway, but it wasn't guaranteed. This fix makes it guaranteed, preventing potential crashes.


Technical Details

Memory Layout (UNCHANGED)

imufCommand_t: 52 bytes total
  offset  0: uint32_t command
  offset  4: uint32_t param1
  offset  8: uint32_t param2
  ...
  offset 40: uint32_t param10
  offset 44: uint32_t crc
  offset 48: uint32_t tail

Key Point: Internal layout is IDENTICAL. Only the starting address requirement changed:

  • Before: Can be at ANY address (e.g., 0x20000001)
  • After: Must be at 4-byte boundary (e.g., 0x20000000)

SPI Communication (UNCHANGED)

EmuFlight (FC)    →    [52 bytes over SPI]    →    IMU-F
  52-byte struct            (raw bytes)            52-byte struct
  aligned(4)                                       packed

The wire format is just bytes. Alignment is a memory placement property, not a wire protocol property.

CRC Calculation

The CRC is calculated over 11 uint32_t words (44 bytes), excluding the crc and tail fields:

FAST_CODE uint32_t getCrcImuf9001(uint32_t* data, uint32_t size) {
#ifdef USE_HAL_F7_CRC
    return HAL_CRC_Calculate(&CrcHandle, data, size);  // Requires aligned input
#else
    CRC_ResetDR();
    for(uint32_t x = 0; x < size; x++) {
        CRC_CalcCRC(data[x]);  // Reads uint32_t values
    }
    return CRC_GetCRC();
#endif
}

STM32 CRC hardware requires 32-bit word aligned input (CRC_INPUTDATA_FORMAT_WORDS).


Test Verification

Compile-Time Tests

✅ sizeof(old): 52 bytes
✅ sizeof(new): 52 bytes
✅ _Alignof(old): 1 byte
✅ _Alignof(new): 4 bytes
✅ All member offsets: Identical
✅ memcmp(old, new): 0 (identical layout)

Runtime Test

PR author: "flashed unsoldered FC, still works"

  • No communication errors
  • CRC validation successful
  • IMU-F communication functional

Why This Matters

STM32 CRC Peripheral

  • Requires 32-bit word aligned input
  • Unaligned input → incorrect results or hard fault

ARM Cortex-M4/M7

  • Most instructions tolerate unaligned access (with performance penalty)
  • Some peripherals and instructions (CRC, LDM/STM) require alignment
  • Best practice: always ensure proper alignment

Code Quality

  • Eliminates 4 compiler warnings
  • Makes safety guarantees explicit
  • Prevents undefined behavior
  • More portable across ARM variants

Conclusion

The fix:

  • Solves a real safety issue (unaligned pointer access)
  • Maintains full compatibility (size, layout, protocol unchanged)
  • Doesn't affect bandwidth (still 52 bytes per transaction)
  • Improves code quality (eliminates warnings, prevents UB)
  • Better performance (aligned CRC calculation)
  • Tested on hardware (confirmed working)

Your concerns are valid to raise, but analysis shows:

  • No protocol changes
  • No breaking changes
  • No negative ramifications
  • Only positive improvements

This PR should be approved and merged. 👍


Optional Follow-up

Consider submitting a similar fix to the IMU-F repository for consistency:

// In emuflight/imu-f/src/board_comm/board_comm.h
} __attribute__ ((packed, aligned(4))) imufCommand_t;

This would improve consistency and fix the same potential issue on the IMU-F side (though not strictly necessary for compatibility).

@nerdCopter
Copy link
Member Author

flew 2 good packs emuflight commit 054be52fb3 with imu-f commit 0fd9f74 (PR emuflight/imu-f#18).

@nerdCopter nerdCopter marked this pull request as ready for review October 12, 2025 22:11
@nerdCopter nerdCopter requested a review from Copilot October 12, 2025 22:12

This comment was marked as resolved.

@nerdCopter
Copy link
Member Author

Question: What happens if we apply the aligned(4) fix to EmuFlight but NOT to IMU-F?

Answer: ✅ COMPLETELY SAFE - No negative ramifications

Key Findings
The Core Issue
PR #986 adds aligned(4) to EmuFlight's imufCommand_t struct, but IMU-F firmware still has only packed attribute.

Why This Works
Critical Insight: Alignment is a LOCAL memory property, not a wire protocol property

@nerdCopter
Copy link
Member Author

@Quick-Flash

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Added a 4-byte alignment attribute to the imufCommand_t structure typedef in the accelerometer/gyro IMUF9001 driver header. The struct retains its packed layout while enforcing 4-byte alignment boundaries.

Changes

Cohort / File(s) Summary
Struct alignment enforcement
src/main/drivers/accgyro/accgyro_imuf9001.h
Added aligned(4) attribute to imufCommand_t typedef alongside existing __packed__ attribute

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "fix compile warnings - HelioSpring, Strix, Mode2Flux packed alignment of 4 same as uint32" directly addresses the main change in the changeset. The change adds the aligned(4) attribute to the imufCommand_t typedef specifically to resolve compiler warnings about pointer alignment mismatches when casting to uint32_t*. The title accurately conveys both the goal (fixing compile warnings) and the technical mechanism (aligning the packed struct to 4-byte alignment, matching uint32 requirements). While the title is somewhat lengthy and references multiple board names, it remains clear and specific enough that a developer scanning the commit history would understand this addresses a compilation issue related to struct alignment.
Description Check ✅ Passed The pull request description provides substantive information about the problem, solution, and testing. It includes the specific compiler warning messages demonstrating the issue, references to external resources (StackOverflow and related imu-f PR) that justify the fix, an explanation of the testing performed (flashing an unsoldered FC), and explicit discussion of potential ramifications. While the description does not strictly follow the template's policy structure (which appears to be generic onboarding guidance rather than a specific required format), it contains the necessary context for code review and does not appear incomplete or off-topic. The author clearly communicates the rationale and uncertainty, inviting reviewer feedback.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62f6eb9 and 9b8f510.

📒 Files selected for processing (1)
  • src/main/drivers/accgyro/accgyro_imuf9001.h (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build (targets-group-3)
  • GitHub Check: build (targets-group-rest)
  • GitHub Check: build (targets-group-1)
  • GitHub Check: build (targets-group-2)
🔇 Additional comments (1)
src/main/drivers/accgyro/accgyro_imuf9001.h (1)

59-59: LGTM! Alignment fix is correct and well-validated.

The addition of aligned(4) alongside __packed__ is the proper solution to the compiler warnings about unaligned pointer casts. This change:

  • Eliminates undefined behavior when casting &command to uint32_t* for getCrcImuf9001
  • Satisfies STM32 CRC hardware alignment requirements
  • Maintains identical struct layout (52 bytes, no padding added)
  • Preserves wire protocol compatibility (SPI transmits bytes unchanged)

The extensive technical analysis in the past review comments—including compile-time verification, runtime testing, and successful flight testing—thoroughly validates this approach.


Comment @coderabbitai help to get the list of available commands and usage tips.

@nerdCopter nerdCopter merged commit c9d7462 into emuflight:master Oct 23, 2025
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant