Skip to content

Renode chip binding: VsxState and VsxCounters are sized for virtual-sx1262 ABI 1.3, and a 1.4+ library overruns them #747

Open

Description

@A13xB0

What happens

The Renode peripheral passes fixed-size C# structs to the chip library as out parameters:

  • tools/renode/peripherals/VirtualSX1262Lib.cs:36 — struct VsxState, laid out for ABI 1.3
  • tools/renode/peripherals/VirtualSX1262Lib.cs:53 — struct VsxCounters, six uint fields
  • VirtualSX1262Lib.cs:130-131 — GetStateFn(IntPtr, out VsxState) and GetCountersFn(IntPtr, out VsxCounters)
  • VirtualSX1262Engine.cs:221-222 — the calls

From ABI 1.4 onward (MeshBench/virtual-sx1262#2) both C structs are longer:

  • vsx_counters gains irq_suppressed, cad_runs, cad_detections, sync_mismatches, params_rejected and three stat_* fields (include/virtual_sx1262.h:207-236)
  • vsx_state gains invert_iq, rx_duty_rx_period, rx_duty_sleep_period and more (include/virtual_sx1262.h, ending at line 203)

The version check at VirtualSX1262Lib.cs:87 (major != AbiMajor || minor < AbiMinor, with AbiMinor = 3) accepts 1.6, so the library loads and vsx_get_state / vsx_get_counters write past the end of the C# structs. That doesn't fail cleanly; it corrupts whatever sits beyond them.

The pin is still v1.3.1 (internal/app/resource/toolchaincatalogue.go:26), so nothing breaks today. Bumping the pin is what triggers it.

Also

VirtualSX1262Engine.cs builds a 39-byte radio stats record and stops there. It writes neither ConsoleBaud (bytes 39-42) nor the irq_suppressed count (43-46) that #745 reads, so Renode nodes would report irq_suppressed: null while running a chip that enforces the mask.

Proposed fix

Before bumping the virtual-sx1262 pin past 1.3.x:

  1. Bring VsxState and VsxCounters up to the 1.6 layout field for field, and raise AbiMinor to 6.
  2. Extend the stats record in VirtualSX1262Engine.cs to 47 bytes: ConsoleBaud, if Renode has one, else zero, then irq_suppressed.
  3. Worth considering on the virtual-sx1262 side: have vsx_get_state / vsx_get_counters take the caller's struct size, so that adding a field to the end is actually additive for a caller with a fixed buffer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions