Add SRAM command injection (#17459)
This commit is contained in:
@ -86,11 +86,15 @@ static int serial_count[NUM_SERIAL] = { 0 };
|
||||
bool send_ok[BUFSIZE];
|
||||
|
||||
/**
|
||||
* Next Injected Command pointer. nullptr if no commands are being injected.
|
||||
* Used by Marlin internally to ensure that commands initiated from within
|
||||
* are enqueued ahead of any pending serial or sd card commands.
|
||||
* Next Injected PROGMEM Command pointer. (nullptr == empty)
|
||||
* Internal commands are enqueued ahead of serial / SD commands.
|
||||
*/
|
||||
static PGM_P injected_commands_P = nullptr;
|
||||
PGM_P GCodeQueue::injected_commands_P; // = nullptr
|
||||
|
||||
/**
|
||||
* Injected SRAM Commands
|
||||
*/
|
||||
char GCodeQueue::injected_commands[64]; // = { 0 }
|
||||
|
||||
GCodeQueue::GCodeQueue() {
|
||||
// Send "ok" after commands by default
|
||||
@ -101,7 +105,7 @@ GCodeQueue::GCodeQueue() {
|
||||
* Check whether there are any commands yet to be executed
|
||||
*/
|
||||
bool GCodeQueue::has_commands_queued() {
|
||||
return queue.length || injected_commands_P;
|
||||
return queue.length || injected_commands_P || injected_commands[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,11 +176,10 @@ bool GCodeQueue::enqueue_one(const char* cmd) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the next "immediate" command.
|
||||
* Return 'true' if any commands were processed,
|
||||
* or remain to process.
|
||||
* Process the next "immediate" command from PROGMEM.
|
||||
* Return 'true' if any commands were processed.
|
||||
*/
|
||||
bool GCodeQueue::process_injected_command() {
|
||||
bool GCodeQueue::process_injected_command_P() {
|
||||
if (injected_commands_P == nullptr) return false;
|
||||
|
||||
char c;
|
||||
@ -198,12 +201,27 @@ bool GCodeQueue::process_injected_command() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Process the next "immediate" command from SRAM.
|
||||
* Return 'true' if any commands were processed.
|
||||
*/
|
||||
void GCodeQueue::inject_P(PGM_P const pgcode) { injected_commands_P = pgcode; }
|
||||
bool GCodeQueue::process_injected_command() {
|
||||
if (injected_commands[0] == '\0') return false;
|
||||
|
||||
char c;
|
||||
size_t i = 0;
|
||||
while ((c = injected_commands[i]) && c != '\n') i++;
|
||||
|
||||
// Execute a non-blank command
|
||||
if (i) {
|
||||
injected_commands[i] = '\0';
|
||||
parser.parse(injected_commands);
|
||||
gcode.process_parsed_command();
|
||||
}
|
||||
|
||||
// Copy the next command into place
|
||||
strcpy(injected_commands, &injected_commands[i + (c != '\0')]);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue and return only when commands are actually enqueued.
|
||||
@ -575,7 +593,7 @@ void GCodeQueue::get_serial_commands() {
|
||||
|
||||
/**
|
||||
* Add to the circular command queue the next command from:
|
||||
* - The command-injection queue (injected_commands_P)
|
||||
* - The command-injection queues (injected_commands_P, injected_commands)
|
||||
* - The active serial input (usually USB)
|
||||
* - The SD card file being actively printed
|
||||
*/
|
||||
@ -594,7 +612,7 @@ void GCodeQueue::get_available_commands() {
|
||||
void GCodeQueue::advance() {
|
||||
|
||||
// Process immediate commands
|
||||
if (process_injected_command()) return;
|
||||
if (process_injected_command_P() || process_injected_command()) return;
|
||||
|
||||
// Return if the G-code buffer is empty
|
||||
if (!length) return;
|
||||
|
@ -66,11 +66,30 @@ public:
|
||||
static void clear();
|
||||
|
||||
/**
|
||||
* Enqueue one or many commands to run from program memory.
|
||||
* Aborts the current queue, if any.
|
||||
* Note: process_injected_command() will process them.
|
||||
* Next Injected Command (PROGMEM) pointer. (nullptr == empty)
|
||||
* Internal commands are enqueued ahead of serial / SD commands.
|
||||
*/
|
||||
static void inject_P(PGM_P const pgcode);
|
||||
static PGM_P injected_commands_P;
|
||||
|
||||
/**
|
||||
* Injected Commands (SRAM)
|
||||
*/
|
||||
static char injected_commands[64];
|
||||
|
||||
/**
|
||||
* Enqueue command(s) to run from PROGMEM. Drained by process_injected_command_P().
|
||||
* Don't inject comments or use leading spaces!
|
||||
* Aborts the current PROGMEM queue so only use for one or two commands.
|
||||
*/
|
||||
static inline void inject_P(PGM_P const pgcode) { injected_commands_P = pgcode; }
|
||||
|
||||
/**
|
||||
* Enqueue command(s) to run from SRAM. Drained by process_injected_command().
|
||||
* Aborts the current SRAM queue so only use for one or two commands.
|
||||
*/
|
||||
static inline void inject(char * const gcode) {
|
||||
strncpy(injected_commands, gcode, sizeof(injected_commands) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue and return only when commands are actually enqueued
|
||||
@ -145,7 +164,10 @@ private:
|
||||
#endif
|
||||
);
|
||||
|
||||
// Process the next "immediate" command
|
||||
// Process the next "immediate" command (PROGMEM)
|
||||
static bool process_injected_command_P();
|
||||
|
||||
// Process the next "immediate" command (SRAM)
|
||||
static bool process_injected_command();
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user