Skip to content

Conversation

@Bwooce
Copy link

@Bwooce Bwooce commented Aug 15, 2025

Add --force-pack option for ESP32 and platforms with non-standard alignment

This adds support for forcing struct packing on all MAVLink messages,
which is necessary for platforms like ESP32 that have different default
struct alignment than x86/ARM platforms.

Problem:
ESP32 can add unexpected padding between struct fields even when the
MAVLink wire protocol layout is perfectly aligned. The existing needs_pack
mechanism only detects misalignment in the wire format itself, but cannot
predict platform-specific struct layout differences.

For example, ATTITUDE message fields are perfectly aligned in wire format:

  • time_boot_ms at offset 0 (4-byte aligned)
  • roll at offset 4 (4-byte aligned)
  • pitch at offset 8 (4-byte aligned)
  • etc.

So needs_pack = False. But ESP32 compiler may still add padding due to
platform-specific alignment rules, causing:

  • Different struct sizes (28 vs 32 bytes)
  • Fields at wrong offsets when using sizeof() in memcpy operations
  • Message corruption when parsing received data

The wire-protocol alignment test cannot detect this because it only
checks wire format offsets, not platform-specific compiler behavior.

Solution:
--force-pack allows platforms to override the automatic detection and
force MAVPACKED on all message structures, ensuring identical layout
across platforms regardless of compiler alignment preferences.

Changes:

  • Add --force-pack command line option to tools/mavgen.py
  • Modify mavgen_c.py to accept opts parameter and check force_pack
  • Apply MAVPACKED to all messages when force_pack is enabled
  • Use mav_array_memcpy instead of type-specific assignment for safer
    memory handling with packed structures

The mav_array_memcpy change is applied universally (not architecture-specific)
to ensure consistent behavior. The old mav_array_assign_* functions still exist
but are now implemented as macros that call mav_array_memcpy, making this a
backward-compatible improvement that avoids alignment assumptions.

This ensures cross-platform compatibility while maintaining the existing
selective packing behavior for standard platforms.

Fixes struct alignment issues on ESP32 that caused MAVLink message
corruption due to unexpected padding bytes in struct layouts.

…gnment

This adds support for forcing struct packing on all MAVLink messages,
which is necessary for platforms like ESP32 that have different default
struct alignment than x86/ARM platforms.

Problem:
ESP32 can add unexpected padding between struct fields even when the
MAVLink wire protocol layout is perfectly aligned. The existing needs_pack
mechanism only detects misalignment in the wire format itself, but cannot
predict platform-specific struct layout differences.

For example, ATTITUDE message fields are perfectly aligned in wire format:
- time_boot_ms at offset 0 (4-byte aligned)
- roll at offset 4 (4-byte aligned)
- pitch at offset 8 (4-byte aligned)
- etc.

So needs_pack = False. But ESP32 compiler may still add padding due to
platform-specific alignment rules, causing:
- Different struct sizes (28 vs 32 bytes)
- Fields at wrong offsets when using sizeof() in memcpy operations
- Message corruption when parsing received data

The wire-protocol alignment test cannot detect this because it only
checks wire format offsets, not platform-specific compiler behavior.

Solution:
--force-pack allows platforms to override the automatic detection and
force MAVPACKED on all message structures, ensuring identical layout
across platforms regardless of compiler alignment preferences.

Changes:
- Add --force-pack command line option to tools/mavgen.py
- Modify mavgen_c.py to accept opts parameter and check force_pack
- Apply MAVPACKED to all messages when force_pack is enabled
- Use mav_array_memcpy instead of type-specific assignment for safer
  memory handling with packed structures

The mav_array_memcpy change is applied universally (not architecture-specific)
to ensure consistent behavior. The old mav_array_assign_* functions still exist
but are now implemented as macros that call mav_array_memcpy, making this a
backward-compatible improvement that avoids alignment assumptions.

This ensures cross-platform compatibility while maintaining the existing
selective packing behavior for standard platforms.

Fixes struct alignment issues on ESP32 that caused MAVLink message
corruption due to unexpected padding bytes in struct layouts.
@Bwooce
Copy link
Author

Bwooce commented Aug 15, 2025

I've been chasing down MAVlink corruption issues on ESP32, and this was part of it, and a frustrating one because the pattern was not immediately obvious. Let me know if you want me to go a different way, or add more tests (where? I'd like to ensure wire-level consistency on all architectures tbh.).

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