An Outsider's Perspective On GRBL
An Outsider's Perspective On GRBL
This document primarily follows one line of serial text down the rabbit hole from start to
finish.
We'll primarily focus on the homing command, but will outline the primary path for other
commands, too.
//Each character in the serial stream picked off the serial receive buffer via interrupt:
serial.c: ISR(SERIAL_RX)
-Picks off reset, realtime, ?!~, setting system_set_exec_state_flag(EXEX_xxxxx).
-Other characters written to serial_rx_buffer[].
serial.c: serial_read()
-returns first byte in the serial_rx_buffer. Called by main program.
main.c: main()
-creates: sys_probe_state/sys_rt_exec______ (all uint8_t).
-creates: sys_position[] //realtime machine position in steps
-creates: sys_probe_position[] //last probe position in steps
-initializes grbl (_init)
-calls protocol_main_loop() //main grbl loop
protocol.c: protocol_main_loop()
-aborts back to main() if sys.abort, else:
-formats character from serial_read() into line[], until \n or \r)
-formats line[] into all CAPS, no comments, spaces, etc
-Adds a '0' to the end of line. Grbl uses this later to determine EOL
-processes line and reports_status_message():
-'0' is empty line, reports 'OK'
-'$' is system command, calls system_execute_line()
-note: ISR(SERIAL_RX) has already picked off real-time (non-g-code)
commands (see protocol_execute_realtime)
-everything else is g-code, sent to gc_execute_line() //in gcode.c. This
function is a switch statement that sequentially parses each g-code parameter
(Letter+Number). Once the line is fully consumed, it is executed in a well-documented
order (see gcode.c).
motion_control.c: mc_homing_cycle(HOMING_CYCLE_ALL)
-limits_disable()
-calls limits_go_home
-protocol_execute_realtime()
-gc_sync_position()
-plan_sync_position()
-limits_init()
...........................................................................................
EEPROM-specific locations:
settings.h:
-EEPROM_ADDR_GLOBAL - physical memory addresses
settings.c:
settings_restore() - restores OEM EEPROM values
settings_store_startup_line() - writes line to EEPROM (we're using N#2 for cal
data)
report_build_info() - $I string
settings_store_global_setting() - stores $number=value
Calibration data:
settings_write_calibration_data
settings_read_calibration_data
...........................................................................................
STRUCTS:
settings.h
-global persistent settings (stored from byte EEPROM_ADDR_GLOBAL onwards)
settings. is type: settings_t (all elements are single numbers, except as noted)
settings.steps_per_mm[]
settings.max_rate[]
settings.acceleration[]
settings.max_travel
settings.pulse_microseconds
settings.step_invert_mask
settings.dir_invert_mask
settings.stepper_idle_lock_time
settings.status_report_mask
settings.junction_deviation
settings.arc_tolerance
settings.rpm_max
settings.rpm_min
settings.flags //contains default boolean settings**
settings.homing_dir_mask
settings.homing_feed_rate
settings.homing_seek_rate
settings.homing_debounce_delay
settings.homing_pulloff
**report_inches, laser_mode, invert_st, hard/soft limits, invert probe/limits
system.h:
-defines realtime command flags (bit masks)(EXEC_ STATE_ etc)
-sys. is type: system_t (all elements are single numbers, mostly uint8)
sys.state //tracks grbl state
sys.abort //forces exit back to main loop for reset
sys.suspend //manages holds/cancels
sys.soft_limit //tracks soft limit errors for state machine
sys.step_control //governs step segment generator based on
state
sys.probe_succeeded //tracks if last probe succeeded
sys.probe_interrupt_occurred //logs that a probe interrupt occurred
sys.homing_axis_lock //locks axes when limits trip
sys.f_override //feedrate override %
sys.r_override //rapid override %
sys.spindle_speed_ovr //spindle speed %
sys.spindle_stop_ovr //tracks spindle stop override state
sys.report_ovr_counter //tracks when to add override data to reports
sys.report_wco_counter //tracks when to add WCO offset to reports
sys.spindle_speed //spindle rpm
gcode.h:
gc_state. is type: parser_state_t (all elements are single numbers, except as noted)
gc_state.modal is type: gc_modal_t (see next lines)
gc_state.modal.motion G0/G1/G2/G38.2/G80
gc_state.modal.feed_rate G93/G94
gc_state.modal.units G20/G21
gc_state.modal.distance G90/G91
gc_state.modal.plane_select G17/G18/G19
gc_state.modal.tool_length G43.1/G49
gc_state.modal.coord_select G54/G55/G56/G57/G58/G59
gc_state.modal.program_flow M0/M1/M2/M30
gc_state.modal.spindle M3/M4/M5
gc_state.modal.override M56
gc_state.spindle_speed rpm
gc_state.feed_rate mm/min
gc_state.tool tool# (not used)
gc_state.line_number last line number sent
gc_state.position[] where interpreter thinks tool is
gc_state.coord_system[] current WCS offset from absolute
position
gc_state.coord_offset[] G92 offset
gc_state.tool_length_offset tool length (if enabled)
planner.h:
block.
cur_block. //the block executing at this moment
pl_block.
next.
current. are all type plan_block_t (all elements are single numbers, except as noted)
current.steps[]
current.step_event_count
current.direction_bits
current.condition
current.line_number
current.entry_speed_sqr
current.acceleration
current.millimeters
current.max_junction_speed_sqr
current.rapid_rate
current.programmed_rate
current.spindle_speed
pl_data. //planner data for motion blocks. feedrate, rpm, line number, condition
plan_data. are type plan_line_data_t (all elements are single numbers)
//used to pass new motions to the planner.
plan_data.feed_rate desired feed rate for G1; ignored if G0
plan_data.spindle_speed desired spindle rpm through line motion
plan_data.condition bitflag indicates planner conditions (PL_COND_)
plan_data.line_number desired line number to report when executing
...........................................................................................
//Watchdog code was removed entirely (previously used for limit switch debounce)
watchdog is available as a timer
#ifdef ENABLE_SOFTWARE_DEBOUNCE
MCUSR &= ~(1<<WDRF);
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDP0); // Set time-out at ~32msec.
#endif