This is an old revision of the document!
Table of Contents
Improving Real-time Performance
USB Host and CFHEADER Timing Synchronization
The USB protocol sends a Start of Frame (SoF) packet from the USB host to connected USB devices, reliably, every 1 millisecond. The arrival of that packet generates an interrupt that can be used as a clock tick to synchronize the USB host with its connected devices.
The CFHEADER leverages this feature of the USB protocol to synchronize the I²C control loop with the USB host. That synchronization can be customized, and even disabled, using the NumberOfUsbFramesToSync property, as described below:
- -1 - The CFHEADER will write to and read from the connected IO modules via I²C immediately after receiving a USB OUT transfer from the host. The I²C communication will be not be performed unless a USB OUT transfer is received. This effectively makes the timing of the I²C control loop dependent on the ability of the USB host application and operating system to send USB OUT transfers to the CFHEADER module deterministically and in real time.
- 0 - The CFHEADER will write to and read from the connected IO modules via I²C immediately after the last I²C iteration, effectively ignoring the USB Start of Frame (SoF) interrupt. The I²C communication will be performed regardless of whether the CFHEADER module has received a USB OUT transfer from the USB host, even if the CFHEADER is not connected to a USB host via a USB cable. This effectively removes any synchronization of I²C communication with the USB host, favoring immediacy of I²C communication over determinism.
- 1 - The default. The CFHEADER module will write to and read from the connected IO modules via I²C on every USB Start of Frame (SoF) interrupt, effectively every millisecond. The I²C communication will be performed regardless of whether the CFHEADER module has received a USB OUT transfer from the USB host. If the CFHEADER is not connected to a USB host, it will not receive SoF packets, so will, therefore, not perform any I²C communication.
- 2 - The CFHEADER module will write to and read from the connected IO modules via I²C on every 2 USB Start of Frame (SoF) interrupts, effectively every 2 milliseconds. The I²C communication will be performed regardless of whether the CFHEADER module has received a USB OUT transfer from the USB host. If the CFHEADER is not connected to a USB host, it will not receive SoF packets, so will, therefore, not perform any I²C communication.
- 3 - The CFHEADER module will write to and read from the connected IO modules via I²C on every 3 USB Start of Frame (SoF) interrupts, effectively every 3 milliseconds. The I²C communication will be performed regardless of whether the CFHEADER module has received a USB OUT transfer from the USB host. If the CFHEADER is not connected to a USB host, it will not receive SoF packets, so will, therefore, not perform any I²C communication.
- etc…
Use the Cfheader.NumberOfI2cIterations to check if the USB host and CFHEADER module are synchronized. If the USB host and CFHEADER module are perfectly synchronized, then this value should increment by exactly 1 for every call to Cfheader.Sync().
As you connect additional CFNET IO modules to the CFHEADER, the I²C control loop will require more time to service all of the modules. To keep the USB host and CFHEADER synchronized, you may need to increase the NumberOfUsbFramesToSync property as additional CFNET IO modules are connected to the CFHEADER. Also, if many IO modules are required, consider distributing them through multiple CFHEADER modules to achieve communication with multiple modules in parallel.
Configuring Real-time Features of the USB Host
Although the Start of Frame (SoF) packet provides a reliable way to synchronize the USB host with its connected devices, it does not mean the host application and/or host operating system can schedule a USB transfer in synchronization with the SoF packet. That will depend on what else the host application and host operating system are doing and how they schedule their work, among many other things.
Ordinary distributions of Windows and Linux hosts are not real-time operating systems, so achieving hard real-time scheduling of USB transfers to the CFHEADER module will likely not be possible, but there are features of both operating systems, some described below, that can be leveraged to improve their real-time performance.
Windows
In C#, it is possible to configure an application for RealTime scheduling via the ProcessPriorityClass enum. However, changing to the RealTime option requires running the process with Administrator privileges.
A process can also be given real-time scheduling using task manager, as shown below:
Making further improvements to Windows' real-time performance will likely require configuration changes to the operating system itself. Please see the Windows soft real time documentation for more information.
Linux
Linux also has utilities and features that can be used to configure processes and threads for real-time scheduling, as well as setting CPU affinity and reserving CPU cores. For more information, please refer to the techniques described in our application note for improving real-time performance on our ComfilePi Linux panel PCs.
Avoid Heap Memory Allocations in the Sync() Thread
The garbage collector in the .NET runtime can cause periodic or intermittent disruptions to the timing of your CFHEADER IO. If you notice the timing of your CFHEADER IO periodically or intermittently deviating from otherwise consistent behavior, it might be due to the garbage collector.
.NET does not provide a way to permanently disable the garbage collection, but there is a simple way to avoid it: Don't allocate memory on the heap. The Cfheader.Sync() method has already been carefully optimized to avoid any heap allocations, but to maintain that optimization, the thread that calls Sync(), and any event handlers tied to it, must also not allocate memory on the heap. If heap allocations are carefully avoided and eliminated, the garbage collector will not run, and the timing of the main loop calling Sync() will be significantly improved.

