Add SRAM command injection (#17459)

This commit is contained in:
Scott Lahteine
2020-04-09 20:05:58 -05:00
committed by GitHub
parent 7af0da7f93
commit 48919c54fb
21 changed files with 120 additions and 109 deletions

View File

@ -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;

View File

@ -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();
/**