Skip to content

Add libiio support#366

Open
m-kormann wants to merge 11 commits intomodelica-3rdparty:masterfrom
m-kormann:libiio
Open

Add libiio support#366
m-kormann wants to merge 11 commits intomodelica-3rdparty:masterfrom
m-kormann:libiio

Conversation

@m-kormann
Copy link

@m-kormann m-kormann commented Dec 2, 2022

Industrial I/O (https://wiki.analog.com/software/linux/docs/iio/iio) is a protocol to communicate with integrated devices.

This implementation allows to read sensor data from IIO devices locally or over network.

Summary by CodeRabbit

  • New Features
    • Introduced a new model that interfaces with a Pinephone’s inertial measurement unit to capture real-time acceleration data and simulate a virtual leveling indicator.
    • Added industrial I/O support, enabling improved sensor communication, configuration, and data reading via Linux-based connectivity.
    • Expanded the device driver library with enhanced error handling and integration of external I/O capabilities for robust performance.

@bernhard-thiele
Copy link
Collaborator

@m-kormann Thanks for offering this PR!

I have no experience with IIO and I will need to get my head around it first. Next days are pretty filled up, so please bear with me if it takes some time.

Seems IIO does similar things like Comedi. From the example, I understand that IIO can be used out-of-the-box on Pinephone and Raspberry Pi. Maybe you could drop a few lines about your motivation for using IIO and how it is positioned to Comedi?

@m-kormann
Copy link
Author

You are very welcome!

This example emerged from personal interest when I found that the data of the phone's gyroscope can be sent over network. This opens a lot of applications to real-time models.

From my understanding, Comedi is an interface to measurement with the help of certain hardware (even Soundcards) to measure voltages. It is restricted to the list of drivers available for the certain measurement hardware.

IIO is a layer above the I2C-Bus, which communicates with I/O hardware. As many arduino expansion boards (i.e. gyroscopes, magnetometers, proximity sensors) use I2C, a lot of devices, drivers and usage examples are available in the communities.

Copy link
Collaborator

@tbeu tbeu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only checked the header file so far and wondered about the usage of the static storage class which should be avoided. There are also some minor style and cosmetic issues.

@bernhard-thiele Did you find some time for evaluation?

tbeu
tbeu previously requested changes Apr 13, 2023
Copy link
Collaborator

@tbeu tbeu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more statics to be avoided.

@tbeu
Copy link
Collaborator

tbeu commented Aug 7, 2023

@bernhard-thiele Did you find some time for evaluation?

Bump.

@tbeu tbeu dismissed their stale review August 7, 2023 13:56

Resolved.

@tbeu tbeu requested a review from bernhard-thiele August 7, 2023 13:56
@bernhard-thiele
Copy link
Collaborator

@bernhard-thiele Did you find some time for evaluation?

No, I only had a superficial view on it. I think it would be cool, but since there was no pressing need to get it in and I have no experience with it, I procrastinated it. My first impression (now some time ago) was that there would be some work needed before it is "feature complete and ready". Unfortunately, at the moment there is not really time for me to work on it, so I'm not sure how to handle it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 8, 2025

Walkthrough

This pull request introduces several new Modelica models and components to integrate Industrial I/O (IIO) support. A new test model for hardware using InternetIO on Pinephone is added along with supporting blocks and configuration records for accessing IMU data. Additionally, new packages, classes, and functions are provided to wrap functionalities from the libiio library, including opening devices and channels, reading data, and managing device contexts. Package order files and header interfaces (both for libiio and custom MDDIIO functionality) have been updated to include these additions.

Changes

File(s) Change Summary
Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo
Modelica_DeviceDrivers/Blocks/Examples/package.order
Added new model TestHardwareIIO with a BullsEyeLevel submodel to access IMU data via InternetIO; updated package order entry.
Modelica_DeviceDrivers/Blocks/HardwareIO.mo Introduced new package IIO with a new record IIOConfig and block PhysicalDataRead for configuring IIO devices and reading real values.
Modelica_DeviceDrivers/HardwareIO/IIO.mo Added new class IIO encapsulating device connection management via external C functions (open/close).
Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo
Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo
Modelica_DeviceDrivers/HardwareIO/IIO_/package.order
Created new package IIO_ with an encapsulated function data_read to read data from IIO channels; updated accompanying package configuration.
Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo Added new class IIOchannel to manage IIO device channels, including constructors and destructors that open and close channels.
Modelica_DeviceDrivers/HardwareIO/package.order Updated package order by adding entries: IIO, IIOchannel, and IIO_.
Modelica_DeviceDrivers/Resources/Include/MDDIIO.h Introduced a new header defining functions and macros for IIO context and channel management (open, close, data read) with error handling.
Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h Added new header file for libiio, detailing structures, enums, and functions necessary for interfacing with IIO devices and channels.

Sequence Diagram(s)

sequenceDiagram
    participant TH as TestHardwareIIO
    participant PD as PhysicalDataRead
    participant IC as IIOchannel
    participant IIO as IIO
    participant Lib as MDDIIO/libiio

    TH->>PD: Initialize IMU data reading
    PD->>IC: Request to open channel
    IC->>IIO: Call "Open channel" (constructor)
    IIO->>Lib: Execute MDD_iio_open_channel
    Lib-->>IIO: Return channel handle
    IIO-->>IC: Pass channel handle
    IC-->>PD: Confirm channel is open
    PD->>Lib: Invoke data_read function
    Lib-->>PD: Return sensor data
    PD-->>TH: Supply acceleration data
Loading

Poem

I'm a happy rabbit, hopping with glee,
New codes and models are sprouting like a tree.
Channels open wide with a bouncy flair,
IIO magic fills the crisp air.
Through every function, I skip and roam—
Celebrating change in our digital home!
🐇💻 Hop on, hop on, to innovation’s bright dome!

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (11)
Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo (2)

2-4: Clarify function documentation for its purpose and return value
The high-level intent is clear ("Read from analog channel"), but the function could use additional contextual insight in its docstring about valid usage scenarios, potential edge cases, and an example of typical attribute reads (e.g., "scale", "raw", etc.).


7-8: Rename 'attrname' for better clarity
The parameter name attrname is documented as "Device name", which can be confusing. If it is specifically meant for channel attributes (e.g., "raw", "scale"), consider changing it to attributeName or clarifying its intended usage.

Modelica_DeviceDrivers/Blocks/HardwareIO.mo (3)

329-339: Ensure the documentation matches IIO usage rather than Comedi
In several places, the text references “comedi device,” e.g., in the annotation at line 338. Please confirm or update the documentation so that it accurately reflects this new IIO context and clarifies that deviceName is for an IIO device, not a Comedi device.


363-363: Rename or correct the parameter documentation
Currently documented as “Handle to comedi device,” but the parameter is actually holding an IIO context. Update the parameter description to say “Handle to IIO device” or similar.


398-399: Remove confusing reference to "Comedi function"
Line 399 mentions "Comedi function iio_channel_attr_read_double(..)", which appears to be a leftover doc mismatch. Change it to something like “Uses iio_channel_attr_read_double(...) from libiio” to avoid confusion.

Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo (1)

2-4: Consider adding usage details and platform constraints
The class docstring is concise. It may be helpful to emphasize any platform constraints (Linux vs. Windows) and mention typical usage scenarios for users unfamiliar with IIO channels.

Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo (3)

31-33: Improve initialization parameters for BullsEyeLevel.
Explicitly setting fixed=true and start=0 for theta and psi is often fine, but consider adjusting the initial angles or making them user-configurable in the model’s parameter dialog. That way, the user can easily shift the ball’s initial position if desired.


72-73: Clarify the 2D projection signs.
The negative sign in x2D[1] = -80*sin(theta)*sin(psi); might be intentional, but a short inline comment could help future contributors understand the orientation or reference frame for this top view.


97-100: Expand the documentation with step-by-step setup instructions.
The documentation references installing iiod and mentions it works out of the box, but adding short instructions (e.g., how to configure mobian.local, start the daemon, or define mpu6050 channels) will help users new to IIO set up the environment more easily.

Modelica_DeviceDrivers/HardwareIO/IIO.mo (1)

6-14: Ensure robustness in the constructor.
Currently, the constructor depends on the internal macro-based error handling in C (via MDD_iio_open). While typical in Modelica, consider handling or propagating an error state back to the user in Modelica if the external function fails (e.g., if libiio is unavailable).

Modelica_DeviceDrivers/Resources/Include/MDDIIO.h (1)

23-34: Avoid overshadowing error messages with a single macro.
The usage of IIO_ENSURE for multiple assignments (e.g., ctx = iio_create_network_context(...)) can be slightly less readable for external collaborators. A more explicit approach could improve maintainability:

  • First check that the function call is successful.
  • Then log or raise an error if needed.

This refinement helps keep context and error-handling logic clear.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c8dd60 and 992fb43.

📒 Files selected for processing (11)
  • Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo (1 hunks)
  • Modelica_DeviceDrivers/Blocks/Examples/package.order (1 hunks)
  • Modelica_DeviceDrivers/Blocks/HardwareIO.mo (1 hunks)
  • Modelica_DeviceDrivers/HardwareIO/IIO.mo (1 hunks)
  • Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo (1 hunks)
  • Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo (1 hunks)
  • Modelica_DeviceDrivers/HardwareIO/IIO_/package.order (1 hunks)
  • Modelica_DeviceDrivers/HardwareIO/IIOchannel.mo (1 hunks)
  • Modelica_DeviceDrivers/HardwareIO/package.order (1 hunks)
  • Modelica_DeviceDrivers/Resources/Include/MDDIIO.h (1 hunks)
  • Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
Modelica_DeviceDrivers/Resources/Include/MDDIIO.h (1)
Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h (7)
  • iio_create_network_context (437-437)
  • iio_create_local_context (408-408)
  • iio_context_get_devices_count (578-579)
  • iio_context_destroy (500-500)
  • iio_context_find_device (598-599)
  • iio_device_find_channel (702-703)
  • iio_channel_attr_read_double (1252-1253)
🔇 Additional comments (9)
Modelica_DeviceDrivers/HardwareIO/package.order (1)

3-5: IIO-related entries added correctly to package order

The entries for IIO, IIOchannel, and IIO_ have been properly added to the package order file, which is necessary for their inclusion in the Modelica package structure. This aligns with the PR objective of adding Industrial I/O (IIO) protocol support.

Modelica_DeviceDrivers/HardwareIO/IIO_/package.order (1)

1-1: Entry for data_read function properly added

The data_read function is correctly listed in the package order file, which is necessary to expose the function in the IIO_ package. This is consistent with the implementation of the data reading capability mentioned in the PR objectives.

Modelica_DeviceDrivers/Blocks/Examples/package.order (1)

19-19: Test case added to package order

The TestHardwareIIO entry has been appropriately added to the Examples package order file. It's correctly positioned after the similar TestHardwareIOComedi entry, maintaining a logical organization in the file.

Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo (1)

1-5:

Details

✅ Verification successful

IIO_ package structure is well-defined

The package declaration is appropriately structured with proper namespace (within Modelica_DeviceDrivers.HardwareIO) and includes a descriptive documentation string. The extension of DriverIcon maintains consistency with other driver implementations in the library.

However, the package appears to be empty at this point, containing only the package declaration but no actual implementation or components. The package.order file suggests a data_read function should be included, but it's not present in this file.


🏁 Script executed:

#!/bin/bash
# Check if the data_read function is implemented in a separate file
echo "Checking for the data_read.mo file in the IIO_ directory:"
find Modelica_DeviceDrivers/HardwareIO/IIO_ -name "data_read.mo" -type f

Length of output: 249


IIO_ package structure verification complete

  • The package declaration in Modelica_DeviceDrivers/HardwareIO/IIO_/package.mo is correct, with appropriate namespacing and extension of DriverIcon.
  • Although the package file itself is minimal, the expected data_read function is implemented in the separate file data_read.mo (located in Modelica_DeviceDrivers/HardwareIO/IIO_), aligning with the design indicated by the package.order file.
Modelica_DeviceDrivers/HardwareIO/IIO_/data_read.mo (1)

10-10: Verify error handling of the external function call
There is no handling for potential errors or invalid return values from MDD_iio_data_read. Consider verifying that unexpected conditions (e.g., non-existent attribute) are handled gracefully in upstream or downstream code.

Modelica_DeviceDrivers/Blocks/Examples/TestHardwareIIO.mo (2)

6-7: Consider validating the connection in Modelica code.
Currently, the iio(deviceName="mobian.local") block does not handle connection failures or missing devices if the device name is incorrect or unreachable. Making the model robust against these issues (e.g., by exposing an error output or providing a fallback) will improve the user experience.

Would you like me to generate a script to search for usage of this device name to see if any fallback is implemented in other parts of the code?


67-68: Double-check division by zero logic.
You already use max(Modelica.Constants.eps, d/2 * sin(theta)) to avoid dividing by zero. Ensure that d or theta can’t be externally modified to zero in a way that produces undesired numeric instabilities.

Modelica_DeviceDrivers/HardwareIO/IIO.mo (1)

16-23: Validate destructor usage.
Destroying an already closed or invalid IIO context might lead to undefined behavior if the call chain from Modelica triggers it multiple times. If feasible in Modelica, confirm that the destructor is only called once or handle repeated destructor calls gracefully in C.

Modelica_DeviceDrivers/Resources/thirdParty/libiio/iio.h (1)

1-1975: Confirm third-party licensing and references.
This file is marked with LGPL-2.1-or-later and references Analog Devices, Inc. Typically, third-party headers should remain unmodified to maintain license compliance. Ensure that you have included any required license text, disclaimers, or references in your repository according to that license’s terms.

Do you want me to generate a script to scan your repository for license headers and confirm all references to “LGPL-2.1-or-later” are present where required?

Comment on lines +378 to +379
rawData = Modelica_DeviceDrivers.HardwareIO.IIO_.data_read(channel, "raw");
y = scaleData*rawData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Handle potential errors or invalid data when reading attributes
Reading "raw" or "scale" could fail or yield invalid data if the attribute is unavailable. Consider adding checks or fallback logic to handle such cases.

Comment on lines +19 to +24
encapsulated function destructor "Close channel"
import Modelica;
extends Modelica.Icons.Function;
import Modelica_DeviceDrivers.HardwareIO.IIOchannel;
input IIOchannel channel "Channel context";
end destructor;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Implement actual channel closure logic
The destructor is empty and doesn’t invoke a corresponding external function to close or free resources. This could lead to resource leaks.

Below is a possible fix for calling a matching external function (assuming one exists, e.g., MDD_iio_close_channel):

 encapsulated function destructor "Close channel"
   import Modelica;
   extends Modelica.Icons.Function;
   import Modelica_DeviceDrivers.HardwareIO.IIOchannel;
   input IIOchannel channel "Channel context";
-end destructor;
+external "C" MDD_iio_close_channel(channel)
+  annotation (Include="#include \"MDDIIO.h\"", Library="libiio");
+end destructor;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
encapsulated function destructor "Close channel"
import Modelica;
extends Modelica.Icons.Function;
import Modelica_DeviceDrivers.HardwareIO.IIOchannel;
input IIOchannel channel "Channel context";
end destructor;
encapsulated function destructor "Close channel"
import Modelica;
extends Modelica.Icons.Function;
import Modelica_DeviceDrivers.HardwareIO.IIOchannel;
input IIOchannel channel "Channel context";
external "C" MDD_iio_close_channel(channel)
annotation (Include="#include \"MDDIIO.h\"", Library="libiio");
end destructor;

else {
IIO_ENSURE(ctx = iio_create_local_context(), "Could not open IIO host", "locally");
}
IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Revisit the device-count assumption.
iio_context_get_devices_count(ctx) > 3 might be too strict for some boards or minimal setups. If a device has fewer than four channels, this check will erroneously fail. Consider making this condition configurable or removing it unless you’re certain every supported IIO device must have at least four recognized channels.

-    IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname);
+    IIO_ENSURE(iio_context_get_devices_count(ctx) > 0, "No devices found at host", targetname);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
IIO_ENSURE(iio_context_get_devices_count(ctx) > 3, "No devices found at host", targetname);
IIO_ENSURE(iio_context_get_devices_count(ctx) > 0, "No devices found at host", targetname);

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants