This repository contains a toy (illustrative) EtherCAT master implementation in C, demonstrating:
- A slave state machine (INIT -> PRE-OP -> SAFE-OP -> OP) with mailbox transactions to actually set AL Control and poll AL Status.
- Distributed Clocks (DC) logic (reading offset from one register, writing correction).
- Dynamic datagram queue (no fixed 256-byte limit) for partial batching of EtherCAT frames.
- SoE (SERCOS over EtherCAT) stubs (
soe-read
,soe-write
). - FoE (File over EtherCAT) stubs (
foe-req
), using a single-block approach. - ESI parsing + minimal ring scanning to discover slaves and match them to ESI data.
- A POSIX-based event loop for DC and frame events.
- A CLI with commands like:
read
,write
(basic FPRD/FPWR)soe-read
,soe-write
foe-req
scan-esi
(parse ESI files and discover slaves)slave-state <idx> <state>
(requests mailbox transition)stop
(shuts down)
Disclaimer: This is a toy or demonstrative EtherCAT master, not production-ready. Real systems require more robust ring scanning, full mailbox usage, multi-slave DC synchronization, PDO configuration, and advanced SoE/FoE chunking/ack. Use this code as a learning or prototype reference.
ul_ecat_master.h
: Single public header with all API declarations.ul_ecat_master.c
: Implements everything in one file:- Master lifecycle (init/shutdown, RT thread).
- DC logic.
- Dynamic datagram queue + partial batching.
- Slave DB and ESI matching.
- SoE / FoE stubs.
- Event loop.
- CLI (read/write/soe-read/scan-esi, etc.).
ul_ecat_tool.c
: Minimalmain()
that callsul_ecat_app_execute(argc, argv)
.CMakeLists.txt
: Example build script for CMake.
-
Install a C compiler and CMake (>= 3.0).
-
Clone or copy these files into a folder named
ecat_project/
. -
In a shell:
cd ecat_project mkdir build cd build cmake .. make
-
This produces
ecatTool
underbuild/
.
From build/
:
./ecatTool [args...]
-
scan-esi <file1.xml> <file2.xml> ... null
Parses the ESI files, scans a minimal ring (fake 2 slaves), matches them with the ESI data, and prints results. -
slave-state <idx> <state_dec>
Requests the mailbox transition from current state to the desired one (INIT=1, PRE-OP=2, SAFE-OP=4, OP=8). Writes AL Control, polls AL Status. -
read <addr_hex> <len>
Queues a read command (FPRD) to that EtherCAT address. -
write <addr_hex> <value_hex> [size=4]
Queues a write (FPWR). -
soe-read <drive_no_dec> <idn_hex>
Minimal SoE read request. -
soe-write <drive_no_dec> <idn_hex> <val_hex>
Minimal SoE write request. -
foe-req <opcode_hex> <size_dec> [pw_hex=0]
Sends a single-block FoE request with optional password. -
stop
Shuts down the master: stops the RT thread, closes raw socket.
-
The code posts DC events or frame arrivals into a POSIX event queue but does not automatically call
ul_ecat_eventloop_run()
. -
If you want real-time event callback usage, do something like:
ul_ecat_register_dc_callback(my_dc_handler); ul_ecat_register_frame_callback(my_frame_handler); ul_ecat_eventloop_run(); // Blocks until ul_ecat_eventloop_stop()
-
This ensures user code executes in a single event-loop context, not in the RT thread.
- No advanced mailbox error handling, multiple CoE or SoE transactions, or multi-slave DC.
- State transitions are partial stubs with short polling loops. Real usage might parse actual read results.
- SoE / FoE are single-block stubs without chunking/ack.
- This is a learning prototype, not a production solution.