Prusa MINI Firmware overview
GCodeQueue Class Reference

#include <queue.h>

Collaboration diagram for GCodeQueue:

Public Member Functions

 GCodeQueue ()
 

Static Public Member Functions

static void stop ()
 
static void clear ()
 
static void inject_P (PGM_P const pgcode)
 
static void enqueue_one_now (const char *cmd)
 
static void enqueue_now_P (PGM_P const cmd)
 
static bool has_commands_queued ()
 
static void advance ()
 
static void get_available_commands ()
 
static void ok_to_send ()
 
static void flush_and_request_resend ()
 
static bool enqueue_one (const char *cmd)
 

Static Public Attributes

static long last_N
 
static long stopped_N = 0
 
static uint8_t length = 0
 
static uint8_t index_r = 0
 
static char command_buffer [BUFSIZE][MAX_CMD_SIZE]
 

Detailed Description

Marlin 3D Printer Firmware Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]

Based on Sprinter and grbl. Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. queue.h - The G-code command queue, which holds commands before they go to the parser and dispatcher.

Constructor & Destructor Documentation

◆ GCodeQueue()

GCodeQueue::GCodeQueue ( )
95  {
96  // Send "ok" after commands by default
97  for (uint8_t i = 0; i < COUNT(send_ok); i++) send_ok[i] = true;
98 }

Member Function Documentation

◆ stop()

static void GCodeQueue::stop ( )
static
40 { stopped_N = last_N; }
Here is the caller graph for this function:

◆ clear()

void GCodeQueue::clear ( )
static

Clear the Marlin command queue

110  {
111  index_r = index_w = length = 0;
112 }
Here is the caller graph for this function:

◆ inject_P()

void GCodeQueue::inject_P ( PGM_P const  pgcode)
static

Enqueue one or many commands to run from program memory. Aborts the current queue, if any. Note: process_injected_command() will process them.

Enqueue one or many commands to run from program memory. Do not inject a comment or use leading spaces! Aborts the current queue, if any. Note: process_injected_command() will be called to drain any commands afterwards

206 { injected_commands_P = pgcode; }
Here is the caller graph for this function:

◆ enqueue_one_now()

void GCodeQueue::enqueue_one_now ( const char *  cmd)
static

Enqueue and return only when commands are actually enqueued

Enqueue and return only when commands are actually enqueued. Never call this from a G-code handler!

212 { while (!enqueue_one(cmd)) idle(); }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enqueue_now_P()

void GCodeQueue::enqueue_now_P ( PGM_P const  pgcode)
static

Enqueue from program memory and return only when commands are actually enqueued

Enqueue from program memory and return only when commands are actually enqueued Never call this from a G-code handler!

218  {
219  size_t i = 0;
220  PGM_P p = pgcode;
221  for (;;) {
222  char c;
223  while ((c = pgm_read_byte(&p[i])) && c != '\n') i++;
224  char cmd[i + 1];
225  memcpy_P(cmd, p, i);
226  cmd[i] = '\0';
227  enqueue_one_now(cmd);
228  if (!c) break;
229  p += i + 1;
230  }
231 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ has_commands_queued()

bool GCodeQueue::has_commands_queued ( )
static

Check whether there are any commands yet to be executed

103  {
104  return queue.length || injected_commands_P;
105 }

◆ advance()

void GCodeQueue::advance ( )
static

Get the next command in the queue, optionally log it to SD, then dispatch it

612  {
613 
614  // Process immediate commands
615  if (process_injected_command()) return;
616 
617  // Return if the G-code buffer is empty
618  if (!length) return;
619 
620  #if ENABLED(SDSUPPORT)
621 
622  if (card.flag.saving) {
623  char* command = command_buffer[index_r];
624  if (is_M29(command)) {
625  // M29 closes the file
626  card.closefile();
628 
629  #if !defined(__AVR__) || !defined(USBCON)
630  #if ENABLED(SERIAL_STATS_DROPPED_RX)
631  SERIAL_ECHOLNPAIR("Dropped bytes: ", MYSERIAL0.dropped());
632  #endif
633 
634  #if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
635  SERIAL_ECHOLNPAIR("Max RX Queue Size: ", MYSERIAL0.rxMaxEnqueued());
636  #endif
637  #endif // !defined(__AVR__) || !defined(USBCON)
638 
639  ok_to_send();
640  }
641  else {
642  // Write the string from the read buffer to SD
643  card.write_command(command);
644  if (card.flag.logging)
645  gcode.process_next_command(); // The card is saving because it's logging
646  else
647  ok_to_send();
648  }
649  }
650  else
651  gcode.process_next_command();
652 
653  #else
654 
655  gcode.process_next_command();
656 
657  #endif // SDSUPPORT
658 
659  // The queue may be reset by a command handler or by code invoked by idle() within a handler
660  if (length) {
661  --length;
662  if (++index_r >= BUFSIZE) index_r = 0;
663  }
664 
665 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_available_commands()

void GCodeQueue::get_available_commands ( )
static

Add to the circular command queue the next command from:

  • The command-injection queue (injected_commands_P)
  • The active serial input (usually USB)
  • The SD card file being actively printed
600  {
601 
602  get_serial_commands();
603 
604  #if ENABLED(SDSUPPORT)
605  get_sdcard_commands();
606  #endif
607 }
Here is the caller graph for this function:

◆ ok_to_send()

void GCodeQueue::ok_to_send ( )
static

Send an "ok" message to the host, indicating that a command was successfully processed.

If ADVANCED_OK is enabled also include: N<int> Line number of the command, if any P<int> Planner space remaining B<int> Block queue space remaining

242  {
243  #if NUM_SERIAL > 1
244  const int16_t pn = port[index_r];
245  if (pn < 0) return;
246  PORT_REDIRECT(pn);
247  #endif
248  if (!send_ok[index_r]) return;
250  #if ENABLED(ADVANCED_OK)
251  char* p = command_buffer[index_r];
252  if (*p == 'N') {
253  SERIAL_ECHO(' ');
254  SERIAL_ECHO(*p++);
255  while (NUMERIC_SIGNED(*p))
256  SERIAL_ECHO(*p++);
257  }
260  #endif
261  SERIAL_EOL();
262 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ flush_and_request_resend()

void GCodeQueue::flush_and_request_resend ( )
static

Clear the serial line and request a resend of the next expected line number.

Send a "Resend: nnn" message to the host to indicate that a command needs to be re-sent.

268  {
269  #if NUM_SERIAL > 1
270  const int16_t p = port[index_r];
271  if (p < 0) return;
272  PORT_REDIRECT(p);
273  #endif
274  SERIAL_FLUSH();
276  SERIAL_ECHOLN(last_N + 1);
277  ok_to_send();
278 }
Here is the call graph for this function:

◆ enqueue_one()

bool GCodeQueue::enqueue_one ( const char *  cmd)
static

Enqueue with Serial Echo Return true on success

Enqueue with Serial Echo Return true if the command was consumed

157  {
158 
159  //SERIAL_ECHOPGM("enqueue_one(\"");
160  //SERIAL_ECHO(cmd);
161  //SERIAL_ECHOPGM("\") \n");
162 
163  if (*cmd == 0 || *cmd == '\n' || *cmd == '\r') return true;
164 
165  if (_enqueue(cmd)) {
167  SERIAL_ECHOLNPAIR(MSG_ENQUEUEING, cmd, "\"");
168  return true;
169  }
170  return false;
171 }
Here is the caller graph for this function:

Member Data Documentation

◆ last_N

long GCodeQueue::last_N
static

GCode line number handling. Hosts may include line numbers when sending commands to Marlin, and lines will be checked for sequentiality. M110 N<int> sets the current line number.

◆ stopped_N

long GCodeQueue::stopped_N = 0
static

◆ length

uint8_t GCodeQueue::length = 0
static

GCode Command Queue A simple ring buffer of BUFSIZE command strings.

Commands are copied into this buffer by the command injectors (immediate, serial, sd card) and they are processed sequentially by the main loop. The gcode.process_next_command method parses the next command and hands off execution to individual handler functions.

◆ index_r

uint8_t GCodeQueue::index_r = 0
static

◆ command_buffer

char GCodeQueue::command_buffer
static
PORT_REDIRECT
#define PORT_REDIRECT(p)
Definition: serial.h:66
SERIAL_ECHO
#define SERIAL_ECHO(x)
Definition: serial.h:70
GCodeQueue::ok_to_send
static void ok_to_send()
Definition: queue.cpp:242
MYSERIAL0
#define MYSERIAL0
Definition: HAL.h:89
queue
GCodeQueue queue
Definition: queue.cpp:28
GCodeQueue::stopped_N
static long stopped_N
Definition: queue.h:38
g29_auto.gcode
list gcode
Definition: g29_auto.py:44
MSG_RESEND
#define MSG_RESEND
Definition: language.h:181
PGM_P
#define PGM_P
Definition: pgmspace.h:30
Planner::movesplanned
static FORCE_INLINE uint8_t movesplanned()
Definition: planner.h:543
i
uint8_t i
Definition: screen_test_graph.c:72
GCodeQueue::length
static uint8_t length
Definition: queue.h:51
SERIAL_ECHO_START
#define SERIAL_ECHO_START()
Definition: serial.h:179
SERIAL_ECHOLN
#define SERIAL_ECHOLN(x)
Definition: serial.h:72
MSG_FILE_SAVED
#define MSG_FILE_SAVED
Definition: language.h:160
pgm_read_byte
#define pgm_read_byte(addr)
Definition: pgmspace.h:95
GCodeQueue::command_buffer
static char command_buffer[BUFSIZE][MAX_CMD_SIZE]
Definition: queue.h:54
GCodeQueue::last_N
static long last_N
Definition: queue.h:38
BLOCK_BUFFER_SIZE
#define BLOCK_BUFFER_SIZE
Definition: Configuration_A3ides_2209_MINI_adv.h:1167
COUNT
#define COUNT(a)
Definition: macros.h:200
GCodeQueue::index_r
static uint8_t index_r
Definition: queue.h:51
SERIAL_ECHOPGM
#define SERIAL_ECHOPGM(S)
Definition: serial.h:173
is_M29
FORCE_INLINE bool is_M29(const char *const cmd)
Definition: queue.cpp:309
SERIAL_ECHOLNPAIR
#define SERIAL_ECHOLNPAIR(V...)
Definition: serial.h:144
GCodeQueue::enqueue_one
static bool enqueue_one(const char *cmd)
Definition: queue.cpp:157
uint8_t
const uint8_t[]
Definition: 404_html.c:3
MSG_OK
#define MSG_OK
Definition: language.h:157
GCodeQueue::enqueue_one_now
static void enqueue_one_now(const char *cmd)
Definition: queue.cpp:212
NUMERIC_SIGNED
#define NUMERIC_SIGNED(a)
Definition: macros.h:198
SERIAL_FLUSH
#define SERIAL_FLUSH()
Definition: serial.h:76
MSG_ENQUEUEING
#define MSG_ENQUEUEING
Definition: language.h:147
send_ok
bool send_ok[BUFSIZE]
Definition: queue.cpp:86
SERIAL_EOL
#define SERIAL_EOL()
Definition: serial.h:181
BUFSIZE
#define BUFSIZE
Definition: Configuration_A3ides_2209_MINI_adv.h:1174
memcpy_P
#define memcpy_P(dest, src, num)
Definition: pgmspace.h:49
SERIAL_ECHOLNPGM
#define SERIAL_ECHOLNPGM(S)
Definition: serial.h:174
idle
void idle()
Definition: Marlin.cpp:629
injected_commands_P
static PGM_P injected_commands_P
Definition: queue.cpp:93
planner
Planner planner
Definition: planner.cpp:111