-
Notifications
You must be signed in to change notification settings - Fork 127
feat(holocat): Add EtherCAT application #1284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add HoloCat application that integrates EtherCAT real-time communication with NVIDIA's Holoscan streaming framework. Key Features: - Real-time EtherCAT master implementation using EC-Master SDK - Holoscan operator architecture with periodic scheduling - Data flow integration between EtherCAT and Holoscan operators - Configurable cycle times and real-time priorities - Docker containerization with proper capabilities (in-progress) Components: - HolocatOp: Main EtherCAT operator with state machine management - HcDataTxOp: Data transmission operator for counter generation - HcDataRxOp: Data reception operator for processing received data - Comprehensive configuration system with validation - Build system integration with CMake and Docker This enables real-time industrial automation applications using EtherCAT fieldbus communication within the Holoscan ecosystem.
WalkthroughAdds a new "holocat" application integrating EtherCAT real-time control with Holoscan. Includes CMake build configuration with conditional EC-Master SDK support, a custom CMake find module, three Holoscan operators for data flow, comprehensive YAML/XML configuration files, Docker containerization, verification scripts, and documentation. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Suggested reviewers
Pre-merge checks✅ Passed checks (2 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 17
🧹 Nitpick comments (15)
applications/holocat/README.md (1)
26-26: Replace hardcoded path with placeholder.The ECMASTER_ROOT path is user-specific and should use a placeholder instead.
Apply this diff:
-export ECMASTER_ROOT=/home/hking/devel/ethercat/ecm +export ECMASTER_ROOT=/path/to/ec-master-sdkapplications/holocat/cpp/hc_data_rx_op.hpp (1)
19-20: Clarify data source in documentation.The documentation states the operator "receives integer data from the ECat bus," but based on the operator architecture, it actually receives data from another Holoscan operator (HolocatOp). Consider clarifying the data flow.
Example:
- * A Holoscan operator that receives integer data from the ECat bus. - * This operator acts as a data receiver, receiving integer values from the ECat bus. + * A Holoscan operator that receives integer data from the HolocatOp. + * This operator acts as a data receiver in the Holocat data flow pipeline.applications/holocat/configs/holocat_config.yaml (2)
5-5: Use generic adapter name in example configuration.The adapter name appears to be a specific hardware MAC-based identifier. For an example configuration file, use a more generic placeholder.
Apply this diff:
- adapter_name: "enxc84bd6d2788c" + adapter_name: "eth0" # Change to your EtherCAT interfaceNote: This matches the placeholder used in the README example.
9-9: Replace hardcoded path with relative or placeholder path.The ENI file path contains a user-specific absolute path. Use a relative path or generic placeholder.
Apply this diff:
- eni_file: "/home/hking/devel/holo/holohub/applications/holocat/configs/eni2.xml" + eni_file: "applications/holocat/configs/eni2.xml"Or use an environment variable placeholder as suggested in the comment above.
applications/holocat/CMakeLists.txt (1)
1-30: Add testing section for functional tests.Per coding guidelines, applications should include a testing section in CMakeLists.txt for functional testing using CTest.
As per coding guidelines, applications should include testing.
Consider adding after the
add_subdirectory(cpp)line:# Testing if(BUILD_TESTING) add_subdirectory(tests) endif()applications/holocat/configs/eni2.xml (1)
1-1: Document the example ENI configuration.This ENI file appears to be for specific hardware (simco drive 40028083-00-0 and WAGO 750-354). Consider adding a comment or separate README in the configs directory explaining that this is an example configuration and users must generate their own ENI file for their specific EtherCAT hardware setup.
Consider adding
applications/holocat/configs/README.md:# EtherCAT Configuration Files ## eni2.xml This is an example EtherCAT Network Information (ENI) file for: - SubDevice_1001: simco drive 40028083-00-0 - SubDevice_1002: WAGO 750-354 I/O module **Important**: You must generate your own ENI file matching your specific EtherCAT hardware configuration using EtherCAT configuration tools (e.g., TwinCAT, EC-Engineer, or acontis EC-Engineer).applications/holocat/cpp/CMakeLists.txt (1)
1-89: Missing CTest integration for functional testing.Per coding guidelines, applications should include a testing section in CMakeLists.txt for functional testing using CTest.
Consider adding a testing section:
# Testing if(BUILD_TESTING) enable_testing() # Add test cases here endif()applications/holocat/cpp/hc_data_tx_op.cpp (1)
28-30: Counter starts at 1, not 0.The counter increments before use, so the first emitted value is
1, not0. If starting at0is intended, consider swapping the order:- // Increment counter - counter_++; - counter_ = counter_ % kMaxCount; - // Emit current counter value op_output.emit<int>(counter_, "count_out"); + + // Increment counter for next cycle + counter_ = (counter_ + 1) % kMaxCount;applications/holocat/cpp/hc_data_rx_op.cpp (1)
33-34: INFO-level logging on every cycle may be excessive.In a real-time system with fast cycle times, logging at INFO level on every received value will flood logs and potentially impact performance. Consider using DEBUG level similar to
HcDataTxOp.last_count_ = maybe_count.value(); - HOLOSCAN_LOG_INFO("HcDataRxOp: Received count: {}", last_count_); + // Log periodically to avoid spam + if (last_count_ % 50 == 0) { + HOLOSCAN_LOG_DEBUG("HcDataRxOp: 50x Received count = {}", last_count_); + }applications/holocat/cpp/holocat_op.cpp (3)
175-182: Blockingsleep(1)instop()delays shutdown.Using
sleep(1)blocks the calling thread unconditionally. Consider using a non-blocking approach or reducing the delay if waiting for async completion.pending_state_transition_ = std::async(std::launch::async, [this]() { return ecatSetMasterState(kEthercatStateChangeTimeout_, eEcatState_INIT); }); - sleep(1); + // Wait for state transition to complete with timeout + if (pending_state_transition_.wait_for(std::chrono::seconds(5)) == std::future_status::timeout) { + HOLOSCAN_LOG_WARN("State transition to INIT timed out during stop"); + } + // deinitialize master ecatDeinitMaster();
350-364: Static local variable incompute()is not thread-safe.The
static struct timespec t_lastis shared across all invocations. If multipleHolocatOpinstances run concurrently or the operator is restarted, timing calculations will be incorrect.Consider making
t_lasta member variable initialized instart():+// In class declaration (holocat_op.hpp): + struct timespec t_last_{}; + +// In start(): + clock_gettime(CLOCK_MONOTONIC, &t_last_); + // In compute(): struct timespec t_now; clock_gettime(CLOCK_MONOTONIC, &t_now); - static struct timespec t_last{t_now.tv_sec, t_now.tv_nsec}; ... - t_last = t_now; + t_last_ = t_now;
311-347: EtherCAT job results are silently discarded.The return values from
ecatExecJobcalls are assigned todwResbut then immediately suppressed withEC_UNREFPARM. While this may be intentional for polling mode, consider logging errors at DEBUG level to aid troubleshooting.dwRes = ecatExecJob(eUsrJob_ProcessAllRxFrames, EC_NULL); - EC_UNREFPARM(dwRes); + if (dwRes != EC_E_NOERROR) { + HOLOSCAN_LOG_DEBUG("ProcessAllRxFrames returned: {} (0x{:x})", ecatGetText(dwRes), dwRes); + }applications/holocat/cpp/holocat_app.cpp (2)
72-78: Clarify comment about uninitialized values.The comment "target remains uninitialized" is misleading since
HolocatConfig config = {}value-initializes all members (empty strings, zeros, false). The behavior is correct but the comment should reflect the actual semantics.auto try_extract = [this](const std::string& key, auto& target) { try { target = from_config(key).as<std::decay_t<decltype(target)>>(); } catch (...) { - // Key not found or conversion failed - target remains uninitialized + // Key not found or conversion failed - target retains default value } };
42-47: Consider making the counter update period configurable.The 100ms period for
HcDataTxOpis hardcoded. For flexibility, consider adding this as a configuration parameter similar tocycle_time_us.applications/holocat/cpp/holocat_op.hpp (1)
10-11: Consider using conventional include guard naming.The include guard
INC_HOLOCAT_Hwith value1is unconventional. A more standard pattern would match the filename.-#ifndef INC_HOLOCAT_H -#define INC_HOLOCAT_H 1 +#ifndef HOLOCAT_OP_HPP +#define HOLOCAT_OP_HPPAnd update the closing guard:
-#endif /* INC_HOLOCAT_H */ +#endif // HOLOCAT_OP_HPP
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (19)
applications/CMakeLists.txt(1 hunks)applications/holocat/CMakeLists.txt(1 hunks)applications/holocat/Dockerfile(1 hunks)applications/holocat/FindEcMaster.cmake(1 hunks)applications/holocat/README.md(1 hunks)applications/holocat/configs/eni2.xml(1 hunks)applications/holocat/configs/holocat_config.yaml(1 hunks)applications/holocat/cpp/CMakeLists.txt(1 hunks)applications/holocat/cpp/hc_data_rx_op.cpp(1 hunks)applications/holocat/cpp/hc_data_rx_op.hpp(1 hunks)applications/holocat/cpp/hc_data_tx_op.cpp(1 hunks)applications/holocat/cpp/hc_data_tx_op.hpp(1 hunks)applications/holocat/cpp/holocat_app.cpp(1 hunks)applications/holocat/cpp/holocat_app.hpp(1 hunks)applications/holocat/cpp/holocat_op.cpp(1 hunks)applications/holocat/cpp/holocat_op.hpp(1 hunks)applications/holocat/cpp/main.cpp(1 hunks)applications/holocat/metadata.json(1 hunks)applications/holocat/scripts/verify_ecmaster.sh(1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
{operators,applications,workflows,gxf_extensions}/**/*.{py,cpp,hpp}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
{operators,applications,workflows,gxf_extensions}/**/*.{py,cpp,hpp}: All code must adhere to Holoscan SDK coding standards including proper error handling and validation
Use descriptive English naming for functions, variables, and components; minimize acronyms and brand names
Include inline comments for complex logic in code
Files:
applications/holocat/cpp/hc_data_rx_op.hppapplications/holocat/cpp/hc_data_tx_op.hppapplications/holocat/cpp/main.cppapplications/holocat/cpp/holocat_op.cppapplications/holocat/cpp/holocat_op.hppapplications/holocat/cpp/holocat_app.cppapplications/holocat/cpp/hc_data_tx_op.cppapplications/holocat/cpp/hc_data_rx_op.cppapplications/holocat/cpp/holocat_app.hpp
{operators,applications,workflows,gxf_extensions}/**/*.{py,cpp,hpp,cmake}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
All code must compile and build successfully on target platforms before submission
Files:
applications/holocat/cpp/hc_data_rx_op.hppapplications/holocat/cpp/hc_data_tx_op.hppapplications/holocat/cpp/main.cppapplications/holocat/cpp/holocat_op.cppapplications/holocat/cpp/holocat_op.hppapplications/holocat/cpp/holocat_app.cppapplications/holocat/cpp/hc_data_tx_op.cppapplications/holocat/cpp/hc_data_rx_op.cppapplications/holocat/cpp/holocat_app.hppapplications/holocat/FindEcMaster.cmake
{operators,applications,workflows,gxf_extensions,tutorials}/**/README.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
README.md must include purpose, usage instructions, requirements, examples, and architecture overview
Files:
applications/holocat/README.md
**/*.md
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Use Holoscan SDK glossary terms when referring to HoloHub-specific locations in documentation
Files:
applications/holocat/README.md
**/metadata.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
When reviewing PRs that modify or add
metadata.jsonfiles, verify that the category (first tag in thetagsarray) matches one of the approved categories: Benchmarking, Camera, Computer Vision and Perception, Converter, Deployment, Development, Extended Reality, Healthcare AI, Image Processing, Inference, Interoperability, Medical Imaging, Natural Language and Conversational AI, Networking and Distributed Computing, Optimization, Quantum Computing, Rendering, Robotics, Scheduler, Signal Processing, Streaming, Threading, Video, Video Capture, Visualization, XR
**/metadata.json: Useinterfaceor specific metadata schema for defining contribution structure (metadata.json)
metadata.json must include name, authors, language, version, changelog, holoscan_sdk info, platforms, tags, ranking, dependencies, and run command
metadata.json ranking levels must be self-assessed from 0 (production-ready) to 5 (deprecated) with corresponding requirements
Dependencies must be correctly specified in metadata.json dependencies section
Files:
applications/holocat/metadata.json
{applications,workflows}/**/CMakeLists.txt
📄 CodeRabbit inference engine (CONTRIBUTING.md)
CMakeLists.txt must include build system integration using add_holohub_application() for applications and workflows
Files:
applications/holocat/CMakeLists.txtapplications/CMakeLists.txtapplications/holocat/cpp/CMakeLists.txt
applications/**/CMakeLists.txt
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Applications should include a testing section in CMakeLists.txt for functional testing using CTest
Files:
applications/holocat/CMakeLists.txtapplications/CMakeLists.txtapplications/holocat/cpp/CMakeLists.txt
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to operators/**/CMakeLists.txt : CMakeLists.txt must include build system integration using add_holohub_operator() for operators
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to {applications,workflows}/**/CMakeLists.txt : CMakeLists.txt must include build system integration using add_holohub_application() for applications and workflows
Learnt from: cdinea
Repo: nvidia-holoscan/holohub PR: 1170
File: operators/video_streaming/streaming_client_enhanced/python/CMakeLists.txt:16-24
Timestamp: 2025-10-22T16:53:45.393Z
Learning: The pybind11_add_holohub_module CMake macro in cmake/pybind11_add_holohub_module.cmake encapsulates all pybind11 setup internally, including finding pybind11, linking against holoscan::pybind11 conditionally, and linking the C++ operator target. Operator Python bindings in holohub should only call this macro without additional pybind11 setup.
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to operators/**/CMakeLists.txt : CMakeLists.txt must include build system integration using add_holohub_operator() for operators
Applied to files:
applications/holocat/cpp/hc_data_rx_op.hppapplications/holocat/cpp/hc_data_tx_op.hppapplications/holocat/CMakeLists.txtapplications/CMakeLists.txtapplications/holocat/cpp/holocat_op.hppapplications/holocat/cpp/hc_data_tx_op.cppapplications/holocat/cpp/hc_data_rx_op.cppapplications/holocat/cpp/CMakeLists.txt
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to {operators,applications,workflows,gxf_extensions}/**/*.{py,cpp,hpp} : All code must adhere to Holoscan SDK coding standards including proper error handling and validation
Applied to files:
applications/holocat/cpp/hc_data_rx_op.hppapplications/holocat/cpp/holocat_op.hppapplications/holocat/cpp/holocat_app.cppapplications/holocat/cpp/hc_data_rx_op.cpp
📚 Learning: 2025-11-24T16:28:06.281Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.281Z
Learning: Applies to **/metadata.json : metadata.json must include name, authors, language, version, changelog, holoscan_sdk info, platforms, tags, ranking, dependencies, and run command
Applied to files:
applications/holocat/metadata.json
📚 Learning: 2025-11-24T16:27:43.600Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T16:27:43.600Z
Learning: Applies to **/metadata.json : When reviewing PRs that modify or add `metadata.json` files, verify that the **category** (first tag in the `tags` array) matches one of the approved categories: Benchmarking, Camera, Computer Vision and Perception, Converter, Deployment, Development, Extended Reality, Healthcare AI, Image Processing, Inference, Interoperability, Medical Imaging, Natural Language and Conversational AI, Networking and Distributed Computing, Optimization, Quantum Computing, Rendering, Robotics, Scheduler, Signal Processing, Streaming, Threading, Video, Video Capture, Visualization, XR
Applied to files:
applications/holocat/metadata.json
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to {applications,workflows}/**/CMakeLists.txt : CMakeLists.txt must include build system integration using add_holohub_application() for applications and workflows
Applied to files:
applications/holocat/CMakeLists.txtapplications/CMakeLists.txtapplications/holocat/cpp/CMakeLists.txt
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to gxf_extensions/**/CMakeLists.txt : CMakeLists.txt must include build system integration using add_holohub_extension() for GXF extensions
Applied to files:
applications/holocat/CMakeLists.txtapplications/CMakeLists.txtapplications/holocat/cpp/CMakeLists.txt
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to applications/**/CMakeLists.txt : Applications should include a testing section in CMakeLists.txt for functional testing using CTest
Applied to files:
applications/holocat/CMakeLists.txtapplications/CMakeLists.txt
📚 Learning: 2025-11-24T16:28:06.281Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.281Z
Learning: Applies to applications/**/ : Applications should follow the directory structure with metadata.json, README.md, implementation files, and CMakeLists.txt
Applied to files:
applications/holocat/CMakeLists.txtapplications/CMakeLists.txt
📚 Learning: 2025-10-22T16:53:45.393Z
Learnt from: cdinea
Repo: nvidia-holoscan/holohub PR: 1170
File: operators/video_streaming/streaming_client_enhanced/python/CMakeLists.txt:16-24
Timestamp: 2025-10-22T16:53:45.393Z
Learning: The pybind11_add_holohub_module CMake macro in cmake/pybind11_add_holohub_module.cmake encapsulates all pybind11 setup internally, including finding pybind11, linking against holoscan::pybind11 conditionally, and linking the C++ operator target. Operator Python bindings in holohub should only call this macro without additional pybind11 setup.
Applied to files:
applications/CMakeLists.txt
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Each operator should have at least one associated application demonstrating its capabilities
Applied to files:
applications/CMakeLists.txt
📚 Learning: 2025-11-24T16:28:06.280Z
Learnt from: CR
Repo: nvidia-holoscan/holohub PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-24T16:28:06.280Z
Learning: Applies to operators/**/*.{py,cpp,hpp} : Use TitleCase + 'Op' suffix for operator class names
Applied to files:
applications/holocat/cpp/holocat_op.hpp
🧬 Code graph analysis (3)
applications/holocat/cpp/hc_data_rx_op.hpp (2)
applications/holocat/cpp/hc_data_tx_op.hpp (2)
spec(40-40)op_input(48-50)applications/holocat/cpp/holocat_op.hpp (2)
spec(63-63)op_input(65-67)
applications/holocat/cpp/hc_data_tx_op.hpp (2)
applications/holocat/cpp/hc_data_rx_op.hpp (2)
spec(38-38)op_input(46-48)applications/holocat/cpp/holocat_op.hpp (2)
spec(63-63)op_input(65-67)
applications/holocat/cpp/holocat_op.hpp (3)
applications/holocat/cpp/holocat_app.hpp (1)
config(25-25)applications/holocat/cpp/hc_data_rx_op.hpp (2)
spec(38-38)op_input(46-48)applications/holocat/cpp/hc_data_tx_op.hpp (2)
spec(40-40)op_input(48-50)
🪛 Cppcheck (2.18.0)
applications/holocat/cpp/main.cpp
[error] 55-55: There is an unknown macro here somewhere. Configuration is required. If HOLOSCAN_OPERATOR_FORWARD_ARGS is a macro then please configure it.
(unknownMacro)
applications/holocat/cpp/holocat_op.cpp
[error] 55-55: There is an unknown macro here somewhere. Configuration is required. If HOLOSCAN_OPERATOR_FORWARD_ARGS is a macro then please configure it.
(unknownMacro)
applications/holocat/cpp/holocat_app.cpp
[error] 55-55: There is an unknown macro here somewhere. Configuration is required. If HOLOSCAN_OPERATOR_FORWARD_ARGS is a macro then please configure it.
(unknownMacro)
🔇 Additional comments (14)
applications/CMakeLists.txt (1)
152-152: LGTM!The holocat application is correctly integrated using
add_holohub_application()and positioned in proper alphabetical order.As per coding guidelines, CMakeLists.txt correctly uses add_holohub_application().
applications/holocat/cpp/holocat_app.hpp (1)
1-28: LGTM!The application class is properly structured, inheriting from holoscan::Application with appropriate method declarations for configuration extraction and validation.
applications/holocat/cpp/hc_data_tx_op.cpp (1)
17-22: LGTM!The setup method correctly configures the output port with appropriate logging.
applications/holocat/scripts/verify_ecmaster.sh (1)
1-221: Well-structured verification script.Comprehensive SDK validation covering directory structure, libraries, version extraction, and system requirements. The colored output and clear next steps guidance are helpful.
applications/holocat/cpp/main.cpp (1)
54-74: LGTM!Clean argument parsing with proper error handling for missing values and unknown options.
applications/holocat/cpp/holocat_op.cpp (1)
32-59: LGTM!The logging bridge correctly maps EC-Master severity levels to Holoscan logging with appropriate prefixing.
applications/holocat/Dockerfile (2)
29-31: User permissions are appropriately configured.The holocat user creation with scoped NOPASSWD access for
setcapis appropriate for granting real-time capabilities to the application without requiring full root access during normal operation.
45-49: Verification fallback logic is sensible.The approach of running the full verification script with a fallback to minimal SDK checks (header and library existence) provides build resilience while still ensuring essential components are present.
applications/holocat/FindEcMaster.cmake (2)
123-137: Imported target is correctly defined.The
EcMaster::EcMasterimported target follows CMake conventions with proper interface properties for include directories and link libraries.
1-16: Well-structured CMake find module.Good use of policy handling for CMP0144 (environment variable handling) and clear documentation of the module's outputs.
applications/holocat/cpp/holocat_app.cpp (1)
140-154: Priority validation handles defaults correctly.The validation properly detects zero-initialized priorities (from missing config) and applies sensible defaults with appropriate warning logs.
applications/holocat/cpp/holocat_op.hpp (3)
24-38: Configuration struct is well-organized.The
HolocatConfigstruct clearly groups related configuration parameters. Includingerror_messagefor validation feedback is a pragmatic approach.
53-68: Operator class follows Holoscan conventions.The
HolocatOpclass correctly derives fromholoscan::Operator, uses theHOLOSCAN_OPERATOR_FORWARD_ARGSmacro for constructor forwarding, and follows the TitleCase + 'Op' naming convention per coding guidelines.
105-118: Async state transition design is appropriate for real-time operation.Using
std::futurefor pending state transitions allows the operator to maintain real-time scheduling while managing the EtherCAT state machine asynchronously.
| message(FATAL_ERROR "EC-Master SDK not found") | ||
|
|
||
| # Exit with failure | ||
| exit(1) | ||
| endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove invalid exit() command.
exit(1) is not a valid CMake command. The message(FATAL_ERROR ...) on line 26 already halts CMake configuration, making line 29 unreachable and incorrect.
Apply this diff:
else()
message(FATAL_ERROR "EC-Master SDK not found")
-
- # Exit with failure
- exit(1)
endif()📝 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.
| message(FATAL_ERROR "EC-Master SDK not found") | |
| # Exit with failure | |
| exit(1) | |
| endif() | |
| else() | |
| message(FATAL_ERROR "EC-Master SDK not found") | |
| endif() |
🤖 Prompt for AI Agents
In applications/holocat/CMakeLists.txt around lines 26 to 30, remove the invalid
exit(1) call since CMake does not have exit() and message(FATAL_ERROR "EC-Master
SDK not found") already stops configuration; simply delete the exit(1) line so
the FATAL_ERROR stands alone and there is no unreachable/incorrect command.
| # Create executable | ||
| add_executable(holocat ${HOLOCAT_SOURCES} ${HOLOCAT_HEADERS}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Missing add_holohub_application() build system integration.
Per HoloHub coding guidelines, applications must use add_holohub_application() for proper build system integration instead of raw add_executable(). This ensures consistent build behavior and integration with the HoloHub infrastructure.
Based on learnings, the CMakeLists.txt should include build system integration using add_holohub_application().
🤖 Prompt for AI Agents
In applications/holocat/cpp/CMakeLists.txt around lines 47-48, the build
currently calls add_executable(holocat ${HOLOCAT_SOURCES} ${HOLOCAT_HEADERS})
which violates HoloHub guidelines; replace this raw add_executable call with the
prescribed add_holohub_application() invocation, passing the same target name
and source/header lists (and any required properties or options the HoloHub
macro expects) so the holocat target is registered through the HoloHub build
integration rather than created directly.
| option(HOLOCAT_SET_CAPABILITIES "Set Linux capabilities during build" ON) | ||
| if(HOLOCAT_SET_CAPABILITIES) | ||
| add_custom_command(TARGET holocat POST_BUILD | ||
| COMMAND sudo setcap 'cap_net_raw,cap_sys_nice,cap_ipc_lock=ep' $<TARGET_FILE:holocat> | ||
| COMMENT "Setting capabilities for real-time EtherCAT operation" | ||
| ) | ||
| endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sudo in POST_BUILD will break non-privileged builds.
Using sudo in a CMake post-build command requires interactive authentication and will fail in CI/CD pipelines, containers without sudo, or when users lack sudo access. Consider making this a separate script or installation step rather than part of the build.
-option(HOLOCAT_SET_CAPABILITIES "Set Linux capabilities during build" ON)
+option(HOLOCAT_SET_CAPABILITIES "Set Linux capabilities during build" OFF)
if(HOLOCAT_SET_CAPABILITIES)
+ message(WARNING "HOLOCAT_SET_CAPABILITIES requires sudo privileges - ensure you have appropriate access")
add_custom_command(TARGET holocat POST_BUILD
COMMAND sudo setcap 'cap_net_raw,cap_sys_nice,cap_ipc_lock=ep' $<TARGET_FILE:holocat>
COMMENT "Setting capabilities for real-time EtherCAT operation"
)
endif()Alternatively, provide a separate install script that users can run manually with appropriate privileges.
📝 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.
| option(HOLOCAT_SET_CAPABILITIES "Set Linux capabilities during build" ON) | |
| if(HOLOCAT_SET_CAPABILITIES) | |
| add_custom_command(TARGET holocat POST_BUILD | |
| COMMAND sudo setcap 'cap_net_raw,cap_sys_nice,cap_ipc_lock=ep' $<TARGET_FILE:holocat> | |
| COMMENT "Setting capabilities for real-time EtherCAT operation" | |
| ) | |
| endif() | |
| option(HOLOCAT_SET_CAPABILITIES "Set Linux capabilities during build" OFF) | |
| if(HOLOCAT_SET_CAPABILITIES) | |
| message(WARNING "HOLOCAT_SET_CAPABILITIES requires sudo privileges - ensure you have appropriate access") | |
| add_custom_command(TARGET holocat POST_BUILD | |
| COMMAND sudo setcap 'cap_net_raw,cap_sys_nice,cap_ipc_lock=ep' $<TARGET_FILE:holocat> | |
| COMMENT "Setting capabilities for real-time EtherCAT operation" | |
| ) | |
| endif() |
🤖 Prompt for AI Agents
In applications/holocat/cpp/CMakeLists.txt around lines 83-89, remove the use of
sudo in the POST_BUILD add_custom_command (it breaks non-privileged/CI builds)
and instead move capability-setting out of the build phase: implement either (a)
an install-time step (e.g. add a CMake install(CODE) or install script that runs
setcap) or (b) a separate optional install target/script (e.g.
add_custom_target(setcap INSTALL_COMMAND ...) or a packaged script in CMake
config) and document that it must be run with appropriate privileges; ensure the
build does not require sudo, optionally add a CMake option to enable automatic
install-time setcap and emit a clear message when capabilities are not set so
users know to run the privileged script.
| /*----------------------------------------------------------------------------- | ||
| * hc_data_rx_op.cpp | ||
| * HoloCat Data Receive Operator | ||
| * | ||
| * This file implements the HcDataTxOp operator that generates incrementing | ||
| * counter data for testing and demonstration purposes. | ||
| *---------------------------------------------------------------------------*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy-paste error in file header comment.
The header describes HcDataTxOp but this file implements HcDataRxOp.
/*-----------------------------------------------------------------------------
* hc_data_rx_op.cpp
* HoloCat Data Receive Operator
*
- * This file implements the HcDataTxOp operator that generates incrementing
- * counter data for testing and demonstration purposes.
+ * This file implements the HcDataRxOp operator that receives counter
+ * data from the EtherCAT bus for testing and demonstration purposes.
*---------------------------------------------------------------------------*/📝 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.
| /*----------------------------------------------------------------------------- | |
| * hc_data_rx_op.cpp | |
| * HoloCat Data Receive Operator | |
| * | |
| * This file implements the HcDataTxOp operator that generates incrementing | |
| * counter data for testing and demonstration purposes. | |
| *---------------------------------------------------------------------------*/ | |
| /*----------------------------------------------------------------------------- | |
| * hc_data_rx_op.cpp | |
| * HoloCat Data Receive Operator | |
| * | |
| * This file implements the HcDataRxOp operator that receives counter | |
| * data from the EtherCAT bus for testing and demonstration purposes. | |
| *---------------------------------------------------------------------------*/ |
🤖 Prompt for AI Agents
In applications/holocat/cpp/hc_data_rx_op.cpp around lines 1 to 7, the file
header comment incorrectly references HcDataTxOp and describes transmitter
behavior; update the header to correctly name HcDataRxOp and describe that this
file implements the HcDataRxOp (the data receive operator) and its purpose
(e.g., receiving/parsing incoming data for HoloCat), ensuring the header text
accurately reflects the implementation and purpose.
|
|
||
| /** | ||
| * @brief Compute method called on each execution cycle | ||
| * @param op_input Input context (unused for this source operator) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect comment about operator type.
The comment states "unused for this source operator" but HcDataRxOp is a receiver/sink operator, not a source operator.
Apply this diff:
- * @param op_input Input context (unused for this source operator)
+ * @param op_input Input context for receiving counter data📝 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.
| * @param op_input Input context (unused for this source operator) | |
| * @param op_input Input context for receiving counter data |
🤖 Prompt for AI Agents
In applications/holocat/cpp/hc_data_rx_op.hpp around line 42, the param comment
incorrectly refers to HcDataRxOp as a "source operator"; this operator is a
receiver/sink. Update the comment text for the op_input parameter to reflect the
correct operator type (for example: "op_input Input context (unused for this
receiver/sink operator)" or "unused for this sink operator") so the docstring
accurately describes HcDataRxOp.
| if(ECMASTER_VERSION_MAJOR AND ECMASTER_VERSION_MINOR AND ECMASTER_VERSION_PATCH) | ||
| set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}.${ECMASTER_VERSION_BUILD}") | ||
| endif() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Version string may include empty component if BUILD is not found.
If EC_VERSION_BUILD is not defined in the header, ECMASTER_VERSION_BUILD will be empty, resulting in a version string like "3.2.1." with a trailing dot.
Consider conditionally including the build number:
if(ECMASTER_VERSION_MAJOR AND ECMASTER_VERSION_MINOR AND ECMASTER_VERSION_PATCH)
- set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}.${ECMASTER_VERSION_BUILD}")
+ if(ECMASTER_VERSION_BUILD)
+ set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}.${ECMASTER_VERSION_BUILD}")
+ else()
+ set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}")
+ endif()
endif()📝 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.
| if(ECMASTER_VERSION_MAJOR AND ECMASTER_VERSION_MINOR AND ECMASTER_VERSION_PATCH) | |
| set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}.${ECMASTER_VERSION_BUILD}") | |
| endif() | |
| if(ECMASTER_VERSION_MAJOR AND ECMASTER_VERSION_MINOR AND ECMASTER_VERSION_PATCH) | |
| if(ECMASTER_VERSION_BUILD) | |
| set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}.${ECMASTER_VERSION_BUILD}") | |
| else() | |
| set(ECMASTER_VERSION "${ECMASTER_VERSION_MAJOR}.${ECMASTER_VERSION_MINOR}.${ECMASTER_VERSION_PATCH}") | |
| endif() | |
| endif() |
🤖 Prompt for AI Agents
In applications/holocat/FindEcMaster.cmake around lines 100-102, the version
string unconditionally appends ECMASTER_VERSION_BUILD which can be empty and
yield a trailing dot; change the logic to build a base version from
ECMASTER_VERSION_MAJOR.MINOR.PATCH and then only append
".${ECMASTER_VERSION_BUILD}" if ECMASTER_VERSION_BUILD is defined and not empty
(e.g., check using IF(DEFINED ECMASTER_VERSION_BUILD AND NOT
"${ECMASTER_VERSION_BUILD}" STREQUAL "") or similar) so the final
ECMASTER_VERSION has no trailing dot when build is missing.
| "tags": [ | ||
| "EtherCAT" | ||
| ], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Invalid category tag - use approved category.
The first tag in the tags array serves as the category and must be from the approved list. "EtherCAT" is not an approved category. Based on the application's purpose, consider using "Interoperability" or "Networking and Distributed Computing".
As per coding guidelines, the category must match one of the approved categories.
Apply this diff to use an appropriate category:
"tags": [
- "EtherCAT"
+ "Interoperability",
+ "EtherCAT"
],Or if networking focus is more appropriate:
"tags": [
- "EtherCAT"
+ "Networking and Distributed Computing",
+ "EtherCAT"
],📝 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.
| "tags": [ | |
| "EtherCAT" | |
| ], | |
| "tags": [ | |
| "Interoperability", | |
| "EtherCAT" | |
| ], |
| "tags": [ | |
| "EtherCAT" | |
| ], | |
| "tags": [ | |
| "Networking and Distributed Computing", | |
| "EtherCAT" | |
| ], |
🤖 Prompt for AI Agents
In applications/holocat/metadata.json around lines 25 to 27, the first element
of the "tags" array ("EtherCAT") is not an approved category; replace it with an
approved category that reflects the app purpose — e.g. change the first tag to
"Interoperability" (or "Networking and Distributed Computing" if networking is
more accurate) so the tags[0] matches the approved category list and keep any
additional tags after it.
| # HoloCat - EtherCAT Real-time Integration | ||
|
|
||
|  | ||
|
|
||
| HoloCat is an EtherCAT master application that integrates the acontis EC-Master SDK with NVIDIA's Holoscan platform. | ||
|
|
||
| ## Overview | ||
|
|
||
| HoloCat provides deterministic EtherCAT communication capabilities within the Holoscan ecosystem, enabling: | ||
|
|
||
| - **Real-time Control** | ||
| - **Holoscan Native** | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| ### Required Dependencies | ||
|
|
||
| 1. **acontis EC-Master SDK** (Commercial License) | ||
| - Version 3.2.3 or later | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Prerequisites | ||
| ```bash | ||
| # Set EC-Master SDK path | ||
| export ECMASTER_ROOT=/home/hking/devel/ethercat/ecm | ||
|
|
||
| # Verify installation (optional) | ||
| ./applications/holocat/scripts/verify_ecmaster.sh | ||
| ``` | ||
|
|
||
| ### Build | ||
| ```bash | ||
| # Build using HoloHub CLI (recommended) | ||
| ./holohub build holocat --local | ||
| ``` | ||
|
|
||
| ### Run | ||
| ```bash | ||
| # Run with configuration file | ||
| ./build/holocat/applications/holocat/cpp/holocat --config ./applications/holocat/configs/holocat_config.yaml | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| ### Basic Configuration | ||
|
|
||
| Create `holocat_config.yaml`: | ||
|
|
||
| ```yaml | ||
| holocat: | ||
| # Network adapter for EtherCAT | ||
| adapter_name: "eth0" # Change to your EtherCAT interface | ||
|
|
||
| # EtherCAT configuration file | ||
| eni_file: "/tmp/holocat_config.xml" | ||
|
|
||
| # Cycle time in microseconds | ||
| cycle_time_us: 1000 # 1ms cycle time | ||
|
|
||
| # Real-time priorities (1-99) | ||
| rt_priority: 39 | ||
| job_thread_priority: 98 | ||
|
|
||
| # Enable real-time scheduling | ||
| enable_rt: true | ||
|
|
||
| # Holoscan application configuration | ||
| holoscan: | ||
| logging: | ||
| level: "info" | ||
| ``` | ||
|
|
||
| ### ENI File Generation | ||
|
|
||
| Use EtherCAT configuration tools to generate your ENI file. | ||
|
|
||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Common Issues | ||
|
|
||
| 1. **Permission Denied** | ||
| ```bash | ||
| # Ensure capabilities are set | ||
| sudo setcap 'cap_net_raw=ep' ./build/holocat/applications/holocat/holocat | ||
| ``` | ||
|
|
||
| 3. **EC-Master SDK Not Found** | ||
| ```bash | ||
| # Verify ECMASTER_ROOT environment variable | ||
| echo $ECMASTER_ROOT | ||
| ls -la $ECMASTER_ROOT/SDK/INC/EcMaster.h | ||
| ``` No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Add architecture overview section.
Per coding guidelines, the README should include an architecture overview. Add a section explaining the operator architecture (HolocatOp, HcDataTxOp, HcDataRxOp) and how they interact with the EtherCAT master and Holoscan framework.
As per coding guidelines, README.md must include architecture overview.
🤖 Prompt for AI Agents
applications/holocat/README.md lines 1-94: The README lacks the required
"Architecture Overview" section; add a concise subsection titled "Architecture
Overview" describing the operator architecture: list and briefly describe
HolocatOp, HcDataTxOp, and HcDataRxOp, explain that HolocatOp manages lifecycle
and interfaces with the acontis EC‑Master SDK (initialization, ENI loading,
cycle scheduling), HcDataTxOp handles outgoing process data to EtherCAT slaves
and timing control, and HcDataRxOp handles incoming process data and publishes
to Holoscan; include a simple diagram or sequence description of how data flows
between Holoscan application -> HolocatOp -> (HcDataTxOp -> EtherCAT master ->
slaves) and (slaves -> EtherCAT master -> HcDataRxOp -> Holoscan), and mention
real‑time considerations (cycle timing and priorities) and configuration points
(adapter_name, eni_file, cycle_time_us).
| 1. **Permission Denied** | ||
| ```bash | ||
| # Ensure capabilities are set | ||
| sudo setcap 'cap_net_raw=ep' ./build/holocat/applications/holocat/holocat | ||
| ``` | ||
|
|
||
| 3. **EC-Master SDK Not Found** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix troubleshooting section numbering.
The numbering jumps from issue 1 to issue 3, skipping 2.
Apply this diff:
-3. **EC-Master SDK Not Found**
+2. **EC-Master SDK Not Found**🤖 Prompt for AI Agents
In applications/holocat/README.md around lines 83 to 89, the troubleshooting
list numbering skips from "1. Permission Denied" to "3. EC-Master SDK Not
Found"; update the ordered list so entries are sequential (1, 2, 3) by
renumbering the affected items or converting to an auto-numbered markdown list
so the second issue becomes "2. EC-Master SDK Not Found" (or use a continuous
numbered sequence) to restore correct ordering and consistency.
| for lib in "${LINK_LIBS[@]}"; do | ||
| if [ -f "$LIB_DIR/$lib" ]; then | ||
| print_status "OK" "$lib found" | ||
| ((FOUND_LIBS++)) | ||
| else | ||
| print_status "WARN" "$lib not found (may be optional)" | ||
| fi | ||
| done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arithmetic increment may cause premature exit with set -e.
When FOUND_LIBS is 0, the expression ((FOUND_LIBS++)) evaluates to 0 (falsy), which bash treats as a failure. Combined with set -e, this will exit the script prematurely on the first found library.
if [ -f "$LIB_DIR/$lib" ]; then
print_status "OK" "$lib found"
- ((FOUND_LIBS++))
+ FOUND_LIBS=$((FOUND_LIBS + 1))
else
print_status "WARN" "$lib not found (may be optional)"
fi📝 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.
| for lib in "${LINK_LIBS[@]}"; do | |
| if [ -f "$LIB_DIR/$lib" ]; then | |
| print_status "OK" "$lib found" | |
| ((FOUND_LIBS++)) | |
| else | |
| print_status "WARN" "$lib not found (may be optional)" | |
| fi | |
| done | |
| for lib in "${LINK_LIBS[@]}"; do | |
| if [ -f "$LIB_DIR/$lib" ]; then | |
| print_status "OK" "$lib found" | |
| FOUND_LIBS=$((FOUND_LIBS + 1)) | |
| else | |
| print_status "WARN" "$lib not found (may be optional)" | |
| fi | |
| done |
🤖 Prompt for AI Agents
In applications/holocat/scripts/verify_ecmaster.sh around lines 111-118, the use
of the post-increment expression ((FOUND_LIBS++)) can produce a zero exit status
when FOUND_LIBS is 0 and cause the script to exit under set -e; change the
increment to a form that yields a non-zero arithmetic result (for example use
FOUND_LIBS=$((FOUND_LIBS+1)) or ((FOUND_LIBS+=1))) so the operation does not
return a failing status and the loop won't prematurely exit.
Greptile Summary
Important Files Changed
Confidence score: 3/5
Sequence DiagramsequenceDiagram
participant User
participant HolocatApp as "HolocatApp"
participant HcDataTxOp as "HcDataTxOp"
participant HolocatOp as "HolocatOp"
participant EtherCAT as "EtherCAT Master"
participant HcDataRxOp as "HcDataRxOp"
User->>HolocatApp: "run()"
HolocatApp->>HolocatApp: "compose()"
HolocatApp->>HcDataTxOp: "create operator"
HolocatApp->>HolocatOp: "create operator"
HolocatApp->>HcDataRxOp: "create operator"
HolocatApp->>HolocatOp: "start()"
HolocatOp->>EtherCAT: "ecatInitMaster()"
loop "Periodic Execution"
HcDataTxOp->>HcDataTxOp: "compute()"
HcDataTxOp->>HolocatOp: "count_out"
HolocatOp->>HolocatOp: "compute()"
HolocatOp->>EtherCAT: "ecatExecJob(ProcessAllRxFrames)"
HolocatOp->>EtherCAT: "ecatGetProcessImageInputPtr()"
EtherCAT-->>HolocatOp: "process data"
HolocatOp->>EtherCAT: "ecatGetProcessImageOutputPtr()"
HolocatOp->>EtherCAT: "write process data"
HolocatOp->>EtherCAT: "ecatExecJob(SendAllCycFrames)"
HolocatOp->>HcDataRxOp: "count_out"
HcDataRxOp->>HcDataRxOp: "compute()"
end
User->>HolocatApp: "stop()"
HolocatOp->>HolocatOp: "stop()"
HolocatOp->>EtherCAT: "ecatSetMasterState(INIT)"
HolocatOp->>EtherCAT: "ecatDeinitMaster()"
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (2)
-
applications/holocat/Dockerfile, line 3-4 (link)syntax:
BASE_IMAGEis used but never defined. The ARG declaresBASE_SDK_VERSIONbut the FROM uses${BASE_IMAGE}. This will cause the Docker build to fail. -
applications/holocat/CMakeLists.txt, line 26-30 (link)syntax: Unreachable code.
message(FATAL_ERROR ...)already terminates CMake execution, soexit(1)will never run.
19 files reviewed, 2 comments
|
Hi @hawkeyeking, thanks for this contribution. There are a few comments from the AI reviewer, which worth checking if not relevant please make the resolve with a short comment. Once they are addressed, we'd be happy to do the full review. Thaks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (3)
-
applications/holocat/CMakeLists.txt, line 26-29 (link)logic: Unreachable code -
message(FATAL_ERROR ...)terminates CMake execution immediately, soexit(1)will never run. -
applications/holocat/Dockerfile, line 3-4 (link)syntax:
BASE_IMAGEis used in the FROM directive but onlyBASE_SDK_VERSIONis declared as an ARG. Either use the declared variable or addARG BASE_IMAGE. -
applications/holocat/cpp/holocat_op.cpp, line 163-165 (link)logic: Unreachable code -
returnstatement afterthrowwill never execute.
19 files reviewed, 3 comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces HoloCat, a new application that integrates EtherCAT real-time industrial communication with NVIDIA's Holoscan SDK. It enables deterministic fieldbus communication for industrial automation applications using the commercial acontis EC-Master SDK.
Key Changes:
- Complete EtherCAT master implementation with Holoscan operator architecture
- Three operators: HolocatOp (main EtherCAT master), HcDataTxOp (data transmission), and HcDataRxOp (data reception)
- Docker containerization with verification scripts and CMake build system
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| applications/holocat/metadata.json | Application metadata with dependencies and configuration modes; category needs correction |
| applications/holocat/cpp/main.cpp | Main entry point with CLI argument parsing; missing return statement |
| applications/holocat/cpp/holocat_op.{hpp,cpp} | Core EtherCAT operator with state machine; unreachable code present |
| applications/holocat/cpp/holocat_app.{hpp,cpp} | Application composition and config validation; format string inconsistency |
| applications/holocat/cpp/hc_data_tx_op.{hpp,cpp} | Counter data generator operator; minor typo in comment |
| applications/holocat/cpp/hc_data_rx_op.{hpp,cpp} | Data receiver operator; incorrect file header documentation |
| applications/holocat/cpp/CMakeLists.txt | C++ build configuration with EC-Master SDK integration |
| applications/holocat/CMakeLists.txt | Top-level build script; unreachable exit statement |
| applications/holocat/FindEcMaster.cmake | CMake module for locating EC-Master SDK installation |
| applications/holocat/configs/holocat_config.yaml | Runtime configuration; contains hardcoded developer-specific paths |
| applications/holocat/configs/eni2.xml | EtherCAT Network Information configuration file |
| applications/holocat/scripts/verify_ecmaster.sh | SDK verification utility; hardcoded path in example |
| applications/holocat/Dockerfile | Container build definition; critical BASE_IMAGE variable issue |
| applications/holocat/README.md | Documentation with setup and usage instructions; list numbering and hardcoded path issues |
| applications/CMakeLists.txt | Adds holocat to build system |
| "aarch64" | ||
| ], | ||
| "tags": [ | ||
| "EtherCAT" |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The category "EtherCAT" is not in the approved category list. Based on the README description, this application provides "deterministic EtherCAT communication capabilities" for "Real-time Control" and appears to be focused on networking and industrial communication.
Please replace "EtherCAT" with an existing category from the approved category list. Here are some suitable alternatives:
- For industrial real-time communication:
Networking and Distributed Computing - For real-time control aspects:
Robotics - For communication protocols:
Interoperability
The most appropriate would be Networking and Distributed Computing or Interoperability given the EtherCAT protocol's focus on industrial networking.
| holoscan::ExecutionContext& context) override; | ||
|
|
||
| private: | ||
| // coutner from 0 to maxcount for output on ECat bus |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling error: "coutner" should be "counter".
| // coutner from 0 to maxcount for output on ECat bus | |
| // counter from 0 to maxcount for output on ECat bus |
| HOLOSCAN_LOG_ERROR("Cannot initialize EtherCAT-Master: {} (0x{:x})", | ||
| ecatGetText(dwRes), dwRes); | ||
| throw std::runtime_error("Cannot initialize EtherCAT-Master: " + std::string(ecatGetText(dwRes))); | ||
| return; |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unreachable code: The return statement on line 165 will never be executed because line 164 throws an exception. Remove the return statement.
| return; |
| adapter_name: "enxc84bd6d2788c" | ||
|
|
||
| # EtherCAT Network Information (ENI) file path | ||
| # Use environment variable HOLOCAT_ENI_FILE to override, or falls back to config dir | ||
| eni_file: "/home/hking/devel/holo/holohub/applications/holocat/configs/eni2.xml" |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded user-specific paths in configuration file. The adapter_name "enxc84bd6d2788c" and eni_file path "/home/hking/devel/holo/holohub/applications/holocat/configs/eni2.xml" contain developer-specific information that should be replaced with generic placeholders or relative paths. Consider using:
- adapter_name: "eth0" (as shown in the README example)
- eni_file: A relative path or environment variable-based path
| adapter_name: "enxc84bd6d2788c" | |
| # EtherCAT Network Information (ENI) file path | |
| # Use environment variable HOLOCAT_ENI_FILE to override, or falls back to config dir | |
| eni_file: "/home/hking/devel/holo/holohub/applications/holocat/configs/eni2.xml" | |
| adapter_name: "eth0" | |
| # EtherCAT Network Information (ENI) file path | |
| # Use environment variable HOLOCAT_ENI_FILE to override, or falls back to config dir | |
| eni_file: "eni2.xml" |
| ### Prerequisites | ||
| ```bash | ||
| # Set EC-Master SDK path | ||
| export ECMASTER_ROOT=/home/hking/devel/ethercat/ecm |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded user-specific path in documentation. The path "/home/hking/devel/ethercat/ecm" is developer-specific and should be replaced with a generic placeholder like "/path/to/ec-master" or "/opt/acontis/ecmaster".
| export ECMASTER_ROOT=/home/hking/devel/ethercat/ecm | |
| export ECMASTER_ROOT=/opt/acontis/ecmaster # Adjust to your EC-Master install path |
| sudo setcap 'cap_net_raw=ep' ./build/holocat/applications/holocat/holocat | ||
| ``` | ||
|
|
||
| 3. **EC-Master SDK Not Found** |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List numbering is incorrect. The list jumps from "1. Permission Denied" to "3. EC-Master SDK Not Found", skipping item 2. Either add the missing item 2 or renumber item 3 as item 2.
| 3. **EC-Master SDK Not Found** | |
| 2. **EC-Master SDK Not Found** |
| print_status "ERROR" "ECMASTER_ROOT environment variable not set" | ||
| echo " Set it to your EC-Master installation path:" | ||
| echo " export ECMASTER_ROOT=/path/to/ecm" | ||
| echo " Example: export ECMASTER_ROOT=/home/hking/devel/ethercat/ecm" |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcoded user-specific path in example. Line 38 contains a developer-specific path "/home/hking/devel/ethercat/ecm" in the example that should use a generic placeholder path like "/path/to/ec-master" or "/opt/acontis/ecmaster".
| echo " Example: export ECMASTER_ROOT=/home/hking/devel/ethercat/ecm" | |
| echo " Example: export ECMASTER_ROOT=/opt/acontis/ecmaster" |
|
|
||
| # Exit with failure | ||
| exit(1) |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exit(1) command on line 29 is unreachable because message(FATAL_ERROR) on line 26 already terminates the CMake configuration process. Remove lines 28-29 as they serve no purpose.
| # Exit with failure | |
| exit(1) |
| std::shared_ptr<HolocatOp> holocat_op = make_operator<HolocatOp>("holocat_op", ecat_bus_periodic_cond); | ||
| holocat_op->set_config(config); | ||
| add_operator(holocat_op); | ||
| HOLOSCAN_LOG_INFO("HoloCat operator created with %dus periodic condition", config.cycle_time_us); |
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent log formatting. Line 39 uses printf-style format string "%dus" while other log statements in the same function (lines 30, 31) use modern C++ format string style with "{}". Use the consistent format string style: HOLOSCAN_LOG_INFO("HoloCat operator created with {}us periodic condition", config.cycle_time_us);
| HOLOSCAN_LOG_INFO("HoloCat operator created with %dus periodic condition", config.cycle_time_us); | |
| HOLOSCAN_LOG_INFO("HoloCat operator created with {}us periodic condition", config.cycle_time_us); |
| usermod -aG sudo holocat && \ | ||
| echo "holocat ALL=(ALL) NOPASSWD: /usr/sbin/setcap" >> /etc/sudoers | ||
|
|
Copilot
AI
Dec 18, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Dockerfile grants the holocat user passwordless sudo access to /usr/sbin/setcap, which allows that user (and any code running as it) to assign arbitrary Linux capabilities to any binary in the container. If an attacker gains code execution as holocat, they can use sudo setcap to escalate privileges and grant powerful capabilities (e.g., raw network, sys_admin) to other binaries, breaking the intended least-privilege isolation. Consider removing this sudoers entry and instead setting the minimal required capabilities at build time or via the container runtime, without allowing arbitrary setcap invocation from inside the container.
| usermod -aG sudo holocat && \ | |
| echo "holocat ALL=(ALL) NOPASSWD: /usr/sbin/setcap" >> /etc/sudoers | |
| usermod -aG sudo holocat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (9)
-
applications/CMakeLists.txt, line 152 (link)style: The holocat application should be placed in alphabetical order per the comment on line 16. It should be positioned between 'high_speed_endoscopy' and 'holochat'.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
-
applications/holocat/CMakeLists.txt, line 28-29 (link)logic: unreachable code after
FATAL_ERROR- CMake stops processing after the fatal error message -
applications/holocat/cpp/hc_data_tx_op.hpp, line 53 (link)syntax: Typo: 'coutner' should be 'counter'
-
applications/holocat/cpp/holocat_op.cpp, line 165 (link)syntax: unreachable code after throw statement
-
applications/holocat/cpp/hc_data_rx_op.hpp, line 42 (link)style: Documentation inconsistency - comment states op_input is unused but this is a receiver operator, not a source operator
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
-
applications/holocat/Dockerfile, line 4 (link)logic: BASE_IMAGE variable is undefined. Change to BASE_SDK_VERSION or add ARG BASE_IMAGE declaration.
-
applications/holocat/metadata.json, line 5-7 (link)style: missing author name field - only affiliation is specified. Should an author name be added to the metadata?
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
-
applications/holocat/cpp/holocat_app.cpp, line 42-43 (link)style: Condition name 'ethercat_cycle' is used for both EtherCAT bus and counter update conditions, but they have different periods (configurable vs 100ms). Consider using distinct names. Should these conditions have the same name when they serve different purposes with different timing?
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
-
applications/holocat/cpp/hc_data_rx_op.cpp, line 5-6 (link)syntax: Comment incorrectly describes HcDataTxOp instead of HcDataRxOp
19 files reviewed, 9 comments
Add HoloCat application that integrates EtherCAT real-time communication with NVIDIA's Holoscan streaming framework.
Key Features:
Components:
This enables real-time industrial automation applications using EtherCAT fieldbus communication within the Holoscan ecosystem.
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.