Traditional Grbl is designed to be used with an external sender - a program running on a different computer that reads GCode lines from a file and sends them one at a time to the controller over a serial connection. The controller microcomputer has no concept of grouping; it just executes each line as it arrives, although it does try to create smooth motion between lines if they arrive quickly enough. The controller does not know when the end of a sequence of lines has been reached; if there is a pause after a line, another line might arrive soon, or later, or not at all.
FluidNC can operate like that, but it can also read files and macros from local storage or SD cards. Subsequently, in this discussion, I will use the word “file” to mean either a file or a macro, since they behave essentially the same.
A file has a beginning and an end, so FluidNC can know when it has no more lines. This opens up the possibility of nested execution, where one file or can run a program from another file, then the first file would resume when the second is done. As of version 3.8.0, FluidNC has a “Job Control” feature that allows such nested execution. There is no specific limitation on the number of nesting levels, so one file could run a second, which runs a third, etc.
We use the word “job” to mean the execution of a file along with any other files that it might invoke. A job starts when the first file begins execution and, unless there are errors, ends when all nested files have completed, returned control to their “caller”, and the first file has executed all of its lines.
The primary interface to FluidNC is ultimately through a user interface program connected to an interactive channel such as a serial interface. WebUI also controls FluidNC through an interactive channel such as the HTTP API or a WebSocket. The user interface program starts a job by sending a command like $SD/Run=filename over such an interactive channel. The channel that was used to start the job is called the Job Leader . Any error messages that arise as a result of the job will be send to the Job Leader channel to be handled by the associated user interface program.
If an error occurs during a job, the job “aborts” - the file that was running at the time stops and all caller files “above” it (at higher nesting levels) also stop. Aborts include not only GCode errors like invalid commands that are detected by the GCode parser, but also alarm conditions arising from things like probe failures, soft limit violations, limit switch activations, or user-initiated reset.
From the user interface point of view, nothing changes. You just run a file or macro from the UI program the same was as always. But now the file or macro can do things it could not do before, as described below.
Before the introduction of Job Control, FluidNC was capable of a very limited form of nesting. A macro could invoke a file run command like $SD/Run=filename, but when that file finished, it was not possible to resume execution of the macro and do other things. Similarly, if one macro invoked another macro, but returning to the first afterward the second one finished was not possible. Previously, running one SD file from inside another was impossible.
Now it is possible to do pretty much anything in this regard. A macro can run a file which runs a second file then does something after the second finished, then after the first file finishes, the macro can do other things, perhaps running other files or macros. This allows you to create fine-grained macros and programs that perform targeted sequences of operations, and use them inside other macros to perform more complex operations without unnecessary duplication of code. This can be especially useful in conjunction with Parameters and Expressions.
macros:
macro0: $macros/run=1 & G0 X1 Y3 & $macros/run=2
macro1: G1 X10 F100 & $SD/Run=test.nc & G1 Y5 F200
macro2: $SD/Run=probe.nc & G10 L20 P1 Z0
Contents of /sd/test.nc:
G53 G0 X5 Y20
$SD/Run=test2.nc
G92 X0 Y0
$SD/Run=test3.nc
The examples above are not necessarily useful; rather they illustrate the many ways that you can run files from within other files.