Browse Source

Merge pull request #3012 from thinkyhead/fix_command_injection

Use a serial line buffer to prevent queue corruption
Scott Lahteine 8 years ago
parent
commit
4634feaeab
6 changed files with 137 additions and 124 deletions
  1. 2
    2
      Marlin/Marlin.h
  2. 117
    105
      Marlin/Marlin_main.cpp
  3. 10
    5
      Marlin/cardreader.cpp
  4. 1
    0
      Marlin/cardreader.h
  5. 1
    1
      Marlin/stepper.cpp
  6. 6
    11
      Marlin/ultralcd.cpp

+ 2
- 2
Marlin/Marlin.h View File

227
 inline bool IsRunning() { return  Running; }
227
 inline bool IsRunning() { return  Running; }
228
 inline bool IsStopped() { return !Running; }
228
 inline bool IsStopped() { return !Running; }
229
 
229
 
230
-bool enqueuecommand(const char* cmd); //put a single ASCII command at the end of the current buffer or return false when it is full
231
-void enqueuecommands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
230
+bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); //put a single ASCII command at the end of the current buffer or return false when it is full
231
+void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
232
 
232
 
233
 void prepare_arc_move(char isclockwise);
233
 void prepare_arc_move(char isclockwise);
234
 void clamp_to_software_endstops(float target[3]);
234
 void clamp_to_software_endstops(float target[3]);

+ 117
- 105
Marlin/Marlin_main.cpp View File

276
 const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
276
 const char axis_codes[NUM_AXIS] = {'X', 'Y', 'Z', 'E'};
277
 
277
 
278
 static bool relative_mode = false;  //Determines Absolute or Relative Coordinates
278
 static bool relative_mode = false;  //Determines Absolute or Relative Coordinates
279
-static char serial_char;
280
 static int serial_count = 0;
279
 static int serial_count = 0;
281
-static boolean comment_mode = false;
282
 static char* seen_pointer; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.)
280
 static char* seen_pointer; ///< A pointer to find chars in the command string (X, Y, Z, E, etc.)
283
 const char* queued_commands_P = NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */
281
 const char* queued_commands_P = NULL; /* pointer to the current line in the active sequence of commands, or NULL when none */
284
 const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
282
 const int sensitive_pins[] = SENSITIVE_PINS; ///< Sensitive pin list for M42
409
   static bool filrunoutEnqueued = false;
407
   static bool filrunoutEnqueued = false;
410
 #endif
408
 #endif
411
 
409
 
412
-#if ENABLED(SDSUPPORT)
413
-  static bool fromsd[BUFSIZE];
414
-#endif
410
+static bool send_ok[BUFSIZE];
415
 
411
 
416
 #if HAS_SERVOS
412
 #if HAS_SERVOS
417
   Servo servo[NUM_SERVOS];
413
   Servo servo[NUM_SERVOS];
487
 #endif //!SDSUPPORT
483
 #endif //!SDSUPPORT
488
 
484
 
489
 /**
485
 /**
490
- * Inject the next command from the command queue, when possible
491
- * Return false only if no command was pending
486
+ * Inject the next "immediate" command, when possible.
487
+ * Return true if any immediate commands remain to inject.
492
  */
488
  */
493
 static bool drain_queued_commands_P() {
489
 static bool drain_queued_commands_P() {
494
-  if (!queued_commands_P) return false;
495
-
496
-  // Get the next 30 chars from the sequence of gcodes to run
497
-  char cmd[30];
498
-  strncpy_P(cmd, queued_commands_P, sizeof(cmd) - 1);
499
-  cmd[sizeof(cmd) - 1] = '\0';
500
-
501
-  // Look for the end of line, or the end of sequence
502
-  size_t i = 0;
503
-  char c;
504
-  while ((c = cmd[i]) && c != '\n') i++; // find the end of this gcode command
505
-  cmd[i] = '\0';
506
-  if (enqueuecommand(cmd)) {      // buffer was not full (else we will retry later)
507
-    if (c)
508
-      queued_commands_P += i + 1; // move to next command
509
-    else
510
-      queued_commands_P = NULL;   // will have no more commands in the sequence
490
+  if (queued_commands_P != NULL) {
491
+    // Get the next gcode to run
492
+    size_t i = 0;
493
+    char c;
494
+    while ((c = queued_commands_P[i++]) && c != '\n') { };
495
+    if (i > 1) {
496
+      char cmd[i];
497
+      strncpy_P(cmd, queued_commands_P, i - 1);
498
+      cmd[i - 1] = '\0';
499
+      if (enqueue_and_echo_command(cmd)) {      // buffer was not full (else we will retry later)
500
+        if (c)
501
+          queued_commands_P += i;     // move to next command
502
+        else
503
+          queued_commands_P = NULL;   // no more commands in the sequence
504
+      }
505
+    }
511
   }
506
   }
512
-  return true;
507
+  return (queued_commands_P != NULL); // any more left to add?
513
 }
508
 }
514
 
509
 
515
 /**
510
 /**
517
  * Aborts the current queue, if any.
512
  * Aborts the current queue, if any.
518
  * Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards
513
  * Note: drain_queued_commands_P() must be called repeatedly to drain the commands afterwards
519
  */
514
  */
520
-void enqueuecommands_P(const char* pgcode) {
515
+void enqueue_and_echo_commands_P(const char* pgcode) {
521
   queued_commands_P = pgcode;
516
   queued_commands_P = pgcode;
522
   drain_queued_commands_P(); // first command executed asap (when possible)
517
   drain_queued_commands_P(); // first command executed asap (when possible)
523
 }
518
 }
524
 
519
 
525
 /**
520
 /**
526
- * Copy a command directly into the main command buffer, from RAM.
527
- *
528
- * This is done in a non-safe way and needs a rework someday.
529
- * Returns false if it doesn't add any command
521
+ * Once a new command is in the ring buffer, call this to commit it
530
  */
522
  */
531
-bool enqueuecommand(const char* cmd) {
532
-  if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
533
-
534
-  // This is dangerous if a mixing of serial and this happens
535
-  char* command = command_queue[cmd_queue_index_w];
536
-  strcpy(command, cmd);
537
-  SERIAL_ECHO_START;
538
-  SERIAL_ECHOPGM(MSG_Enqueueing);
539
-  SERIAL_ECHO(command);
540
-  SERIAL_ECHOLNPGM("\"");
523
+inline void _commit_command(bool say_ok) {
524
+  send_ok[cmd_queue_index_w] = say_ok;
541
   cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
525
   cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
542
   commands_in_queue++;
526
   commands_in_queue++;
527
+}
528
+
529
+/**
530
+ * Copy a command directly into the main command buffer, from RAM.
531
+ * Returns true if successfully adds the command
532
+ */
533
+inline bool _enqueuecommand(const char* cmd, bool say_ok=false) {
534
+  if (*cmd == ';' || commands_in_queue >= BUFSIZE) return false;
535
+  strcpy(command_queue[cmd_queue_index_w], cmd);
536
+  _commit_command(say_ok);
543
   return true;
537
   return true;
544
 }
538
 }
545
 
539
 
540
+/**
541
+ * Enqueue with Serial Echo
542
+ */
543
+bool enqueue_and_echo_command(const char* cmd, bool say_ok/*=false*/) {
544
+  if (_enqueuecommand(cmd, say_ok)) {
545
+    SERIAL_ECHO_START;
546
+    SERIAL_ECHOPGM(MSG_Enqueueing);
547
+    SERIAL_ECHO(cmd);
548
+    SERIAL_ECHOLNPGM("\"");
549
+    return true;
550
+  }
551
+  return false;
552
+}
553
+
546
 void setup_killpin() {
554
 void setup_killpin() {
547
   #if HAS_KILL
555
   #if HAS_KILL
548
     SET_INPUT(KILL_PIN);
556
     SET_INPUT(KILL_PIN);
699
   SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES);
707
   SERIAL_ECHOPGM(MSG_PLANNER_BUFFER_BYTES);
700
   SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
708
   SERIAL_ECHOLN((int)sizeof(block_t)*BLOCK_BUFFER_SIZE);
701
 
709
 
702
-  #if ENABLED(SDSUPPORT)
703
-    for (int8_t i = 0; i < BUFSIZE; i++) fromsd[i] = false;
704
-  #endif
710
+  // Send "ok" after commands by default
711
+  for (int8_t i = 0; i < BUFSIZE; i++) send_ok[i] = true;
705
 
712
 
706
   // loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
713
   // loads data from EEPROM if available else uses defaults (and resets step acceleration rate)
707
   Config_RetrieveSettings();
714
   Config_RetrieveSettings();
760
  *  - Call LCD update
767
  *  - Call LCD update
761
  */
768
  */
762
 void loop() {
769
 void loop() {
763
-  if (commands_in_queue < BUFSIZE - 1) get_command();
770
+  if (commands_in_queue < BUFSIZE) get_command();
764
 
771
 
765
   #if ENABLED(SDSUPPORT)
772
   #if ENABLED(SDSUPPORT)
766
     card.checkautostart(false);
773
     card.checkautostart(false);
820
  */
827
  */
821
 void get_command() {
828
 void get_command() {
822
 
829
 
830
+  static char serial_line_buffer[MAX_CMD_SIZE];
831
+  static boolean serial_comment_mode = false;
832
+
823
   if (drain_queued_commands_P()) return; // priority is given to non-serial commands
833
   if (drain_queued_commands_P()) return; // priority is given to non-serial commands
824
 
834
 
825
-  #if ENABLED(NO_TIMEOUTS)
835
+  #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0
826
     static millis_t last_command_time = 0;
836
     static millis_t last_command_time = 0;
827
     millis_t ms = millis();
837
     millis_t ms = millis();
828
 
838
 
837
   //
847
   //
838
   while (commands_in_queue < BUFSIZE && MYSERIAL.available() > 0) {
848
   while (commands_in_queue < BUFSIZE && MYSERIAL.available() > 0) {
839
 
849
 
840
-    #if ENABLED(NO_TIMEOUTS)
841
-      last_command_time = ms;
842
-    #endif
843
-
844
-    serial_char = MYSERIAL.read();
850
+    char serial_char = MYSERIAL.read();
845
 
851
 
846
     //
852
     //
847
-    // If the character ends the line, or the line is full...
853
+    // If the character ends the line
848
     //
854
     //
849
-    if (serial_char == '\n' || serial_char == '\r' || serial_count >= MAX_CMD_SIZE - 1) {
855
+    if (serial_char == '\n' || serial_char == '\r') {
850
 
856
 
851
-      // end of line == end of comment
852
-      comment_mode = false;
857
+      serial_comment_mode = false; // end of line == end of comment
853
 
858
 
854
       if (!serial_count) return; // empty lines just exit
859
       if (!serial_count) return; // empty lines just exit
855
 
860
 
856
-      char* command = command_queue[cmd_queue_index_w];
857
-      command[serial_count] = 0; // terminate string
861
+      serial_line_buffer[serial_count] = 0; // terminate string
862
+      serial_count = 0; //reset buffer
858
 
863
 
859
-      // this item in the queue is not from sd
860
-      #if ENABLED(SDSUPPORT)
861
-        fromsd[cmd_queue_index_w] = false;
862
-      #endif
864
+      char* command = serial_line_buffer;
863
 
865
 
864
       while (*command == ' ') command++; // skip any leading spaces
866
       while (*command == ' ') command++; // skip any leading spaces
865
       char* npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line
867
       char* npos = (*command == 'N') ? command : NULL; // Require the N parameter to start the line
924
       // If command was e-stop process now
926
       // If command was e-stop process now
925
       if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED));
927
       if (strcmp(command, "M112") == 0) kill(PSTR(MSG_KILLED));
926
 
928
 
927
-      cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
928
-      commands_in_queue += 1;
929
+      #if defined(NO_TIMEOUTS) && NO_TIMEOUTS > 0
930
+        last_command_time = ms;
931
+      #endif
929
 
932
 
930
-      serial_count = 0; //clear buffer
933
+      // Add the command to the queue
934
+      _enqueuecommand(serial_line_buffer, true);
935
+    }
936
+    else if (serial_count >= MAX_CMD_SIZE - 1) {
937
+      // Keep fetching, but ignore normal characters beyond the max length
938
+      // The command will be injected when EOL is reached
931
     }
939
     }
932
     else if (serial_char == '\\') {  // Handle escapes
940
     else if (serial_char == '\\') {  // Handle escapes
933
-      if (MYSERIAL.available() > 0 && commands_in_queue < BUFSIZE) {
941
+      if (MYSERIAL.available() > 0) {
934
         // if we have one more character, copy it over
942
         // if we have one more character, copy it over
935
         serial_char = MYSERIAL.read();
943
         serial_char = MYSERIAL.read();
936
-        command_queue[cmd_queue_index_w][serial_count++] = serial_char;
944
+        serial_line_buffer[serial_count++] = serial_char;
937
       }
945
       }
938
       // otherwise do nothing
946
       // otherwise do nothing
939
     }
947
     }
940
-    else { // its not a newline, carriage return or escape char
941
-      if (serial_char == ';') comment_mode = true;
942
-      if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
948
+    else { // it's not a newline, carriage return or escape char
949
+      if (serial_char == ';') serial_comment_mode = true;
950
+      if (!serial_comment_mode) serial_line_buffer[serial_count++] = serial_char;
943
     }
951
     }
944
-  }
952
+
953
+  } // queue has space, serial has data
945
 
954
 
946
   #if ENABLED(SDSUPPORT)
955
   #if ENABLED(SDSUPPORT)
947
 
956
 
948
-    if (!card.sdprinting || serial_count) return;
957
+    static bool stop_buffering = false,
958
+                sd_comment_mode = false;
959
+
960
+    if (!card.sdprinting) return;
949
 
961
 
950
     // '#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible
962
     // '#' stops reading from SD to the buffer prematurely, so procedural macro calls are possible
951
-    // if it occurs, stop_buffering is triggered and the buffer is ran dry.
963
+    // if it occurs, stop_buffering is triggered and the buffer is run dry.
952
     // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
964
     // this character _can_ occur in serial com, due to checksums. however, no checksums are used in SD printing
953
 
965
 
954
-    static bool stop_buffering = false;
955
     if (commands_in_queue == 0) stop_buffering = false;
966
     if (commands_in_queue == 0) stop_buffering = false;
956
 
967
 
957
-    while (!card.eof() && commands_in_queue < BUFSIZE && !stop_buffering) {
968
+    uint16_t sd_count = 0;
969
+    bool card_eof = card.eof();
970
+    while (commands_in_queue < BUFSIZE && !card_eof && !stop_buffering) {
958
       int16_t n = card.get();
971
       int16_t n = card.get();
959
-      serial_char = (char)n;
960
-      if (serial_char == '\n' || serial_char == '\r' ||
961
-          ((serial_char == '#' || serial_char == ':') && !comment_mode) ||
962
-          serial_count >= (MAX_CMD_SIZE - 1) || n == -1
972
+      char sd_char = (char)n;
973
+      card_eof = card.eof();
974
+      if (card_eof || n == -1
975
+          || sd_char == '\n' || sd_char == '\r'
976
+          || ((sd_char == '#' || sd_char == ':') && !sd_comment_mode)
963
       ) {
977
       ) {
964
-        if (card.eof()) {
978
+        if (card_eof) {
965
           SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
979
           SERIAL_PROTOCOLLNPGM(MSG_FILE_PRINTED);
966
           print_job_stop_ms = millis();
980
           print_job_stop_ms = millis();
967
           char time[30];
981
           char time[30];
974
           card.printingHasFinished();
988
           card.printingHasFinished();
975
           card.checkautostart(true);
989
           card.checkautostart(true);
976
         }
990
         }
977
-        if (serial_char == '#') stop_buffering = true;
991
+        if (sd_char == '#') stop_buffering = true;
978
 
992
 
979
-        if (!serial_count) {
980
-          comment_mode = false; //for new command
981
-          return; //if empty line
982
-        }
983
-        command_queue[cmd_queue_index_w][serial_count] = 0; //terminate string
984
-        // if (!comment_mode) {
985
-        fromsd[cmd_queue_index_w] = true;
986
-        commands_in_queue += 1;
987
-        cmd_queue_index_w = (cmd_queue_index_w + 1) % BUFSIZE;
988
-        // }
989
-        comment_mode = false; //for new command
990
-        serial_count = 0; //clear buffer
993
+        sd_comment_mode = false; //for new command
994
+
995
+        if (!sd_count) continue; //skip empty lines
996
+
997
+        command_queue[cmd_queue_index_w][sd_count] = '\0'; //terminate string
998
+        sd_count = 0; //clear buffer
999
+
1000
+        _commit_command(false);
1001
+      }
1002
+      else if (sd_count >= MAX_CMD_SIZE - 1) {
1003
+        // Keep fetching, but ignore normal characters beyond the max length
1004
+        // The command will be injected when EOL is reached
991
       }
1005
       }
992
       else {
1006
       else {
993
-        if (serial_char == ';') comment_mode = true;
994
-        if (!comment_mode) command_queue[cmd_queue_index_w][serial_count++] = serial_char;
1007
+        if (sd_char == ';') sd_comment_mode = true;
1008
+        if (!sd_comment_mode) command_queue[cmd_queue_index_w][sd_count++] = sd_char;
995
       }
1009
       }
996
     }
1010
     }
997
 
1011
 
2703
       case MeshStart:
2717
       case MeshStart:
2704
         mbl.reset();
2718
         mbl.reset();
2705
         probe_point = 0;
2719
         probe_point = 0;
2706
-        enqueuecommands_P(PSTR("G28\nG29 S2"));
2720
+        enqueue_and_echo_commands_P(PSTR("G28\nG29 S2"));
2707
         break;
2721
         break;
2708
 
2722
 
2709
       case MeshNext:
2723
       case MeshNext:
2742
           SERIAL_PROTOCOLLNPGM("Mesh probing done.");
2756
           SERIAL_PROTOCOLLNPGM("Mesh probing done.");
2743
           probe_point = -1;
2757
           probe_point = -1;
2744
           mbl.active = 1;
2758
           mbl.active = 1;
2745
-          enqueuecommands_P(PSTR("G28"));
2759
+          enqueue_and_echo_commands_P(PSTR("G28"));
2746
         }
2760
         }
2747
         break;
2761
         break;
2748
 
2762
 
3264
           SERIAL_ECHOLNPGM(Z_PROBE_END_SCRIPT);
3278
           SERIAL_ECHOLNPGM(Z_PROBE_END_SCRIPT);
3265
         }
3279
         }
3266
       #endif
3280
       #endif
3267
-      enqueuecommands_P(PSTR(Z_PROBE_END_SCRIPT));
3281
+      enqueue_and_echo_commands_P(PSTR(Z_PROBE_END_SCRIPT));
3268
       st_synchronize();
3282
       st_synchronize();
3269
     #endif
3283
     #endif
3270
 
3284
 
3429
   }
3443
   }
3430
 
3444
 
3431
   /**
3445
   /**
3432
-   * M23: Select a file
3446
+   * M23: Open a file
3433
    */
3447
    */
3434
   inline void gcode_M23() {
3448
   inline void gcode_M23() {
3435
     card.openFile(current_command_args, true);
3449
     card.openFile(current_command_args, true);
5301
         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
5315
         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
5302
         LCD_ALERTMESSAGEPGM("Err: Too far!");
5316
         LCD_ALERTMESSAGEPGM("Err: Too far!");
5303
         #if HAS_BUZZER
5317
         #if HAS_BUZZER
5304
-          enqueuecommands_P(PSTR("M300 S40 P200"));
5318
+          enqueue_and_echo_commands_P(PSTR("M300 S40 P200"));
5305
         #endif
5319
         #endif
5306
         err = true;
5320
         err = true;
5307
         break;
5321
         break;
5315
     sync_plan_position();
5329
     sync_plan_position();
5316
     LCD_ALERTMESSAGEPGM("Offset applied.");
5330
     LCD_ALERTMESSAGEPGM("Offset applied.");
5317
     #if HAS_BUZZER
5331
     #if HAS_BUZZER
5318
-      enqueuecommands_P(PSTR("M300 S659 P200\nM300 S698 P200"));
5332
+      enqueue_and_echo_commands_P(PSTR("M300 S659 P200\nM300 S698 P200"));
5319
     #endif
5333
     #endif
5320
   }
5334
   }
5321
 }
5335
 }
6365
 
6379
 
6366
 void ok_to_send() {
6380
 void ok_to_send() {
6367
   refresh_cmd_timeout();
6381
   refresh_cmd_timeout();
6368
-  #if ENABLED(SDSUPPORT)
6369
-    if (fromsd[cmd_queue_index_r]) return;
6370
-  #endif
6382
+  if (!send_ok[cmd_queue_index_r]) return;
6371
   SERIAL_PROTOCOLPGM(MSG_OK);
6383
   SERIAL_PROTOCOLPGM(MSG_OK);
6372
   #if ENABLED(ADVANCED_OK)
6384
   #if ENABLED(ADVANCED_OK)
6373
     char* p = command_queue[cmd_queue_index_r];
6385
     char* p = command_queue[cmd_queue_index_r];
7067
       filrunout();
7079
       filrunout();
7068
   #endif
7080
   #endif
7069
 
7081
 
7070
-  if (commands_in_queue < BUFSIZE - 1) get_command();
7082
+  if (commands_in_queue < BUFSIZE) get_command();
7071
 
7083
 
7072
   millis_t ms = millis();
7084
   millis_t ms = millis();
7073
 
7085
 
7124
     const int HOME_DEBOUNCE_DELAY = 2500;
7136
     const int HOME_DEBOUNCE_DELAY = 2500;
7125
     if (!READ(HOME_PIN)) {
7137
     if (!READ(HOME_PIN)) {
7126
       if (!homeDebounceCount) {
7138
       if (!homeDebounceCount) {
7127
-        enqueuecommands_P(PSTR("G28"));
7139
+        enqueue_and_echo_commands_P(PSTR("G28"));
7128
         LCD_MESSAGEPGM(MSG_AUTO_HOME);
7140
         LCD_MESSAGEPGM(MSG_AUTO_HOME);
7129
       }
7141
       }
7130
       if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
7142
       if (homeDebounceCount < HOME_DEBOUNCE_DELAY)
7250
   void filrunout() {
7262
   void filrunout() {
7251
     if (!filrunoutEnqueued) {
7263
     if (!filrunoutEnqueued) {
7252
       filrunoutEnqueued = true;
7264
       filrunoutEnqueued = true;
7253
-      enqueuecommands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
7265
+      enqueue_and_echo_commands_P(PSTR(FILAMENT_RUNOUT_SCRIPT));
7254
       st_synchronize();
7266
       st_synchronize();
7255
     }
7267
     }
7256
   }
7268
   }

+ 10
- 5
Marlin/cardreader.cpp View File

243
   cardOK = false;
243
   cardOK = false;
244
 }
244
 }
245
 
245
 
246
+void CardReader::openAndPrintFile(const char *name) {
247
+  char cmd[4 + (FILENAME_LENGTH + 1) * MAX_DIR_DEPTH + 2]; // Room for "M23 ", names with slashes, a null, and one extra
248
+  sprintf_P(cmd, PSTR("M23 %s"), name);
249
+  for (char *c = &cmd[4]; *c; c++) *c = tolower(*c);
250
+  enqueue_and_echo_command(cmd);
251
+  enqueue_and_echo_commands_P(PSTR("M24"));
252
+}
253
+
246
 void CardReader::startFileprint() {
254
 void CardReader::startFileprint() {
247
   if (cardOK)
255
   if (cardOK)
248
     sdprinting = true;
256
     sdprinting = true;
500
   while (root.readDir(p, NULL) > 0) {
508
   while (root.readDir(p, NULL) > 0) {
501
     for (int8_t i = 0; i < (int8_t)strlen((char*)p.name); i++) p.name[i] = tolower(p.name[i]);
509
     for (int8_t i = 0; i < (int8_t)strlen((char*)p.name); i++) p.name[i] = tolower(p.name[i]);
502
     if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) {
510
     if (p.name[9] != '~' && strncmp((char*)p.name, autoname, 5) == 0) {
503
-      char cmd[4 + (FILENAME_LENGTH + 1) * (MAX_DIR_DEPTH) + 2];
504
-      sprintf_P(cmd, PSTR("M23 %s"), autoname);
505
-      enqueuecommand(cmd);
506
-      enqueuecommands_P(PSTR("M24"));
511
+      openAndPrintFile(autoname);
507
       found = true;
512
       found = true;
508
     }
513
     }
509
   }
514
   }
589
     sdprinting = false;
594
     sdprinting = false;
590
     if (SD_FINISHED_STEPPERRELEASE) {
595
     if (SD_FINISHED_STEPPERRELEASE) {
591
       //finishAndDisableSteppers();
596
       //finishAndDisableSteppers();
592
-      enqueuecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
597
+      enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
593
     }
598
     }
594
     autotempShutdown();
599
     autotempShutdown();
595
   }
600
   }

+ 1
- 0
Marlin/cardreader.h View File

23
   void removeFile(char* name);
23
   void removeFile(char* name);
24
   void closefile(bool store_location=false);
24
   void closefile(bool store_location=false);
25
   void release();
25
   void release();
26
+  void openAndPrintFile(const char *name);
26
   void startFileprint();
27
   void startFileprint();
27
   void pauseSDPrint();
28
   void pauseSDPrint();
28
   void getStatus();
29
   void getStatus();

+ 1
- 1
Marlin/stepper.cpp View File

611
     current_block = NULL;
611
     current_block = NULL;
612
     plan_discard_current_block();
612
     plan_discard_current_block();
613
     #ifdef SD_FINISHED_RELEASECOMMAND
613
     #ifdef SD_FINISHED_RELEASECOMMAND
614
-      if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueuecommands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
614
+      if ((cleaning_buffer_counter == 1) && (SD_FINISHED_STEPPERRELEASE)) enqueue_and_echo_commands_P(PSTR(SD_FINISHED_RELEASECOMMAND));
615
     #endif
615
     #endif
616
     cleaning_buffer_counter--;
616
     cleaning_buffer_counter--;
617
     OCR1A = 200;
617
     OCR1A = 200;

+ 6
- 11
Marlin/ultralcd.cpp View File

479
  */
479
  */
480
 void lcd_set_home_offsets() {
480
 void lcd_set_home_offsets() {
481
   // M428 Command
481
   // M428 Command
482
-  enqueuecommands_P(PSTR("M428"));
482
+  enqueue_and_echo_commands_P(PSTR("M428"));
483
   lcd_return_to_status();
483
   lcd_return_to_status();
484
 }
484
 }
485
 
485
 
1530
     lcd_move_y();
1530
     lcd_move_y();
1531
   }
1531
   }
1532
   static void reprapworld_keypad_move_home() {
1532
   static void reprapworld_keypad_move_home() {
1533
-    enqueuecommands_P((PSTR("G28"))); // move all axis home
1533
+    enqueue_and_echo_commands_P((PSTR("G28"))); // move all axis home
1534
   }
1534
   }
1535
 #endif // REPRAPWORLD_KEYPAD
1535
 #endif // REPRAPWORLD_KEYPAD
1536
 
1536
 
1582
  */
1582
  */
1583
 static void menu_action_back(menuFunc_t func) { lcd_goto_menu(func); }
1583
 static void menu_action_back(menuFunc_t func) { lcd_goto_menu(func); }
1584
 static void menu_action_submenu(menuFunc_t func) { lcd_save_previous_menu(); lcd_goto_menu(func); }
1584
 static void menu_action_submenu(menuFunc_t func) { lcd_save_previous_menu(); lcd_goto_menu(func); }
1585
-static void menu_action_gcode(const char* pgcode) { enqueuecommands_P(pgcode); }
1585
+static void menu_action_gcode(const char* pgcode) { enqueue_and_echo_commands_P(pgcode); }
1586
 static void menu_action_function(menuFunc_t func) { (*func)(); }
1586
 static void menu_action_function(menuFunc_t func) { (*func)(); }
1587
 
1587
 
1588
 #if ENABLED(SDSUPPORT)
1588
 #if ENABLED(SDSUPPORT)
1589
 
1589
 
1590
   static void menu_action_sdfile(const char* filename, char* longFilename) {
1590
   static void menu_action_sdfile(const char* filename, char* longFilename) {
1591
-    char cmd[30];
1592
-    char* c;
1593
-    sprintf_P(cmd, PSTR("M23 %s"), filename);
1594
-    for (c = &cmd[4]; *c; c++) *c = tolower(*c);
1595
-    enqueuecommand(cmd);
1596
-    enqueuecommands_P(PSTR("M24"));
1591
+    card.openAndPrintFile(filename);
1597
     lcd_return_to_status();
1592
     lcd_return_to_status();
1598
   }
1593
   }
1599
 
1594
 
2339
           current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
2334
           current_position[Z_AXIS] = MESH_HOME_SEARCH_Z;
2340
           line_to_current(Z_AXIS);
2335
           line_to_current(Z_AXIS);
2341
           mbl.active = 1;
2336
           mbl.active = 1;
2342
-          enqueuecommands_P(PSTR("G28"));
2337
+          enqueue_and_echo_commands_P(PSTR("G28"));
2343
           lcd_return_to_status();
2338
           lcd_return_to_status();
2344
         }
2339
         }
2345
         else {
2340
         else {
2383
   static void lcd_level_bed() {
2378
   static void lcd_level_bed() {
2384
     axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
2379
     axis_known_position[X_AXIS] = axis_known_position[Y_AXIS] = axis_known_position[Z_AXIS] = false;
2385
     mbl.reset();
2380
     mbl.reset();
2386
-    enqueuecommands_P(PSTR("G28"));
2381
+    enqueue_and_echo_commands_P(PSTR("G28"));
2387
     lcdDrawUpdate = 2;
2382
     lcdDrawUpdate = 2;
2388
     lcd_goto_menu(_lcd_level_bed_homing);
2383
     lcd_goto_menu(_lcd_level_bed_homing);
2389
   }
2384
   }

Loading…
Cancel
Save