Try to monitor planner buffer underruns in the auto_report_buffer_statistics loop as modifying the stepper ISR loop seems like a bad idea
This commit is contained in:
parent
e874558381
commit
f560ab9ab7
3 changed files with 60 additions and 10 deletions
|
|
@ -91,10 +91,14 @@ bool send_ok[BUFSIZE];
|
||||||
#if ENABLED(BUFFER_MONITORING)
|
#if ENABLED(BUFFER_MONITORING)
|
||||||
uint32_t GCodeQueue::command_buffer_underruns = 0;
|
uint32_t GCodeQueue::command_buffer_underruns = 0;
|
||||||
bool GCodeQueue::command_buffer_empty = false;
|
bool GCodeQueue::command_buffer_empty = false;
|
||||||
|
|
||||||
millis_t GCodeQueue::max_command_buffer_empty_duration = 0;
|
millis_t GCodeQueue::max_command_buffer_empty_duration = 0;
|
||||||
millis_t GCodeQueue::command_buffer_empty_at = 0;
|
millis_t GCodeQueue::command_buffer_empty_at = 0;
|
||||||
|
|
||||||
|
uint32_t GCodeQueue::planner_buffer_underruns = 0;
|
||||||
|
bool GCodeQueue::planner_buffer_empty = false;
|
||||||
|
millis_t GCodeQueue::max_planner_buffer_empty_duration = 0;
|
||||||
|
millis_t GCodeQueue::planner_buffer_empty_at = 0;
|
||||||
|
|
||||||
uint8_t GCodeQueue::auto_buffer_report_interval;
|
uint8_t GCodeQueue::auto_buffer_report_interval;
|
||||||
millis_t GCodeQueue::next_buffer_report_ms;
|
millis_t GCodeQueue::next_buffer_report_ms;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -639,12 +643,14 @@ void GCodeQueue::advance() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(BUFFER_MONITORING)
|
#if ENABLED(BUFFER_MONITORING)
|
||||||
static millis_t command_buffer_empty_duration;
|
if (command_buffer_empty) {
|
||||||
command_buffer_empty_duration = millis() - command_buffer_empty_at;
|
static millis_t command_buffer_empty_duration;
|
||||||
if (command_buffer_empty_duration > max_command_buffer_empty_duration) {
|
command_buffer_empty_duration = millis() - command_buffer_empty_at;
|
||||||
max_command_buffer_empty_duration = command_buffer_empty_duration;
|
if (command_buffer_empty_duration > max_command_buffer_empty_duration) {
|
||||||
|
max_command_buffer_empty_duration = command_buffer_empty_duration;
|
||||||
|
}
|
||||||
|
command_buffer_empty = false;
|
||||||
}
|
}
|
||||||
command_buffer_empty = false;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -697,15 +703,40 @@ void GCodeQueue::report_buffer_statistics() {
|
||||||
SERIAL_ECHO("M576");
|
SERIAL_ECHO("M576");
|
||||||
SERIAL_ECHOLNPAIR(SP_P_STR, int(planner.moves_free()),
|
SERIAL_ECHOLNPAIR(SP_P_STR, int(planner.moves_free()),
|
||||||
SP_B_STR, int(BUFSIZE - length),
|
SP_B_STR, int(BUFSIZE - length),
|
||||||
|
" PU", queue.planner_buffer_underruns,
|
||||||
|
" PD", queue.max_planner_buffer_empty_duration,
|
||||||
" BU", queue.command_buffer_underruns,
|
" BU", queue.command_buffer_underruns,
|
||||||
" BD", queue.max_command_buffer_empty_duration,
|
" BD", queue.max_command_buffer_empty_duration,
|
||||||
);
|
);
|
||||||
|
|
||||||
command_buffer_underruns = 0;
|
command_buffer_underruns = 0;
|
||||||
max_command_buffer_empty_duration = 0;
|
max_command_buffer_empty_duration = 0;
|
||||||
|
|
||||||
|
planner_buffer_underruns = 0;
|
||||||
|
max_planner_buffer_empty_duration = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCodeQueue::auto_report_buffer_statistics() {
|
void GCodeQueue::auto_report_buffer_statistics() {
|
||||||
|
// Bit of a hack to try to catch planner buffer underruns without having logic
|
||||||
|
// running inside Stepper::block_phase_isr
|
||||||
|
if (planner.movesplanned() == 0) {
|
||||||
|
if (!planner_buffer_empty) { // if the planner buffer wasn't empty, but now it is
|
||||||
|
planner_buffer_empty = true;
|
||||||
|
planner_buffer_underruns++;
|
||||||
|
planner_buffer_empty_at = millis();
|
||||||
|
}
|
||||||
|
} else if (planner_buffer_empty) { // if the planner buffer was empty, but now it ain't
|
||||||
|
static millis_t planner_buffer_empty_duration;
|
||||||
|
planner_buffer_empty_duration = millis() - planner_buffer_empty_at;
|
||||||
|
|
||||||
|
// if it's longer than the currently tracked max duration, replace it
|
||||||
|
if (planner_buffer_empty_duration > max_planner_buffer_empty_duration) {
|
||||||
|
max_planner_buffer_empty_duration = planner_buffer_empty_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
planner_buffer_empty = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (queue.auto_buffer_report_interval && ELAPSED(millis(), queue.next_buffer_report_ms)) {
|
if (queue.auto_buffer_report_interval && ELAPSED(millis(), queue.next_buffer_report_ms)) {
|
||||||
queue.next_buffer_report_ms = millis() + 1000UL * queue.auto_buffer_report_interval;
|
queue.next_buffer_report_ms = millis() + 1000UL * queue.auto_buffer_report_interval;
|
||||||
PORT_REDIRECT(SERIAL_BOTH);
|
PORT_REDIRECT(SERIAL_BOTH);
|
||||||
|
|
|
||||||
|
|
@ -156,13 +156,21 @@ public:
|
||||||
static millis_t max_command_buffer_empty_duration;
|
static millis_t max_command_buffer_empty_duration;
|
||||||
static millis_t command_buffer_empty_at;
|
static millis_t command_buffer_empty_at;
|
||||||
|
|
||||||
|
static uint32_t planner_buffer_underruns;
|
||||||
|
static bool planner_buffer_empty;
|
||||||
|
static millis_t max_planner_buffer_empty_duration;
|
||||||
|
static millis_t planner_buffer_empty_at;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Report buffer statistics to the host to be able to detect buffer underruns
|
* Report buffer statistics to the host to be able to detect buffer underruns
|
||||||
*
|
*
|
||||||
* Returns "M576 " followed by:
|
* Returns "M576 " followed by:
|
||||||
* P<uint> Planner space remaining
|
* P<uint> Planner space remaining
|
||||||
* B<uint> Command buffer space remaining
|
* B<uint> Command buffer space remaining
|
||||||
* U<uint> Number of command buffer underruns since last report
|
* PU<uint> Number of planner buffer underruns since last report
|
||||||
|
* PD<uint> Max time in ms the planner buffer was empty since last report
|
||||||
|
* BU<uint> Number of command buffer underruns since last report
|
||||||
|
* BD<uint> Max time in ms the command buffer was empty since last report
|
||||||
*/
|
*/
|
||||||
static void report_buffer_statistics();
|
static void report_buffer_statistics();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,18 @@
|
||||||
#include "../queue.h"
|
#include "../queue.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* M576: Return buffer stats, and optionally set auto-report interval. M576 [S<seconds>]
|
* M576: Return buffer stats, and optionally set auto-report interval.
|
||||||
|
* Usage: M576 [S<seconds>]
|
||||||
|
*
|
||||||
|
* When called, printer emits the following output:
|
||||||
|
* "M576 P<nn> B<nn> PU<nn> PD<nn> BU<nn> BD<nn>"
|
||||||
|
* Where:
|
||||||
|
* P: Planner buffers available
|
||||||
|
* B: Command buffers available
|
||||||
|
* PU: Planner buffer underruns since last report
|
||||||
|
* PD: Maximum time in ms planner buffer was empty since last report
|
||||||
|
* BU: Command buffer underruns since last report
|
||||||
|
* BD: Maximum time in ms command buffer was empty since last report
|
||||||
*/
|
*/
|
||||||
void GcodeSuite::M576() {
|
void GcodeSuite::M576() {
|
||||||
if (parser.seenval('S')) {
|
if (parser.seenval('S')) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue