3.1. Timing
3.1.1. JobTask: Interaction between application and EtherCAT® network
EtherCAT® is a cycle-based fieldbus technology. The EC-Master has no internal tasks and the timing of the cyclic operation is fully controlled by the application. To implement this, the application contains a thread that cyclically calls emExecJob() / ecatExecJob(). Within the emExecJob() calls, the EC-Master sends and processes the EtherCAT® frames and handles internal state machines. This thread is referred to as the JobTask .
The benefits of this design are:
No synchronization issues between application and EC-Master
Consistent process data without using any locks
Various network timings driven by the application possible
Cyclic part may run within Interrupt Service Routine (ISR)
Easy to integrate
Note
For real-time EtherCAT® applications, this task must be scheduled in real-time.
Note
Blocking APIs such as emCoeSdoDownload(), which depend on the JobTask and wait for results,
must not be called within the JobTask as it would result in a lock-up of the JobTask.
Note
It is highly recommended that there is a single task calling all required jobs to run the stack as demonstrated in the EcMasterDemo.
3.1.2. Timing models
From the application perspective, the EC-Master behaves like a driver that is controlled by the emExecJob() function with additional parameters, so-called EC_T_USER_JOB.
Typical sequence of EC_T_USER_JOB for emExecJob() to be called cyclically by the application:
Refresh InputsEC_T_USER_JOB::eUsrJob_ProcessAllRxFrames: Process all received frames
Write OutputsEC_T_USER_JOB::eUsrJob_SendAllCycFrames: Send cyclic frames to update process output data
AdministrationEC_T_USER_JOB::eUsrJob_MasterTimer: Trigger MainDevice and SubDevice state machines
Send acyclic datagrams/commandsEC_T_USER_JOB::eUsrJob_SendAcycFrames: Transmit pending acyclic frame(s)
When a process data update is initiated by calling emExecJob(eUsrJob_ProcessAllRxFrames) new input data are read from the received frames and copied into the process data image. After the function returns the application can process the inputs, calculate the outputs and update the values in the process image. With calling emExecJob(eUsrJob_SendAllCycFrames) the output data are read from the process data image and stored in Ethernet/EtherCAT® frames prior to sending them to the Real-time Ethernet Driver. When this call returns all output process data values are stored in Ethernet/EtherCAT® frames which are then processed by the network controller.
If only one single thread is both writing into the process data image and calling emExecJob(eUsrJob_SendAllCycFrames) no further output process data synchronization is necessary.
The application is responsible to (cyclically) call the function emExecJob() with the appropriate parameters.
EtherCAT® frames are divided into two categories:
- Cyclic frames
Contain process output and input data
Distributed Clocks (DC): Contain datagram to distribute network time
Typically sent by MainDevice in every cycle
Defined by the configuration tool (which data to read and to write)
- Acyclic frames
Asynchronous, event triggered communication
Mailbox communication (CoE, FoE, EoE)
Status requests (e. g. read SubDevice state information)
Raw EtherCAT® datagrams requested by application
3.1.3. Standard EtherCAT® Timing: Short output dead time
Cyclic frames
Application has to perform:
/* Job P: Process data are saved in the process data image */
emExecJob(dwInstanceId, eUsrJob_ProcessAllRxFrames, &oJobParms);
/* App. Task */
/* Job S: Send updated process data.
Outputs are updated in slaves and input data is collected to be present for the next cycle.
The process data image is saved during eUsrJob_ProcessAllRxFrames */
emExecJob(dwInstanceId, eUsrJob_SendAllCycFrames, EC_NULL);
/* Job MT: Trigger master state machines.
Required to perform any status changes or internal administration tasks */
emExecJob(dwInstanceId, eUsrJob_MasterTimer, EC_NULL);
Cyclic and acyclic frames
Application has to perform:
/* Job P: Process data are saved in the process data image */
emExecJob(dwInstanceId, eUsrJob_ProcessAllRxFrames, &oJobParms);
/* App. Task */
/* Job S: Send updated process data.
Outputs are updated in slaves and input data is collected to be present for the next cycle.
The process data image is saved during eUsrJob_ProcessAllRxFrames */
emExecJob(dwInstanceId, eUsrJob_SendAllCycFrames, EC_NULL);
/* Job MT: Trigger master state machines.
Required to perform any status changes or internal administration tasks */
emExecJob(dwInstanceId, eUsrJob_MasterTimer, EC_NULL);
/* Job AS: Transmission of the acyclic commands from the queue.
These may have been queued by the application or by the internal administration task (eUsrJob_MasterTimer) */
emExecJob(dwInstanceId, eUsrJob_SendAcycFrames, EC_NULL);
Cyclic frames with DC
Application has to perform:
/* Job P: Process data are saved in the process data image */
emExecJob(dwInstanceId, eUsrJob_ProcessAllRxFrames, &oJobParms);
/* App. Task */
/* Job S: Send updated process data.
Outputs are updated in slaves and input data is collected to be present for the next cycle.
The process data image is saved during eUsrJob_ProcessAllRxFrames */
emExecJob(dwInstanceId, eUsrJob_SendAllCycFrames, EC_NULL);
/* Job MT: Trigger master state machines.
Required to perform any status changes or internal administration tasks */
emExecJob(dwInstanceId, eUsrJob_MasterTimer, EC_NULL);
3.1.4. Alternative EtherCAT® Timing: Short Input dead time
Application has to perform during startup:
emInitMaster(dwInstanceId, &oInitMasterParms);
/* create event for "cyclic frame received" and register RX callback function */
{
EC_T_CYCFRAME_RX_CBDESC oCycFrameRxCallbackDesc;
S_pvCycFrameReceivedEvent = OsCreateEvent();
/* setup callback function which is called after RX */
OsMemset(&oCycFrameRxCallbackDesc, 0, sizeof(EC_T_CYCFRAME_RX_CBDESC));
oCycFrameRxCallbackDesc.pfnCallback = CycFrameReceivedCallback;
oCycFrameRxCallbackDesc.pCallbackContext = S_pvCycFrameReceivedEvent;
emIoCtl(dwInstanceId, EC_IOCTL_REGISTER_CYCFRAME_RX_CB, &oCycFrameRxCallbackDesc, sizeof(EC_T_CYCFRAME_RX_CBDESC), EC_NULL, 0, EC_NULL);
}
/* create cyclic process data Thread */
S_pvtJobThread = OsCreateThread((EC_T_CHAR*)"EcMasterJobTask", EcMasterJobTask, CpuSet,
JOBS_THREAD_PRIO, JOBS_THREAD_STACKSIZE, (EC_T_VOID*)pAppContext);
Application has to perform inside job task:
/* Job S: Send updated process data.
Outputs are updated in slaves and input data is collected to be present for the current cycle.
The process data image is saved after receiving the response frame within the interrupt service thread */
emExecJob(dwInstanceId, eUsrJob_SendAllCycFrames, EC_NULL);
/* wait until cyclic frame is received */
OsWaitForEvent(S_pvCycFrameReceivedEvent, dwCycleTime);
/* App. Task */
/* Job MT: Trigger master state machines.
Required to perform any status changes or internal administration tasks */
emExecJob(dwInstanceId, eUsrJob_MasterTimer, EC_NULL);
/* Job AS: Transmission of the acyclic commands from the queue.
These may have been queued by the application or by the internal administration task (eUsrJob_MasterTimer) */
emExecJob(dwInstanceId, eUsrJob_SendAcycFrames, EC_NULL);
For closer details find an example project Examples/EcMasterDemoSyncSm