mirror of https://github.com/Desuuuu/klipper.git
docs: Avoid using "firmware" in the documentation
The term "firmware" is ambiguous - it could refer to the entire project (host and micro-controller software) or to just the micro-controller software. Avoid the term in the documentation. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
parent
d7a1111955
commit
c1c0b2dd38
|
@ -17,7 +17,7 @@ host architectures. The build arranges for includes of
|
|||
src/generic/somefile.h).
|
||||
|
||||
The **klippy/** directory contains the C and Python source for the
|
||||
host part of the firmware.
|
||||
host part of the software.
|
||||
|
||||
The **lib/** directory contains external 3rd-party library code that
|
||||
is necessary to build some targets.
|
||||
|
@ -92,8 +92,8 @@ some functionality in C code.
|
|||
Initial execution starts in **klippy/klippy.py**. This reads the
|
||||
command-line arguments, opens the printer config file, instantiates
|
||||
the main printer objects, and starts the serial connection. The main
|
||||
execution of gcode commands is in the process_commands() method in
|
||||
**klippy/gcode.py**. This code translates the gcode commands into
|
||||
execution of G-code commands is in the process_commands() method in
|
||||
**klippy/gcode.py**. This code translates the G-code commands into
|
||||
printer object calls, which frequently translate the actions to
|
||||
commands to be executed on the micro-controller (as declared via the
|
||||
DECL_COMMAND macro in the micro-controller code).
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
The Klippy host code has some tools to help in debugging the firmware.
|
||||
The Klippy host code has some tools to help in debugging.
|
||||
|
||||
Translating gcode files to firmware commands
|
||||
============================================
|
||||
Translating gcode files to micro-controller commands
|
||||
====================================================
|
||||
|
||||
The Klippy host code can run in a batch mode to produce the low-level
|
||||
firmware commands associated with a gcode file. Inspecting these
|
||||
low-level firmware commands is useful when trying to understand the
|
||||
micro-controller commands associated with a gcode file. Inspecting
|
||||
these low-level commands is useful when trying to understand the
|
||||
actions of the low-level hardware. It can also be useful to compare
|
||||
the difference in firmware commands after a code change.
|
||||
the difference in micro-controller commands after a code change.
|
||||
|
||||
To run Klippy in this batch mode, there is a one time step necessary
|
||||
to generate the firmware "data dictionary". This is done by compiling
|
||||
the firmware code to obtain the **out/klipper.dict** file:
|
||||
to generate the micro-controller "data dictionary". This is done by
|
||||
compiling the micro-controller code to obtain the **out/klipper.dict**
|
||||
file:
|
||||
|
||||
```
|
||||
make menuconfig
|
||||
|
@ -34,13 +35,13 @@ output. This output can be translated to readable text with:
|
|||
```
|
||||
|
||||
The resulting file **test.txt** contains a human readable list of
|
||||
firmware commands.
|
||||
micro-controller commands.
|
||||
|
||||
The batch mode disables certain response / request commands in order
|
||||
to function. As a result, there will be some differences between
|
||||
actual firmware commands and the above output. The generated data is
|
||||
useful for testing and inspection; it is not useful for sending to a
|
||||
real micro-controller.
|
||||
actual commands and the above output. The generated data is useful for
|
||||
testing and inspection; it is not useful for sending to a real
|
||||
micro-controller.
|
||||
|
||||
Testing with simulavr
|
||||
=====================
|
||||
|
@ -74,9 +75,10 @@ cd /patch/to/klipper
|
|||
make menuconfig
|
||||
```
|
||||
|
||||
and compile the firmware for an AVR atmega644p, disable the AVR
|
||||
watchdog timer, and set the MCU frequency to 20000000. Then one can
|
||||
compile Klipper (run `make`) and then start the simulation with:
|
||||
and compile the micro-controller software for an AVR atmega644p,
|
||||
disable the AVR watchdog timer, and set the MCU frequency
|
||||
to 20000000. Then one can compile Klipper (run `make`) and then start
|
||||
the simulation with:
|
||||
|
||||
```
|
||||
PYTHONPATH=/path/to/simulavr/src/python/ ./scripts/avrsim.py -m atmega644 -s 20000000 -b 250000 out/klipper.elf
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Klipper is a 3d printer firmware with several compelling features:
|
||||
Klipper has several compelling features:
|
||||
|
||||
* High precision stepper movement. Klipper utilizes an application
|
||||
processor (such as a low-cost Raspberry Pi) when calculating printer
|
||||
|
@ -32,9 +32,9 @@ Klipper is a 3d printer firmware with several compelling features:
|
|||
micro-controller architectures as well.
|
||||
|
||||
* Simpler code. Klipper uses a very high level language (Python) for
|
||||
most code. The kinematics algorithms, the gcode parsing, the heating
|
||||
and thermistor algorithms, etc. are all written in Python. This
|
||||
makes it easier to develop new functionality.
|
||||
most code. The kinematics algorithms, the G-code parsing, the
|
||||
heating and thermistor algorithms, etc. are all written in
|
||||
Python. This makes it easier to develop new functionality.
|
||||
|
||||
* Advanced features:
|
||||
* Klipper implements the "pressure advance" algorithm for
|
||||
|
@ -68,10 +68,10 @@ Klipper supports many standard 3d printer features:
|
|||
gradually accelerate from standstill to cruising speed and then
|
||||
decelerate back to a standstill.
|
||||
|
||||
* "Lookahead" support. The incoming stream of G-Code movement commands
|
||||
are queued and analyzed - the acceleration between movements in a
|
||||
similar direction will be optimized to reduce print stalls and
|
||||
improve overall print time.
|
||||
* "Look-ahead" support. The incoming stream of G-Code movement
|
||||
commands are queued and analyzed - the acceleration between
|
||||
movements in a similar direction will be optimized to reduce print
|
||||
stalls and improve overall print time.
|
||||
|
||||
* Support for cartesian, delta, and corexy style printers.
|
||||
|
||||
|
|
|
@ -1,290 +0,0 @@
|
|||
This document provides high-level information on common firmware
|
||||
commands. It is not an authoritative reference for these commands, nor
|
||||
is it an exclusive list of all available firmware commands.
|
||||
|
||||
This document may be useful for users needing to configure a set of
|
||||
hardware actions that their printer may require at startup (via the
|
||||
"custom" field in the printer config file), and it may be useful for
|
||||
developers wishing to obtain a high-level feel for available firmware
|
||||
commands.
|
||||
|
||||
See the [protocol](Protocol.md) document for more information on the
|
||||
format of commands and their low-level transmission. The commands here
|
||||
are described using their "printf" style syntax - for those unfamiliar
|
||||
with that format, just note that where a '%...' sequence is seen it
|
||||
should be replaced with an actual integer. For example, a description
|
||||
with "count=%c" could be replaced with the text "count=10".
|
||||
|
||||
Startup Commands
|
||||
================
|
||||
|
||||
It may be necessary to take certain one-time actions to configure the
|
||||
micro-controller and its peripherals. This section lists common
|
||||
commands available for that purpose. Unlike other firmware commands,
|
||||
these commands run as soon as they are received by the firmware and
|
||||
they do not require any particular setup.
|
||||
|
||||
These commands are most useful in the "custom" block of the "mcu"
|
||||
section of the printer configuration file. This feature is typically
|
||||
used to configure the initial settings of LEDs, to configure
|
||||
micro-stepping pins, to configure a digipot, etc.
|
||||
|
||||
Several of these commands will take a "pin=%u" parameter. The
|
||||
low-level firmware uses integer encodings of the hardware pin numbers,
|
||||
but to make things more readable the host will translate human
|
||||
readable pin names (eg, "PA3") to their equivalent integer
|
||||
encodings. By convention, any parameter named "pin" or that has a
|
||||
"_pin" suffix will use pin name translation by the host. Similarly,
|
||||
several commands take time parameters specified in clock ticks. One
|
||||
can specify a value for these parameters in seconds using the
|
||||
"TICKS()" macro - for example "cycle_ticks=TICKS(0.001)" would result
|
||||
in "cycle_ticks=16000" on a micro-controller with a 16Mhz clock.
|
||||
|
||||
Common startup commands:
|
||||
|
||||
* `set_digital_out pin=%u value=%c` : This command immediately
|
||||
configures the given pin as a digital out GPIO and it sets it to
|
||||
either a low level (value=0) or a high level (value=1). This command
|
||||
may be useful for configuring the initial value of LEDs and for
|
||||
configuring the initial value of stepper driver micro-stepping pins.
|
||||
|
||||
* `set_pwm_out pin=%u cycle_ticks=%u value=%c` : This command will
|
||||
immediately configure the given pin to use hardware based
|
||||
pulse-width-modulation (PWM) with the given number of
|
||||
cycle_ticks. The "cycle_ticks" is the number of MCU clock ticks each
|
||||
power on and power off cycle should last. A cycle_ticks value of 1
|
||||
can be used to request the fastest possible cycle time. The "value"
|
||||
parameter is between 0 and 255 with 0 indicating a full off state
|
||||
and 255 indicating a full on state. This command may be useful for
|
||||
enabling CPU and nozzle cooling fans.
|
||||
|
||||
* `send_spi_message pin=%u msg=%*s` : This command can be used to
|
||||
transmit messages to a serial-peripheral-interface (SPI) component
|
||||
connected to the micro-controller. It has been used to configure the
|
||||
startup settings of AD5206 digipots. The 'pin' parameter specifies
|
||||
the chip select line to use during the transmission. The 'msg'
|
||||
indicates the binary message to transmit to the given chip.
|
||||
|
||||
Firmware configuration
|
||||
======================
|
||||
|
||||
Most commands in the firmware require an initial setup before they can
|
||||
be successfully invoked. This section provides a high-level overview
|
||||
of the micro-controller configuration process. This section and the
|
||||
following sections are likely only of interest to developers
|
||||
interested in the internal details of Klipper.
|
||||
|
||||
When the host first connects to the firmware it always starts by
|
||||
obtaining the firmware's data dictionary (see [protocol](Protocol.md)
|
||||
for more information). After the data dictionary is obtained the host
|
||||
will check if the firmware is in a "configured" state and configure it
|
||||
if not. Configuration involves the following phases:
|
||||
|
||||
* `get_config` : The host starts by checking if the firmware is already
|
||||
configured. The firmware responds to this command with a "config"
|
||||
response message. At micro-controller power-on the firmware always
|
||||
starts in an unconfigured state. It remains in this state until the
|
||||
host completes the configuration processes (by issuing a
|
||||
finalize_config command). If the firmware is already configured (and
|
||||
is configured with the desired settings) from a previous
|
||||
host/firmware session then no further action is needed by the host
|
||||
and the configuration process ends successfully.
|
||||
|
||||
* `allocate_oids count=%c` : This command is issued to inform the
|
||||
firmware the maximum number of object-ids (oid) that the host
|
||||
requires. It is only valid to issue this command once. An oid is an
|
||||
integer identifier allocated to each stepper, each endstop, and each
|
||||
schedulable gpio pin. The host determines in advance the number of
|
||||
oids it will require to operate the hardware and passes this to the
|
||||
firmware so that the firmware may allocate sufficient memory to
|
||||
store a mapping from oid to internal firmware object.
|
||||
|
||||
* `config_XXX oid=%c ...` : By convention any command starting with
|
||||
the "config_" prefix creates a new firmware object and assigns the
|
||||
given oid to it. For example, the config_digital_out command will
|
||||
configure the specified pin as a digital output GPIO and create an
|
||||
internal object that the host can use to schedule changes to the
|
||||
given GPIO. The oid parameter passed into the config command is
|
||||
selected by the host and must be between zero and the maximum count
|
||||
supplied in the allocate_oids command. The config commands may only
|
||||
be run when the firmware is not in a configured state (ie, prior to
|
||||
the host sending finalize_config) and after the allocate_oids
|
||||
command has been sent.
|
||||
|
||||
* `finalize_config crc=%u` : The finalize_config command transitions
|
||||
the firmware from an unconfigured state to a configured state. The
|
||||
crc parameter passed to the firmware is stored in the firmware and
|
||||
provided back to the host in "config" response messages. By
|
||||
convention, the host takes a 32bit CRC of the firmware configuration
|
||||
it will request and at the start of subsequent host/firmware
|
||||
communication sessions it checks that the CRC stored in the firmware
|
||||
exactly matches its desired CRC. If the CRC does not match then the
|
||||
host knows the firmware has not been configured in the state desired
|
||||
by the host.
|
||||
|
||||
Common firmware objects
|
||||
-----------------------
|
||||
|
||||
This section lists some commonly used config commands.
|
||||
|
||||
* `config_digital_out oid=%c pin=%u default_value=%c
|
||||
max_duration=%u` : This command creates an internal firmware object
|
||||
for the given GPIO 'pin'. The pin will be configured in digital
|
||||
output mode and set to an initial value as specified by
|
||||
'default_value' (0 for low, 1 for high). Creating a digital_out
|
||||
object allows the host to schedule GPIO updates for the given pin at
|
||||
specified times (see the schedule_digital_out command described
|
||||
below). Should the firmware go into shutdown mode then all
|
||||
configured digital_out objects will be set back to their default
|
||||
values. The 'max_duration' parameter is used to implement a safety
|
||||
check - if it is non-zero then it is the maximum number of clock
|
||||
ticks that the host may set the given GPIO to a non-default value
|
||||
without further updates. For example, if the default_value is zero
|
||||
and the max_duration is 16000 then if the host sets the gpio to a
|
||||
value of one then it must schedule another update to the gpio pin
|
||||
(to either zero or one) within 16000 clock ticks. This safety
|
||||
feature can be used with heater pins to ensure the host does not set
|
||||
the heater to a value of one and then go off-line.
|
||||
|
||||
* `config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
||||
max_duration=%u` : This command creates an internal object for
|
||||
hardware based PWM pins that the host may schedule updates for. Its
|
||||
usage is analogous to config_digital_out - see the description of
|
||||
the 'set_pwm_out' and 'config_digital_out' commands for parameter
|
||||
description.
|
||||
|
||||
* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
||||
max_duration=%u` : This command creates an internal firmware object
|
||||
for software implemented PWM. Unlike hardware pwm pins, a software
|
||||
pwm object does not require any special hardware support (other than
|
||||
the ability to configure the pin as a digital output GPIO). Because
|
||||
the output switching is implemented in the software of the firmware,
|
||||
it is recommended that the cycle_ticks parameter correspond to a
|
||||
time of 10ms or greater. See the description of the 'set_pwm_out'
|
||||
and 'config_digital_out' commands for parameter description.
|
||||
|
||||
* `config_analog_in oid=%c pin=%u` : This command is used to configure
|
||||
a pin in analog input sampling mode. Once configured, the pin can be
|
||||
sampled at regular interval using the query_analog_in command (see
|
||||
below).
|
||||
|
||||
* `config_stepper oid=%c step_pin=%c dir_pin=%c min_stop_interval=%u
|
||||
invert_step=%c` : This command creates an internal stepper
|
||||
object. The 'step_pin' and 'dir_pin' parameters specify the step and
|
||||
direction pins respectively; this command will configure them in
|
||||
digital output mode. The 'invert_step' parameter specifies whether a
|
||||
step occurs on a rising edge (invert_step=0) or falling edge
|
||||
(invert_step=1). The 'min_stop_interval' implements a safety
|
||||
feature - it is checked when the firmware finishes all moves for a
|
||||
stepper - if it is non-zero it specifies the minimum number of clock
|
||||
ticks since the last step. It is used as a check on the maximum
|
||||
stepper velocity that a stepper may have before stopping.
|
||||
|
||||
* `config_end_stop oid=%c pin=%c pull_up=%c stepper_count=%c` : This
|
||||
command creates an internal "endstop" object. It is used to specify
|
||||
the endstop pins and to enable "homing" operations (see the
|
||||
end_stop_home command below). The command will configure the
|
||||
specified pin in digital input mode. The 'pull_up' parameter
|
||||
determines whether hardware provided pullup resistors for the pin
|
||||
(if available) will be enabled. The 'stepper_count' parameter
|
||||
specifies the maximum number of steppers that this endstop may need
|
||||
to halt during a homing operation (see end_stop_home below).
|
||||
|
||||
Common commands
|
||||
===============
|
||||
|
||||
This section lists some commonly used run-time commands. It is likely
|
||||
only of interest to developers looking to gain insight into Klippy.
|
||||
|
||||
* `schedule_digital_out oid=%c clock=%u value=%c` : This command will
|
||||
schedule a change to a digital output GPIO pin at the given clock
|
||||
time. To use this command a 'config_digital_out' command with the
|
||||
same 'oid' parameter must have been issued during firmware
|
||||
configuration.
|
||||
|
||||
* `schedule_pwm_out oid=%c clock=%u value=%c` : Schedules a change to
|
||||
a hardware PWM output pin. See the 'schedule_digital_out' and
|
||||
'config_pwm_out' commands for more info.
|
||||
|
||||
* `schedule_soft_pwm_out oid=%c clock=%u value=%c` : Schedules a
|
||||
change to a software PWM output pin. See the 'schedule_digital_out'
|
||||
and 'config_soft_pwm_out' commands for more info.
|
||||
|
||||
* `query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c
|
||||
rest_ticks=%u min_value=%hu max_value=%hu` : This command sets up a
|
||||
recurring schedule of analog input samples. To use this command a
|
||||
'config_analog_in' command with the same 'oid' parameter must have
|
||||
been issued during firmware configuration. The samples will start as
|
||||
of 'clock' time, it will report on the obtained value every
|
||||
'rest_ticks' clock ticks, it will over-sample 'sample_count' number
|
||||
of times, and it will pause 'sample_ticks' number of clock ticks
|
||||
between over-sample samples. The 'min_value' and 'max_value'
|
||||
parameters implement a safety feature - the firmware will verify the
|
||||
sampled value (after any oversampling) is always between the
|
||||
supplied range. This is intended for use with pins attached to
|
||||
thermistors controlling heaters - it can be used to check that a
|
||||
heater is within a temperature range.
|
||||
|
||||
* `get_status` : This command causes the firmware to generate a
|
||||
"status" response message. The host sends this command once a second
|
||||
to obtain the value of the micro-controller clock and to estimate
|
||||
the drift between host and micro-controller clocks. It enables the
|
||||
host to accurately estimate the micro-controller clock.
|
||||
|
||||
Stepper commands
|
||||
----------------
|
||||
|
||||
* `queue_step oid=%c interval=%u count=%hu add=%hi` : This command
|
||||
schedules 'count' number of steps for the given stepper, with
|
||||
'interval' number of clock ticks between each step. The first step
|
||||
will be 'interval' number of clock ticks since the last scheduled
|
||||
step for the given stepper. If 'add' is non-zero then the interval
|
||||
will be adjusted by 'add' amount after each step. This command
|
||||
appends the given interval/count/add sequence to a per-stepper
|
||||
queue. There may be hundreds of these sequences queued during normal
|
||||
operation. New sequence are appended to the end of the queue and as
|
||||
each sequence completes its 'count' number of steps it is popped
|
||||
from the front of the queue. This system allows the firmware to
|
||||
queue potentially hundreds of thousands of steps - all with reliable
|
||||
and predictable schedule times.
|
||||
|
||||
* `set_next_step_dir oid=%c dir=%c` : This command specifies the value
|
||||
of the dir_pin that the next queue_step command will use.
|
||||
|
||||
* `reset_step_clock oid=%c clock=%u` : Normally, step timing is
|
||||
relative to the last step for a given stepper. This command resets
|
||||
the clock so that the next step is relative to the supplied 'clock'
|
||||
time. The host usually only sends this command at the start of a
|
||||
print.
|
||||
|
||||
* `stepper_get_position oid=%c` : This command causes the firmware to
|
||||
generate a "stepper_position" response message with the stepper's
|
||||
current position. The position is the total number of steps
|
||||
generated with dir=1 minus the total number of steps generated with
|
||||
dir=0.
|
||||
|
||||
* `end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c` : This
|
||||
command is used during stepper "homing" operations. To use this
|
||||
command a 'config_end_stop' command with the same 'oid' parameter
|
||||
must have been issued during firmware configuration. When invoked,
|
||||
the firmware will sample the endstop pin every 'rest_ticks' clock
|
||||
ticks and check if it has a value equal to 'pin_value'. If the value
|
||||
matches then the movement queue for the associated stepper will be
|
||||
cleared and the stepper will come to an immediate halt. The host
|
||||
uses this command to implement homing - the host instructs the
|
||||
endstop to sample for the endstop trigger and then it issues a
|
||||
series of queue_step commands to the stepper to move it towards the
|
||||
endstop. Once the stepper hits the endstop, the trigger will be
|
||||
detected, the movement halted, and the host notified.
|
||||
|
||||
### Move queue
|
||||
|
||||
Each queue_step command utilizes an entry in the firmware "move
|
||||
queue". The firmware allocates this queue when it receives the
|
||||
"finalize_config" command, and it reports the number of available
|
||||
queue entries in "config" response messages.
|
||||
|
||||
It is the responsibility of the host to ensure that there is available
|
||||
space in the queue before sending a queue_step command. The host does
|
||||
this by calculating when each queue_step command completes and
|
||||
scheduling new queue_step commands accordingly.
|
|
@ -0,0 +1,294 @@
|
|||
This document provides information on the low-level micro-controller
|
||||
commands that are sent from the Klipper "host" software and processed
|
||||
by the Klipper micro-controller software. This document is not an
|
||||
authoritative reference for these commands, nor is it an exclusive
|
||||
list of all available commands.
|
||||
|
||||
This document may be useful for users needing to configure a set of
|
||||
hardware actions that their printer may require at startup (via the
|
||||
"custom" field in the printer config file), and it may be useful for
|
||||
developers wishing to obtain a high-level feel for low-level commands.
|
||||
|
||||
See the [protocol](Protocol.md) document for more information on the
|
||||
format of commands and their transmission. The commands here are
|
||||
described using their "printf" style syntax - for those unfamiliar
|
||||
with that format, just note that where a '%...' sequence is seen it
|
||||
should be replaced with an actual integer. For example, a description
|
||||
with "count=%c" could be replaced with the text "count=10".
|
||||
|
||||
Startup Commands
|
||||
================
|
||||
|
||||
It may be necessary to take certain one-time actions to configure the
|
||||
micro-controller and its peripherals. This section lists common
|
||||
commands available for that purpose. Unlike most micro-controller
|
||||
commands, these commands run as soon as they are received and they do
|
||||
not require any particular setup.
|
||||
|
||||
These commands are most useful in the "custom" block of the "mcu"
|
||||
section of the printer configuration file. This feature is typically
|
||||
used to configure the initial settings of LEDs, to configure
|
||||
micro-stepping pins, to configure a digipot, etc.
|
||||
|
||||
Several of these commands will take a "pin=%u" parameter. The
|
||||
low-level micro-controller software uses integer encodings of the
|
||||
hardware pin numbers, but to make things more readable the host will
|
||||
translate human readable pin names (eg, "PA3") to their equivalent
|
||||
integer encodings. By convention, any parameter named "pin" or that
|
||||
has a "_pin" suffix will use pin name translation by the
|
||||
host. Similarly, several commands take time parameters specified in
|
||||
clock ticks. One can specify a value for these parameters in seconds
|
||||
using the "TICKS()" macro - for example "cycle_ticks=TICKS(0.001)"
|
||||
would result in "cycle_ticks=16000" on a micro-controller with a 16Mhz
|
||||
clock.
|
||||
|
||||
Common startup commands:
|
||||
|
||||
* `set_digital_out pin=%u value=%c` : This command immediately
|
||||
configures the given pin as a digital out GPIO and it sets it to
|
||||
either a low level (value=0) or a high level (value=1). This command
|
||||
may be useful for configuring the initial value of LEDs and for
|
||||
configuring the initial value of stepper driver micro-stepping pins.
|
||||
|
||||
* `set_pwm_out pin=%u cycle_ticks=%u value=%c` : This command will
|
||||
immediately configure the given pin to use hardware based
|
||||
pulse-width-modulation (PWM) with the given number of
|
||||
cycle_ticks. The "cycle_ticks" is the number of MCU clock ticks each
|
||||
power on and power off cycle should last. A cycle_ticks value of 1
|
||||
can be used to request the fastest possible cycle time. The "value"
|
||||
parameter is between 0 and 255 with 0 indicating a full off state
|
||||
and 255 indicating a full on state. This command may be useful for
|
||||
enabling CPU and nozzle cooling fans.
|
||||
|
||||
* `send_spi_message pin=%u msg=%*s` : This command can be used to
|
||||
transmit messages to a serial-peripheral-interface (SPI) component
|
||||
connected to the micro-controller. It has been used to configure the
|
||||
startup settings of AD5206 digipots. The 'pin' parameter specifies
|
||||
the chip select line to use during the transmission. The 'msg'
|
||||
indicates the binary message to transmit to the given chip.
|
||||
|
||||
Low-level micro-controller configuration
|
||||
========================================
|
||||
|
||||
Most commands in the micro-controller require an initial setup before
|
||||
they can be successfully invoked. This section provides an overview of
|
||||
the configuration process. This section and the following sections are
|
||||
likely only of interest to developers interested in the internal
|
||||
details of Klipper.
|
||||
|
||||
When the host first connects to the micro-controller it always starts
|
||||
by obtaining a data dictionary (see [protocol](Protocol.md) for more
|
||||
information). After the data dictionary is obtained the host will
|
||||
check if the micro-controller is in a "configured" state and configure
|
||||
it if not. Configuration involves the following phases:
|
||||
|
||||
* `get_config` : The host starts by checking if the micro-controller
|
||||
is already configured. The micro-controller responds to this command
|
||||
with a "config" response message. The micro-controller software
|
||||
always starts in an unconfigured state at power-on. It remains in
|
||||
this state until the host completes the configuration processes (by
|
||||
issuing a finalize_config command). If the micro-controller is
|
||||
already configured from a previous session (and is configured with
|
||||
the desired settings) then no further action is needed by the host
|
||||
and the configuration process ends successfully.
|
||||
|
||||
* `allocate_oids count=%c` : This command is issued to inform the
|
||||
micro-controller of the maximum number of object-ids (oid) that the
|
||||
host requires. It is only valid to issue this command once. An oid
|
||||
is an integer identifier allocated to each stepper, each endstop,
|
||||
and each schedulable gpio pin. The host determines in advance the
|
||||
number of oids it will require to operate the hardware and passes
|
||||
this to the micro-controller so that it may allocate sufficient
|
||||
memory to store a mapping from oid to internal object.
|
||||
|
||||
* `config_XXX oid=%c ...` : By convention any command starting with
|
||||
the "config_" prefix creates a new micro-controller object and
|
||||
assigns the given oid to it. For example, the config_digital_out
|
||||
command will configure the specified pin as a digital output GPIO
|
||||
and create an internal object that the host can use to schedule
|
||||
changes to the given GPIO. The oid parameter passed into the config
|
||||
command is selected by the host and must be between zero and the
|
||||
maximum count supplied in the allocate_oids command. The config
|
||||
commands may only be run when the micro-controller is not in a
|
||||
configured state (ie, prior to the host sending finalize_config) and
|
||||
after the allocate_oids command has been sent.
|
||||
|
||||
* `finalize_config crc=%u` : The finalize_config command transitions
|
||||
the micro-controller from an unconfigured state to a configured
|
||||
state. The crc parameter passed to the micro-controller is stored
|
||||
and provided back to the host in "config" response messages. By
|
||||
convention, the host takes a 32bit CRC of the configuration it will
|
||||
request and at the start of subsequent communication sessions it
|
||||
checks that the CRC stored in the micro-controller exactly matches
|
||||
its desired CRC. If the CRC does not match then the host knows the
|
||||
micro-controller has not been configured in the state desired by the
|
||||
host.
|
||||
|
||||
Common micro-controller objects
|
||||
-------------------------------
|
||||
|
||||
This section lists some commonly used config commands.
|
||||
|
||||
* `config_digital_out oid=%c pin=%u default_value=%c
|
||||
max_duration=%u` : This command creates an internal micro-controller
|
||||
object for the given GPIO 'pin'. The pin will be configured in
|
||||
digital output mode and set to an initial value as specified by
|
||||
'default_value' (0 for low, 1 for high). Creating a digital_out
|
||||
object allows the host to schedule GPIO updates for the given pin at
|
||||
specified times (see the schedule_digital_out command described
|
||||
below). Should the micro-controller software go into shutdown mode
|
||||
then all configured digital_out objects will be set back to their
|
||||
default values. The 'max_duration' parameter is used to implement a
|
||||
safety check - if it is non-zero then it is the maximum number of
|
||||
clock ticks that the host may set the given GPIO to a non-default
|
||||
value without further updates. For example, if the default_value is
|
||||
zero and the max_duration is 16000 then if the host sets the gpio to
|
||||
a value of one then it must schedule another update to the gpio pin
|
||||
(to either zero or one) within 16000 clock ticks. This safety
|
||||
feature can be used with heater pins to ensure the host does not
|
||||
enable the heater and then go off-line.
|
||||
|
||||
* `config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
||||
max_duration=%u` : This command creates an internal object for
|
||||
hardware based PWM pins that the host may schedule updates for. Its
|
||||
usage is analogous to config_digital_out - see the description of
|
||||
the 'set_pwm_out' and 'config_digital_out' commands for parameter
|
||||
description.
|
||||
|
||||
* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
|
||||
max_duration=%u` : This command creates an internal micro-controller
|
||||
object for software implemented PWM. Unlike hardware pwm pins, a
|
||||
software pwm object does not require any special hardware support
|
||||
(other than the ability to configure the pin as a digital output
|
||||
GPIO). Because the output switching is implemented in the
|
||||
micro-controller software, it is recommended that the cycle_ticks
|
||||
parameter correspond to a time of 10ms or greater. See the
|
||||
description of the 'set_pwm_out' and 'config_digital_out' commands
|
||||
for parameter description.
|
||||
|
||||
* `config_analog_in oid=%c pin=%u` : This command is used to configure
|
||||
a pin in analog input sampling mode. Once configured, the pin can be
|
||||
sampled at regular interval using the query_analog_in command (see
|
||||
below).
|
||||
|
||||
* `config_stepper oid=%c step_pin=%c dir_pin=%c min_stop_interval=%u
|
||||
invert_step=%c` : This command creates an internal stepper
|
||||
object. The 'step_pin' and 'dir_pin' parameters specify the step and
|
||||
direction pins respectively; this command will configure them in
|
||||
digital output mode. The 'invert_step' parameter specifies whether a
|
||||
step occurs on a rising edge (invert_step=0) or falling edge
|
||||
(invert_step=1). The 'min_stop_interval' implements a safety
|
||||
feature - it is checked when the micro-controller finishes all moves
|
||||
for a stepper - if it is non-zero it specifies the minimum number of
|
||||
clock ticks since the last step. It is used as a check on the
|
||||
maximum stepper velocity that a stepper may have before stopping.
|
||||
|
||||
* `config_end_stop oid=%c pin=%c pull_up=%c stepper_count=%c` : This
|
||||
command creates an internal "endstop" object. It is used to specify
|
||||
the endstop pins and to enable "homing" operations (see the
|
||||
end_stop_home command below). The command will configure the
|
||||
specified pin in digital input mode. The 'pull_up' parameter
|
||||
determines whether hardware provided pullup resistors for the pin
|
||||
(if available) will be enabled. The 'stepper_count' parameter
|
||||
specifies the maximum number of steppers that this endstop may need
|
||||
to halt during a homing operation (see end_stop_home below).
|
||||
|
||||
Common commands
|
||||
===============
|
||||
|
||||
This section lists some commonly used run-time commands. It is likely
|
||||
only of interest to developers looking to gain insight into Klipper.
|
||||
|
||||
* `schedule_digital_out oid=%c clock=%u value=%c` : This command will
|
||||
schedule a change to a digital output GPIO pin at the given clock
|
||||
time. To use this command a 'config_digital_out' command with the
|
||||
same 'oid' parameter must have been issued during micro-controller
|
||||
configuration.
|
||||
|
||||
* `schedule_pwm_out oid=%c clock=%u value=%c` : Schedules a change to
|
||||
a hardware PWM output pin. See the 'schedule_digital_out' and
|
||||
'config_pwm_out' commands for more info.
|
||||
|
||||
* `schedule_soft_pwm_out oid=%c clock=%u value=%c` : Schedules a
|
||||
change to a software PWM output pin. See the 'schedule_digital_out'
|
||||
and 'config_soft_pwm_out' commands for more info.
|
||||
|
||||
* `query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c
|
||||
rest_ticks=%u min_value=%hu max_value=%hu` : This command sets up a
|
||||
recurring schedule of analog input samples. To use this command a
|
||||
'config_analog_in' command with the same 'oid' parameter must have
|
||||
been issued during micro-controller configuration. The samples will
|
||||
start as of 'clock' time, it will report on the obtained value every
|
||||
'rest_ticks' clock ticks, it will over-sample 'sample_count' number
|
||||
of times, and it will pause 'sample_ticks' number of clock ticks
|
||||
between over-sample samples. The 'min_value' and 'max_value'
|
||||
parameters implement a safety feature - the micro-controller
|
||||
software will verify the sampled value (after any oversampling) is
|
||||
always between the supplied range. This is intended for use with
|
||||
pins attached to thermistors controlling heaters - it can be used to
|
||||
check that a heater is within a temperature range.
|
||||
|
||||
* `get_status` : This command causes the micro-controller to generate
|
||||
a "status" response message. The host sends this command once a
|
||||
second to obtain the value of the micro-controller clock and to
|
||||
estimate the drift between host and micro-controller clocks. It
|
||||
enables the host to accurately estimate the micro-controller clock.
|
||||
|
||||
Stepper commands
|
||||
----------------
|
||||
|
||||
* `queue_step oid=%c interval=%u count=%hu add=%hi` : This command
|
||||
schedules 'count' number of steps for the given stepper, with
|
||||
'interval' number of clock ticks between each step. The first step
|
||||
will be 'interval' number of clock ticks since the last scheduled
|
||||
step for the given stepper. If 'add' is non-zero then the interval
|
||||
will be adjusted by 'add' amount after each step. This command
|
||||
appends the given interval/count/add sequence to a per-stepper
|
||||
queue. There may be hundreds of these sequences queued during normal
|
||||
operation. New sequence are appended to the end of the queue and as
|
||||
each sequence completes its 'count' number of steps it is popped
|
||||
from the front of the queue. This system allows the micro-controller
|
||||
to queue potentially hundreds of thousands of steps - all with
|
||||
reliable and predictable schedule times.
|
||||
|
||||
* `set_next_step_dir oid=%c dir=%c` : This command specifies the value
|
||||
of the dir_pin that the next queue_step command will use.
|
||||
|
||||
* `reset_step_clock oid=%c clock=%u` : Normally, step timing is
|
||||
relative to the last step for a given stepper. This command resets
|
||||
the clock so that the next step is relative to the supplied 'clock'
|
||||
time. The host usually only sends this command at the start of a
|
||||
print.
|
||||
|
||||
* `stepper_get_position oid=%c` : This command causes the
|
||||
micro-controller to generate a "stepper_position" response message
|
||||
with the stepper's current position. The position is the total
|
||||
number of steps generated with dir=1 minus the total number of steps
|
||||
generated with dir=0.
|
||||
|
||||
* `end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c` : This
|
||||
command is used during stepper "homing" operations. To use this
|
||||
command a 'config_end_stop' command with the same 'oid' parameter
|
||||
must have been issued during micro-controller configuration. When
|
||||
this command is invoked, the micro-controller will sample the
|
||||
endstop pin every 'rest_ticks' clock ticks and check if it has a
|
||||
value equal to 'pin_value'. If the value matches then the movement
|
||||
queue for the associated stepper will be cleared and the stepper
|
||||
will come to an immediate halt. The host uses this command to
|
||||
implement homing - the host instructs the endstop to sample for the
|
||||
endstop trigger and then it issues a series of queue_step commands
|
||||
to move a stepper towards the endstop. Once the stepper hits the
|
||||
endstop, the trigger will be detected, the movement halted, and the
|
||||
host notified.
|
||||
|
||||
### Move queue
|
||||
|
||||
Each queue_step command utilizes an entry in the micro-controller
|
||||
"move queue". This queue is allocated when it receives the
|
||||
"finalize_config" command, and it reports the number of available
|
||||
queue entries in "config" response messages.
|
||||
|
||||
It is the responsibility of the host to ensure that there is available
|
||||
space in the queue before sending a queue_step command. The host does
|
||||
this by calculating when each queue_step command completes and
|
||||
scheduling new queue_step commands accordingly.
|
|
@ -15,9 +15,9 @@ See [code overview](Code_Overview.md) for information on the structure
|
|||
and layout of the Klipper code.
|
||||
|
||||
See [protocol](Protocol.md) for information on the messaging protocol
|
||||
between host and firmware. See also
|
||||
[firmware commands](Firmware_Commands.md) for a high-level description
|
||||
of common commands implemented in the firmware.
|
||||
between host and micro-controller. See also
|
||||
[MCU commands](MCU_Commands.md) for a description of low-level
|
||||
commands implemented in the micro-controller software.
|
||||
|
||||
See [debugging](Debugging.md) for information on how to test and debug
|
||||
Klipper.
|
||||
|
|
256
docs/Protocol.md
256
docs/Protocol.md
|
@ -1,8 +1,9 @@
|
|||
The Klipper transmission protocol can be thought of, at a high level,
|
||||
as a series of command and response strings that are compressed,
|
||||
transmitted over a serial line, and then processed at the receiving
|
||||
side. An example series of commands in uncompressed human-readable
|
||||
format might look like:
|
||||
The Klipper messaging protocol is used for low-level communication
|
||||
between the Klipper host software and the Klipper micro-controller
|
||||
software. At a high level the protocol can be thought of as a series
|
||||
of command and response strings that are compressed, transmitted, and
|
||||
then processed at the receiving side. An example series of commands in
|
||||
uncompressed human-readable format might look like:
|
||||
|
||||
```
|
||||
set_digital_out pin=86 value=1
|
||||
|
@ -12,34 +13,35 @@ queue_step oid=7 interval=7458 count=10 add=331
|
|||
queue_step oid=7 interval=11717 count=4 add=1281
|
||||
```
|
||||
|
||||
See the [firmware commands](Firmware_Commands.md) document for
|
||||
information on available commands. See the [debugging](Debugging.md)
|
||||
document for information on how to translate a G-Code file into its
|
||||
corresponding human-readable firmware commands.
|
||||
See the [mcu commands](MCU_Commands.md) document for information on
|
||||
available commands. See the [debugging](Debugging.md) document for
|
||||
information on how to translate a G-Code file into its corresponding
|
||||
human-readable micro-controller commands.
|
||||
|
||||
This page provides a high-level description of the Klipper
|
||||
transmission protocol itself. It describes how messages are declared,
|
||||
encoded in binary format (the "compression" scheme), and transmitted.
|
||||
This page provides a high-level description of the Klipper messaging
|
||||
protocol itself. It describes how messages are declared, encoded in
|
||||
binary format (the "compression" scheme), and transmitted.
|
||||
|
||||
The goal of the protocol is to enable an error-free communication
|
||||
channel between the host and firmware that is low-latency,
|
||||
low-bandwidth, and low-complexity for the firmware.
|
||||
channel between the host and micro-controller that is low-latency,
|
||||
low-bandwidth, and low-complexity for the micro-controller.
|
||||
|
||||
Firmware Interface
|
||||
==================
|
||||
Micro-controller Interface
|
||||
==========================
|
||||
|
||||
The Klipper transmission protocol can be thought of as a
|
||||
[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) mechanism
|
||||
between firmware and host. The firmware declares the commands that the
|
||||
host may invoke along with the response messages that it can
|
||||
generate. The host uses that information to command the firmware to
|
||||
perform actions and to interpret the results.
|
||||
between micro-controller and host. The micro-controller software
|
||||
declares the commands that the host may invoke along with the response
|
||||
messages that it can generate. The host uses that information to
|
||||
command the micro-controller to perform actions and to interpret the
|
||||
results.
|
||||
|
||||
Declaring commands
|
||||
------------------
|
||||
|
||||
The firmware declares a "command" by using the DECL_COMMAND() macro in
|
||||
the C code. For example:
|
||||
The micro-controller software declares a "command" by using the
|
||||
DECL_COMMAND() macro in the C code. For example:
|
||||
|
||||
```
|
||||
DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c");
|
||||
|
@ -48,11 +50,11 @@ DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c");
|
|||
The above declares a command named "set_digital_out". This allows the
|
||||
host to "invoke" this command which would cause the
|
||||
command_set_digital_out() C function to be executed in the
|
||||
firmware. The above also indicates that the command takes two integer
|
||||
parameters. When the command_set_digital_out() C code is executed, it
|
||||
will be passed an array containing these two integers - the first
|
||||
corresponding to the 'pin' and the second corresponding to the
|
||||
'value'.
|
||||
micro-controller. The above also indicates that the command takes two
|
||||
integer parameters. When the command_set_digital_out() C code is
|
||||
executed, it will be passed an array containing these two integers -
|
||||
the first corresponding to the 'pin' and the second corresponding to
|
||||
the 'value'.
|
||||
|
||||
In general, the parameters are described with printf() style syntax
|
||||
(eg, "%u"). The formatting directly corresponds to the human-readable
|
||||
|
@ -63,42 +65,42 @@ documentation. In this example, the "%c" is also used as documentation
|
|||
to indicate the expected integer is 1 byte in size (the declared
|
||||
integer size does not impact the parsing or encoding).
|
||||
|
||||
At firmware compile time, the build will collect all commands declared
|
||||
with DECL_COMMAND(), determine their parameters, and arrange for them
|
||||
to be callable.
|
||||
The micro-controller build will collect all commands declared with
|
||||
DECL_COMMAND(), determine their parameters, and arrange for them to be
|
||||
callable.
|
||||
|
||||
Declaring responses
|
||||
-------------------
|
||||
|
||||
To send information from the firmware to the host a "response" is
|
||||
generated. These are both declared and transmitted using the sendf() C
|
||||
macro. For example:
|
||||
To send information from the micro-controller to the host a "response"
|
||||
is generated. These are both declared and transmitted using the
|
||||
sendf() C macro. For example:
|
||||
|
||||
```
|
||||
sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown());
|
||||
```
|
||||
|
||||
The above transmits a "status" response message that contains two
|
||||
integer parameters ("clock" and "status"). At firmware compile time
|
||||
the build automatically finds all sendf() calls and generates encoders
|
||||
for them. The first parameter of the sendf() function describes the
|
||||
integer parameters ("clock" and "status"). The micro-controller build
|
||||
automatically finds all sendf() calls and generates encoders for
|
||||
them. The first parameter of the sendf() function describes the
|
||||
response and it is in the same format as command declarations.
|
||||
|
||||
The host can arrange to register a callback function for each
|
||||
response. So, in effect, commands allow the host to invoke C functions
|
||||
in the firmware and responses allow the firmware to invoke code in the
|
||||
host.
|
||||
in the micro-controller and responses allow the micro-controller
|
||||
software to invoke code in the host.
|
||||
|
||||
The firmware should only invoke sendf() from command or task handlers,
|
||||
and it should not be invoked from interrupts or timers. The firmware
|
||||
does not need to issue a sendf() in response to a received command, it
|
||||
is not limited in the number of times sendf() may be invoked, and it
|
||||
may invoke sendf() at any time from a task handler.
|
||||
The sendf() macro should only be invoked from command or task
|
||||
handlers, and it should not be invoked from interrupts or timers. The
|
||||
code does not need to issue a sendf() in response to a received
|
||||
command, it is not limited in the number of times sendf() may be
|
||||
invoked, and it may invoke sendf() at any time from a task handler.
|
||||
|
||||
### Output responses
|
||||
|
||||
To simplify debugging, the firmware also has an output() C
|
||||
function. For example:
|
||||
To simplify debugging, there is also has an output() C function. For
|
||||
example:
|
||||
|
||||
```
|
||||
output("The value of %u is %s with size %u.", x, buf, buf_len);
|
||||
|
@ -110,15 +112,14 @@ to generate and format arbitrary messages for human consumption.
|
|||
Declaring constants
|
||||
-------------------
|
||||
|
||||
The firmware can also define constants to be exported. For example,
|
||||
the following:
|
||||
Constants can also be exported. For example, the following:
|
||||
|
||||
```
|
||||
DECL_CONSTANT(SERIAL_BAUD, 250000);
|
||||
```
|
||||
|
||||
would export a constant named "SERIAL_BAUD" with a value of 250000
|
||||
from the firmware to the host.
|
||||
from the micro-controller to the host.
|
||||
|
||||
Low-level message encoding
|
||||
==========================
|
||||
|
@ -130,9 +131,9 @@ the transmission system.
|
|||
Message Blocks
|
||||
--------------
|
||||
|
||||
All data sent from host to firmware and vice-versa are contained in
|
||||
"message blocks". A message block has a two byte header and a three
|
||||
byte trailer. The format of a message block is:
|
||||
All data sent from host to micro-controller and vice-versa are
|
||||
contained in "message blocks". A message block has a two byte header
|
||||
and a three byte trailer. The format of a message block is:
|
||||
|
||||
```
|
||||
<1 byte length><1 byte sequence><n-byte content><2 byte crc><1 byte sync>
|
||||
|
@ -160,11 +161,11 @@ present in the message block content.
|
|||
Message Block Contents
|
||||
----------------------
|
||||
|
||||
Each message block sent from host to firmware contains a series of
|
||||
zero or more message commands in its contents. Each command starts
|
||||
with a [Variable Length Quantity](#variable-length-quantities) (VLQ)
|
||||
encoded integer command-id followed by zero or more VLQ parameters for
|
||||
the given command.
|
||||
Each message block sent from host to micro-controller contains a
|
||||
series of zero or more message commands in its contents. Each command
|
||||
starts with a [Variable Length Quantity](#variable-length-quantities)
|
||||
(VLQ) encoded integer command-id followed by zero or more VLQ
|
||||
parameters for the given command.
|
||||
|
||||
As an example, the following four commands might be placed in a single
|
||||
message block:
|
||||
|
@ -183,21 +184,22 @@ and encoded into the following eight VLQ integers:
|
|||
```
|
||||
|
||||
In order to encode and parse the message contents, both the host and
|
||||
firmware must agree on the command ids and the number of parameters
|
||||
each command has. So, in the above example, both the host and firmware
|
||||
would know that "id_set_digital_out" is always followed by two
|
||||
parameters, and "id_get_config" and "id_get_status" have zero
|
||||
parameters. The host and firmware share a "data dictionary" that maps
|
||||
the command descriptions (eg, "set_digital_out pin=%u value=%c") to
|
||||
their integer command-ids. When processing the data, the parser will
|
||||
know to expect a specific number of VLQ encoded parameters following a
|
||||
given command id.
|
||||
micro-controller must agree on the command ids and the number of
|
||||
parameters each command has. So, in the above example, both the host
|
||||
and micro-controller would know that "id_set_digital_out" is always
|
||||
followed by two parameters, and "id_get_config" and "id_get_status"
|
||||
have zero parameters. The host and micro-controller share a "data
|
||||
dictionary" that maps the command descriptions (eg, "set_digital_out
|
||||
pin=%u value=%c") to their integer command-ids. When processing the
|
||||
data, the parser will know to expect a specific number of VLQ encoded
|
||||
parameters following a given command id.
|
||||
|
||||
The message contents for blocks sent from firmware to host follow the
|
||||
same format. The identifiers in these messages are "response ids", but
|
||||
they serve the same purpose and follow the same encoding rules. In
|
||||
practice, message blocks sent from the firmware to the host never
|
||||
contain more than one response in the message block contents.
|
||||
The message contents for blocks sent from micro-controller to host
|
||||
follow the same format. The identifiers in these messages are
|
||||
"response ids", but they serve the same purpose and follow the same
|
||||
encoding rules. In practice, message blocks sent from the
|
||||
micro-controller to the host never contain more than one response in
|
||||
the message block contents.
|
||||
|
||||
### Variable Length Quantities
|
||||
|
||||
|
@ -229,60 +231,62 @@ the length as a VLQ encoded integer followed by the contents itself:
|
|||
```
|
||||
|
||||
The command descriptions found in the data dictionary allow both the
|
||||
host and firmware to know which command parameters use simple VLQ
|
||||
encoding and which parameters use string encoding.
|
||||
host and micro-controller to know which command parameters use simple
|
||||
VLQ encoding and which parameters use string encoding.
|
||||
|
||||
Data Dictionary
|
||||
===============
|
||||
|
||||
In order for meaningful communications to be established between
|
||||
firmware and host, both sides must agree on a "data dictionary". This
|
||||
data dictionary contains the integer identifiers for commands and
|
||||
responses along with their descriptions.
|
||||
micro-controller and host, both sides must agree on a "data
|
||||
dictionary". This data dictionary contains the integer identifiers for
|
||||
commands and responses along with their descriptions.
|
||||
|
||||
At compile time the firmware build uses the contents of DECL_COMMAND()
|
||||
and sendf() macros to generate the data dictionary. The build
|
||||
The micro-controller build uses the contents of DECL_COMMAND() and
|
||||
sendf() macros to generate the data dictionary. The build
|
||||
automatically assigns unique identifiers to each command and
|
||||
response. This system allows both the host and firmware code to
|
||||
seamlessly use descriptive human-readable names while still using
|
||||
response. This system allows both the host and micro-controller code
|
||||
to seamlessly use descriptive human-readable names while still using
|
||||
minimal bandwidth.
|
||||
|
||||
The host queries the data dictionary when it first connects to the
|
||||
firmware. Once the host downloads the data dictionary from the
|
||||
firmware, it uses that data dictionary to encode all commands and to
|
||||
parse all responses from the firmware. The host must therefore handle
|
||||
a dynamic data dictionary. However, to keep the firmware simple, the
|
||||
firmware always uses its static (compiled in) data dictionary.
|
||||
micro-controller. Once the host downloads the data dictionary from the
|
||||
micro-controller, it uses that data dictionary to encode all commands
|
||||
and to parse all responses from the micro-controller. The host must
|
||||
therefore handle a dynamic data dictionary. However, to keep the
|
||||
micro-controller software simple, the micro-controller always uses its
|
||||
static (compiled in) data dictionary.
|
||||
|
||||
The data dictionary is queried by sending "identify" commands to the
|
||||
firmware. The firmware will respond to each identify command with an
|
||||
"identify_response" message. Since these two commands are needed prior
|
||||
to obtaining the data dictionary, their integer ids and parameter
|
||||
types are hard-coded in both the firmware and the host. The
|
||||
"identify_response" response id is 0, the "identify" command id
|
||||
is 1. Other than having hard-coded ids the identify command and its
|
||||
response are declared and transmitted the same way as other commands
|
||||
and responses. No other command or response is hard-coded.
|
||||
micro-controller. The micro-controller will respond to each identify
|
||||
command with an "identify_response" message. Since these two commands
|
||||
are needed prior to obtaining the data dictionary, their integer ids
|
||||
and parameter types are hard-coded in both the micro-controller and
|
||||
the host. The "identify_response" response id is 0, the "identify"
|
||||
command id is 1. Other than having hard-coded ids the identify command
|
||||
and its response are declared and transmitted the same way as other
|
||||
commands and responses. No other command or response is hard-coded.
|
||||
|
||||
The format of the transmitted data dictionary itself is a zlib
|
||||
compressed JSON string. The firmware compile process generates the
|
||||
string, compresses it, and stores it in the text section of the
|
||||
firmware. The data dictionary can be much larger than the maximum
|
||||
message block size - the host downloads it by sending multiple
|
||||
identify commands requesting progressive chunks of the data
|
||||
compressed JSON string. The micro-controller build process generates
|
||||
the string, compresses it, and stores it in the text section of the
|
||||
micro-controller flash. The data dictionary can be much larger than
|
||||
the maximum message block size - the host downloads it by sending
|
||||
multiple identify commands requesting progressive chunks of the data
|
||||
dictionary. Once all chunks are obtained the host will assemble the
|
||||
chunks, uncompress the data, and parse the contents.
|
||||
|
||||
In addition to information on the communication protocol, the data
|
||||
dictionary also contains firmware version, constants (as defined by
|
||||
DECL_CONSTANT), and static strings.
|
||||
dictionary also contains the software version, constants (as defined
|
||||
by DECL_CONSTANT), and static strings.
|
||||
|
||||
Static Strings
|
||||
--------------
|
||||
|
||||
To reduce bandwidth the data dictionary also contains a set of static
|
||||
strings known to the firmware. This is useful when sending messages
|
||||
from firmware to host. For example, if the firmware were to run:
|
||||
strings known to the micro-controller. This is useful when sending
|
||||
messages from micro-controller to host. For example, if the
|
||||
micro-controller were to run:
|
||||
|
||||
```
|
||||
shutdown("Unable to handle command");
|
||||
|
@ -295,22 +299,22 @@ to their associated human-readable strings.
|
|||
Message flow
|
||||
============
|
||||
|
||||
Message commands sent from host to firmware are intended to be
|
||||
error-free. The firmware will check the CRC and sequence numbers in
|
||||
each message block to ensure the commands are accurate and
|
||||
in-order. The firmware always processes message blocks in-order -
|
||||
should it receive a block out-of-order it will discard it and any
|
||||
other out-of-order blocks until it receives blocks with the correct
|
||||
sequencing.
|
||||
Message commands sent from host to micro-controller are intended to be
|
||||
error-free. The micro-controller will check the CRC and sequence
|
||||
numbers in each message block to ensure the commands are accurate and
|
||||
in-order. The micro-controller always processes message blocks
|
||||
in-order - should it receive a block out-of-order it will discard it
|
||||
and any other out-of-order blocks until it receives blocks with the
|
||||
correct sequencing.
|
||||
|
||||
The low-level host code implements an automatic retransmission system
|
||||
for lost and corrupt message blocks sent to the firmware. To
|
||||
facilitate this, the firmware transmits an "ack message block" after
|
||||
each successfully received message block. The host schedules a timeout
|
||||
after sending each block and it will retransmit should the timeout
|
||||
expire without receiving a corresponding "ack". In addition, if the
|
||||
firmware detects a corrupt or out-of-order block it may transmit a
|
||||
"nak message block" to facilitate fast retransmission.
|
||||
for lost and corrupt message blocks sent to the micro-controller. To
|
||||
facilitate this, the micro-controller transmits an "ack message block"
|
||||
after each successfully received message block. The host schedules a
|
||||
timeout after sending each block and it will retransmit should the
|
||||
timeout expire without receiving a corresponding "ack". In addition,
|
||||
if the micro-controller detects a corrupt or out-of-order block it may
|
||||
transmit a "nak message block" to facilitate fast retransmission.
|
||||
|
||||
An "ack" is a message block with empty content (ie, a 5 byte message
|
||||
block) and a sequence number greater than the last received host
|
||||
|
@ -325,15 +329,15 @@ in the event of transmission latency. The timeout, retransmit,
|
|||
windowing, and ack mechanism are inspired by similar mechanisms in
|
||||
[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol).
|
||||
|
||||
In the other direction, message blocks sent from firmware to host are
|
||||
designed to be error-free, but they do not have assured
|
||||
In the other direction, message blocks sent from micro-controller to
|
||||
host are designed to be error-free, but they do not have assured
|
||||
transmission. (Responses should not be corrupt, but they may go
|
||||
missing.) This is done to keep the implementation in the firmware
|
||||
simple. There is no automatic retransmission system for responses -
|
||||
the high-level code is expected to be capable of handling an
|
||||
occasional missing response (usually by re-requesting the content or
|
||||
setting up a recurring schedule of response transmission). The
|
||||
sequence number field in message blocks sent to the host is always one
|
||||
greater than the last received sequence number of message blocks
|
||||
received from the host. It is not used to track sequences of response
|
||||
message blocks.
|
||||
missing.) This is done to keep the implementation in the
|
||||
micro-controller simple. There is no automatic retransmission system
|
||||
for responses - the high-level code is expected to be capable of
|
||||
handling an occasional missing response (usually by re-requesting the
|
||||
content or setting up a recurring schedule of response
|
||||
transmission). The sequence number field in message blocks sent to the
|
||||
host is always one greater than the last received sequence number of
|
||||
message blocks received from the host. It is not used to track
|
||||
sequences of response message blocks.
|
||||
|
|
21
docs/Todo.md
21
docs/Todo.md
|
@ -31,12 +31,12 @@ Host user interaction
|
|||
Safety features
|
||||
===============
|
||||
|
||||
* Support loading a valid step range into the firmware after
|
||||
homing. This would provide a sanity check in the firmware that would
|
||||
reduce the risk of the host commanding a stepper motor past its
|
||||
valid step range. To maintain high efficiency in the firmware, the
|
||||
firmware would only need to check periodically (eg, every 100ms)
|
||||
that the stepper is in range.
|
||||
* Support loading a valid step range into the micro-controller
|
||||
software after homing. This would provide a sanity check in the
|
||||
micro-controller that would reduce the risk of the host commanding a
|
||||
stepper motor past its valid step range. To maintain high
|
||||
efficiency, the micro-controller would only need to check
|
||||
periodically (eg, every 100ms) that the stepper is in range.
|
||||
|
||||
* Possibly support periodically querying the endstop switches and use
|
||||
multiple step ranges depending on the switch state. This would
|
||||
|
@ -52,9 +52,10 @@ Testing features
|
|||
================
|
||||
|
||||
* Complete the host based simulator. It's possible to compile the
|
||||
firmware for a "host simulator", but that simulator doesn't do
|
||||
anything currently. It would be useful to expand the code to support
|
||||
more error checks, kinematic simulations, and improved logging.
|
||||
micro-controller for a "host simulator", but that simulator doesn't
|
||||
do anything currently. It would be useful to expand the code to
|
||||
support more error checks, kinematic simulations, and improved
|
||||
logging.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
@ -67,7 +68,7 @@ Documentation
|
|||
Hardware features
|
||||
=================
|
||||
|
||||
* Port firmware to more architectures:
|
||||
* Port to additional micro-controller architectures:
|
||||
* Beagle Bone Black PRU
|
||||
* Smoothieboard / NXP LPC1769 (ARM cortex-M3)
|
||||
* Unix based scheduling; Unix based real-time scheduling
|
||||
|
|
Loading…
Reference in New Issue