The purpose of this page is to describe the kinds of motion control hardware interfaces that are well-suited to emc2's hal. Some specific cases of non-compatible interfaces are also discussed.
- 1. Physical Interface
- 2. HAL's timing model
3. Why isn't there support for <interface>
- 2.1. Realtime API
- 2.2. No buffering
- 2.3. No externally-initiated reads or writes
- 2.4. "fairly fast"
- 3.1. Ethernet
- 3.2. USB
- 3.3. RS232 Serial
1. Physical Interface
At present, there are three major physical interfaces used by emc2-supported hardware:
- Parport (SPP and EPP)
- ISA (extremely limited availablity on new hardware)
2. HAL's timing model
In HAL, all I/O is initiated by hal functions which run with an order and timing specified in the HAL configuration. Typically, the "servo thread" runs every 1ms and can be broadly divided into three separate steps:
- Read all inputs from external hardware including position feedback (sense)
- Trajectory planner, ladder logic, pid, etc (model, plan)
- Write all outputs on external hardware, including torque/velocity commands (act)
(On machines with software step generation, software PWM, or software encoder counting, there's also a "fast thread" which does low-level I/O at rates of up to 50kHz or so. In that case, "read inputs from external hardware" consists of latching counters maintained by the fast thread, and "write outputs" consists of updating registers such as step frequency registers which are then used staring in the next invocation of the fast thread)
2.1. Realtime API
In a HAL realtime function, only a very restricted set of APIs be called. Basically, these consist of:
- access to the HAL shared memory region and to hardware memory-mapped I/O previously mapped by a setup function
- hal_XXX and rtapi_XXX functions noted as OK to call from realtime tasks
- inb/w/l(), outb/w/l() for direct register-level access to hardware
- functions defined by the underlying rtos (e.g., rtai) which are nonblocking
APIs that cannot be used include:
- standard POSIX APIs (the underlying functions used by normal Linux userspace processes)
- linux kernel APIs (the underlying functions used by normal Linux hardware drivers)
For instance, the HAL parport driver cannot call the Linux kernel function "parport_write_data()" to communicate with the parport hardware. Instead, it uses outb() directly. This is one reason that hardware support tends towards simple, bit-bangable hardware like parport and pci-bus and away from complex hardware like USB and Ethernet.
2.2. No buffering
In other products, external buffers are used to compensate for lack of true realtime in the PC. Any external device which buffers up motion is a bad fit for emc2. While various ways to allow external buffering have been proposed, working code has never been submitted. With external buffering, some features will simply not work. This includes closing the PID loop in the PC, spindle synchronized moves, homing, and other items.
2.3. No externally-initiated reads or writes
Externally initiated reads and writes are similar to buffering. They introduce undesirable phase shift. Imagine that emc's servo loop runs at a nominal 1kHz, and so does an externally initiated read of feedback position. However, the actual periods are 990Hz and 1000Hz. The two frequencies will beat at 10Hz. At its worst, the new feedback value will come just after a new command value, causing the motor to seem to move as little as 1% as far as PID commanded it to. This variable phase shift might produce a completely untunable system; at best it will provide a difficult to tune system.
2.4. "fairly fast"
The total time to read and write the external hardware (including all overhead for initiating reads and writes) should be fairly small compared to 1ms--ballpark figure, 200us. For example, using a bandwidth of 2megabit/second for EPP
, 50 bytes can be transferred in 200us.
If the read and write is not "fairly fast", two problems occur. First, there is less time left over for linux userspace programs such as the user interface. Second, the time from read to write represents a phase shift which (even though it is roughly constant) can still hurt the tunability of the system.
3. Why isn't there support for <interface>
Linux hardware drivers cannot be used from the realtime context, so it is not possible to reuse them. In principle, emc supports two different real-time kernels (rtlinux and rtai) and they have no mutually compatiable hardware drivers. For this reason, hal hardware drivers have been written in the lowest possible terms: inb(), outb() and the like. Realistically, the only real-time kernel we know of people using with emc2 is rtai. For this reason, it is reasonable to consider using higher-level drivers that work with rtai.
In principle, the RTAI realtime kernel has a network interface, RTnet
. However, no one has ever submitted a driver that uses RTnet. It is not clear whether RTnet as written will work with HAL's timing model.
(Note: A working ethernet HAL driver using RTNet is currently being developed, see rt-8p8c.)
In principle, there is an RTAI project to add USB support, rt-usb
. However, no one has ever submitted a driver that uses rt-usb. It is not clear whether USB can meet HAL's timing model.
3.3. RS232 Serial
Many PCs have a common, easy-to-program chip for RS232 serial interfaces, the 16550 FIFO. However, the top speed is 115200baud. In 200us, only 16 usable bits can be transmitted in each direction (10 bit times per character, 2 characters = 173uS), which is not enough to send DAC commands and retrieve position feedback for multiple axes.