Work on debug and diagnostics

This commit is contained in:
Alden Hart
2017-02-20 06:13:08 -05:00
parent d67dc6540e
commit 5810eda239
12 changed files with 144 additions and 132 deletions
Executable → Regular
+11 -8
View File
@@ -52,14 +52,17 @@ NEEDS_PRINTF_FLOAT=1
# Now invoke the Motate compile system
include $(MOTATE_PATH)/Motate.mk
ifeq ($(DEBUG),1)
DEVICE_DEFINES += DEBUG=1
endif
ifeq ($(DEBUG),2)
DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1
endif
ifeq ($(DEBUG),3)
DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1 DEBUG_SEMIHOSTING=1
ifeq ($(DEBUG),0)
DEVICE_DEFINES += DEBUG=0 IN_DEBUGGER=0
endif
ifeq ($(DEBUG),1)
DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=0
endif
ifeq ($(DEBUG),2)
DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1
endif
#ifeq ($(DEBUG),3)
# DEVICE_DEFINES += DEBUG=1 IN_DEBUGGER=1 DEBUG_SEMIHOSTING=1
#endif
# *** EOF ***
+1 -1
View File
@@ -230,7 +230,7 @@ stat_t cm_shutdown(const stat_t status, const char *msg)
stat_t cm_panic(const stat_t status, const char *msg)
{
_debug_trap(msg);
__debug_trap(msg);
if (cm->machine_state == MACHINE_PANIC) { // only do this once
return (STAT_OK);
+1 -1
View File
@@ -1177,7 +1177,7 @@
<OutputPath>bin\Makeblock-v9\</OutputPath>
<UsesExternalMakeFile>True</UsesExternalMakeFile>
<OutputDirectory />
<BuildTarget>CONFIG=Makeblock COLOR=0 VERBOSE=1</BuildTarget>
<BuildTarget>CONFIG=Makeblock COLOR=0 VERBOSE=1 DEBUG=2</BuildTarget>
<CleanTarget>clean CONFIG=Makeblock</CleanTarget>
<ExternalMakeFilePath>Makefile</ExternalMakeFilePath>
<ToolchainSettings>
+6 -4
View File
@@ -50,17 +50,19 @@
stat_t status_code; // allocate a variable for the ritorno macro
/************* System Globals For Diagnostics ****************/
/************* System Globals For Debugging and Diagnostics ****************/
// See also: util.h for debugging and diagnostics
// Using motate pins for profiling
// see https://github.com/synthetos/g2/wiki/Using-Pin-Changes-for-Timing-(and-light-debugging)
// Usage: https://github.com/synthetos/g2/wiki/Using-Pin-Changes-for-Timing-(and-light-debugging)
using namespace Motate;
OutputPin<kDebug1_PinNumber> debug_pin1;
OutputPin<kDebug2_PinNumber> debug_pin2;
OutputPin<kDebug3_PinNumber> debug_pin3;
//OutputPin<kDebug4_PinNumber> debug_pin4;
OutputPin<kDebug4_PinNumber> debug_pin4;
// or these to disable the pin
//OutputPin<-1> debug_pin1;
//OutputPin<-1> debug_pin2;
//OutputPin<-1> debug_pin3;
@@ -72,7 +74,7 @@ using namespace Motate;
extern OutputPin<kDebug1_PinNumber> debug_pin1;
extern OutputPin<kDebug2_PinNumber> debug_pin2;
extern OutputPin<kDebug3_PinNumber> debug_pin3;
//extern OutputPin<kDebug4_PinNumber> debug_pin4;
extern OutputPin<kDebug4_PinNumber> debug_pin4;
//extern OutputPin<-1> debug_pin1;
//extern OutputPin<-1> debug_pin2;
+10 -18
View File
@@ -166,14 +166,11 @@ static stat_t _plan_aline(mpBuf_t *bf, float entry_velocity)
mpBlockRuntimeBuf_t* block = mr->p; // set a local planning block so it doesn't change on you
mp_calculate_ramps(block, bf, entry_velocity); // (which it will if you don't do this)
#ifdef IN_DEBUGGER // DIAGNOSTIC
if (block->exit_velocity > block->cruise_velocity) {
__asm__("BKPT"); // exit > cruise after calculate_block
}
if (block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001) {
__asm__("BKPT"); // zero or negative length block
}
#endif
__debug_trap_if_true((block->exit_velocity > block->cruise_velocity),
"_plan_line() exit velocity > cruise velocity after calculate_ramps()");
__debug_trap_if_true((block->head_length < 0.00001 && block->body_length < 0.00001 && block->tail_length < 0.00001),
"_plan_line() zero or negative length block after calculate_ramps()");
bf->buffer_state = MP_BUFFER_PLANNED; //...here
bf->plannable = false;
@@ -259,10 +256,7 @@ stat_t mp_exec_move()
// first-time operations
if (bf->buffer_state != MP_BUFFER_RUNNING) {
if ((bf->buffer_state < MP_BUFFER_PREPPED) && (cm->motion_state == MOTION_RUN)) {
#ifdef IN_DEBUGGER
__asm__("BKPT"); // mp_exec_move() buffer is not prepped
#endif
// IMPORTANT: We can't rpt_exception from here!
__debug_trap("mp_exec_move() buffer is not prepped"); // IMPORTANT: can't rpt_exception from here!
st_prep_null();
return (STAT_NOOP);
}
@@ -274,9 +268,7 @@ stat_t mp_exec_move()
if (bf->buffer_state == MP_BUFFER_PREPPED) {
if (cm->motion_state == MOTION_RUN) {
#ifdef IN_DEBUGGER
// __asm__("BKPT"); // we are running but don't have a block planned
#endif
__debug_trap("mp_exec_move() don't have a block planned"); // IMPORTANT: can't rpt_exception from here!
}
// We need to have it planned. We don't want to do this here, as it
// might already be happening in a lower interrupt.
@@ -885,7 +877,7 @@ static stat_t _exec_aline_head(mpBuf_t *bf)
_init_forward_diffs(mr->entry_velocity, mr->r->cruise_velocity); // <-- sets inital segment_velocity
}
if (mr->segment_time < MIN_SEGMENT_TIME) {
_debug_trap("mr->segment_time < MIN_SEGMENT_TIME");
__debug_trap("mr->segment_time < MIN_SEGMENT_TIME (head)");
return(STAT_OK); // exit without advancing position, say we're done
}
mr->section = SECTION_HEAD;
@@ -930,7 +922,7 @@ static stat_t _exec_aline_body(mpBuf_t *bf)
mr->segment_velocity = mr->r->cruise_velocity;
mr->segment_count = (uint32_t)mr->segments;
if (mr->segment_time < MIN_SEGMENT_TIME) {
_debug_trap("mr->segment_time < MIN_SEGMENT_TIME");
__debug_trap("mr->segment_time < MIN_SEGMENT_TIME (body)");
return(STAT_OK); // exit without advancing position, say we're done
}
@@ -971,7 +963,7 @@ static stat_t _exec_aline_tail(mpBuf_t *bf)
_init_forward_diffs(mr->r->cruise_velocity, mr->r->exit_velocity); // <-- sets inital segment_velocity
}
if (mr->segment_time < MIN_SEGMENT_TIME) {
_debug_trap("mr->segment_time < MIN_SEGMENT_TIME");
__debug_trap("mr->segment_time < MIN_SEGMENT_TIME (tail)");
return(STAT_OK); // exit without advancing position, say we're done
// return(STAT_MINIMUM_TIME_MOVE); // exit without advancing position
}
+3 -1
View File
@@ -36,7 +36,6 @@
#include "util.h"
#include "spindle.h"
#include "settings.h"
#include "xio.h"
// using Motate::Timeout;
@@ -55,7 +54,9 @@ static void _calculate_jerk(mpBuf_t* bf);
static void _calculate_vmaxes(mpBuf_t* bf, const float axis_length[], const float axis_square[]);
static void _calculate_junction_vmax(mpBuf_t* bf);
#ifdef __PLANNER_DIAGNOSTICS
#pragma GCC push_options
#pragma GCC optimize("O0") // this pragma is required to force the planner to actually set these unused values
static void _set_bf_diagnostics(mpBuf_t* bf) {
UPDATE_BF_DIAGNOSTICS(bf);
@@ -65,6 +66,7 @@ static void _set_bf_diagnostics(mpBuf_t* bf) {
static void _set_bf_diagnostics(mpBuf_t* bf) {}
#endif
/* Runtime-specific setters and getters
*
* mp_zero_segment_velocity() - correct velocity in last segment for reporting purposes
+26 -41
View File
@@ -31,11 +31,11 @@
#include "planner.h"
#include "report.h"
#include "util.h"
#include "xio.h" // only need for DIAGNOSTICS
//#include "xio.h" // only need for_ramp_exit_logger
// DIAGNOSTICS
stat_t _exit_logger(mpBuf_t* bf, const char *msg)
stat_t _ramp_exit_logger(mpBuf_t* bf, const char *msg)
{
#ifdef __PLANNER_DIAGNOSTICS
if (mp_runtime_is_idle()) { // normally the runtime keeps this value fresh
@@ -44,32 +44,23 @@ stat_t _exit_logger(mpBuf_t* bf, const char *msg)
}
#endif
#ifdef IN_DEBUGGER
// insert logger functions here
//static char logbuf[128];
//static void _logger(const char *msg, const mpBuf_t *bf) // LOG_RETURN with full state dump
//{
// sprintf(logbuf, "[%2d] %s (%d) mt:%5.2f, L:%1.3f [%1.3f, %1.3f, %1.3f] V:[%1.2f, %1.2f, %1.2f]\n",
// bf->buffer_number, msg, bf->hint, (bf->block_time * 60000),
// bf->length, bf->head_length, bf->body_length, bf->tail_length,
// bf->pv->exit_velocity, bf->cruise_velocity, bf->exit_velocity);
// xio_writeline(logbuf);
//}
#endif
/* insert logger functions here if needed:
// LOG_RETURN with full state dump
#if IN_DEBUGGER == 1
static char logbuf[128];
sprintf(logbuf, "[%2d] %s (%d) mt:%5.2f, L:%1.3f [%1.3f, %1.3f, %1.3f] V:[%1.2f, %1.2f, %1.2f]\n",
bf->buffer_number, msg, bf->hint, (bf->block_time * 60000),
bf->length, bf->head_length, bf->body_length, bf->tail_length,
bf->pv->exit_velocity, bf->cruise_velocity, bf->exit_velocity);
xio_writeline(logbuf);
#endif
*/
return (STAT_OK);
}
#ifndef IN_DEBUGGER
#define TRAP_ZERO(t,m)
#else
#define TRAP_ZERO(t, m) \
if (fp_ZERO(t)) { \
rpt_exception(STAT_MINIMUM_LENGTH_MOVE, m); \
_debug_trap(m); \
}
#endif
// END DIAGNOSTICS
/* local functions */
@@ -134,8 +125,8 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
bf->hint = COMMAND_BLOCK;
return (STAT_NOOP); // NOOP status is informative, not actionable
}
TRAP_ZERO(bf->length, "zoid() got L=0"); //+++++ Move this outside of zoid
TRAP_ZERO(bf->cruise_velocity, "zoid() got Vc=0"); // move this outside
__debug_trap_if_zero(bf->length, "mp_calculate_ramps() - got L=0");
__debug_trap_if_zero(bf->cruise_velocity, "mp_calculate_ramps() - got Vc=0");
// Timings from *here*
@@ -171,7 +162,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
block->body_length = bf->length;
block->body_time = block->body_length / block->cruise_velocity;
bf->block_time = block->body_time;
return (_exit_logger(bf, "1c"));
return (_ramp_exit_logger(bf, "1c"));
}
else { // degrade the hint to MIXED_ACCELERATION
bf->hint = MIXED_ACCELERATION;
@@ -203,7 +194,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
block->body_time = block->body_length / block->cruise_velocity;
block->tail_time = block->tail_length * 2 / (block->exit_velocity + block->cruise_velocity);
bf->block_time = block->body_time + block->tail_time;
return (_exit_logger(bf, "2d"));
return (_ramp_exit_logger(bf, "2d"));
}
// PERFECT_DECELERATION (1d) single tail segment (deltaV == delta_vmax)
@@ -213,7 +204,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
block->cruise_velocity = entry_velocity;
block->tail_time = block->tail_length * 2 / (block->exit_velocity + block->cruise_velocity);
bf->block_time = block->tail_time;
return (_exit_logger(bf, "1d"));
return (_ramp_exit_logger(bf, "1d"));
}
// Reset entry_changed. We won't likely be changing the next block's entry velocity.
@@ -246,7 +237,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
block->cruise_velocity = block->exit_velocity;
block->head_time = (block->head_length * 2.0) / (entry_velocity + block->cruise_velocity);
bf->block_time = block->head_time;
return (_exit_logger(bf, "1a"));
return (_ramp_exit_logger(bf, "1a"));
}
else { // it's hit the cusp
@@ -271,7 +262,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
block->head_time = (block->head_length * 2.0) / (entry_velocity + block->cruise_velocity);
block->body_time = block->body_length / block->cruise_velocity;
bf->block_time = block->head_time + block->body_time;
return (_exit_logger(bf, "2a"));
return (_ramp_exit_logger(bf, "2a"));
}
}
}
@@ -303,7 +294,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
bf->block_time = block->head_time + block->body_time + block->tail_time;
bf->hint = ASYMMETRIC_BUMP;
return (_exit_logger(bf, "2c"));
return (_ramp_exit_logger(bf, "2c"));
}
// *** Rate-Limited-Fit cases (3) ***
@@ -312,14 +303,8 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
// Rate-limited asymmetric cases (3)
// compute meet velocity to see if the cruise velocity rises above the entry and/or exit velocities
block->cruise_velocity = _get_meet_velocity(entry_velocity, block->exit_velocity, bf->length, bf, block);
#if (0)
TRAP_ZERO(block->cruise_velocity, "zoid() Vc=0 asymmetric HT case");
#else
if (fp_ZERO(block->cruise_velocity)) {
// return (STAT_MINIMUM_LENGTH_MOVE); // This error case needs to be recovered upstream
__asm__("BKPT");
}
#endif
__debug_trap_if_zero(block->cruise_velocity, "mp_calculate_ramps() Vc=0 asymmetric HT case");
// We now store the head/tail lengths we computed in _get_meet_velocity.
// treat as a full up and down (head and tail)
bf->hint = ASYMMETRIC_BUMP;
@@ -337,7 +322,7 @@ stat_t mp_calculate_ramps(mpBlockRuntimeBuf_t* block, mpBuf_t* bf, const float e
block->tail_time = (block->tail_length * 2.0) / (block->exit_velocity + block->cruise_velocity);
}
bf->block_time = block->head_time + block->body_time + block->tail_time;
return (_exit_logger(bf, "3c")); // 550us worst case
return (_ramp_exit_logger(bf, "3c")); // 550us worst case
}
/**** Planner helpers ****
+1 -1
View File
@@ -62,7 +62,7 @@
#include "report.h"
#include "util.h"
#include "json_parser.h"
#include "xio.h" // DIAGNOSTIC - only needed if xio_writeline() direct prints are used
#include "xio.h"
// Allocate planner structures
+1 -18
View File
@@ -226,23 +226,6 @@ typedef enum { // code blocks for planning and trapezoid ge
ASYMMETRIC_BUMP, // (Ve != Vx) < Vc
} blockHint;
/*
typedef enum {
ZOID_EXIT_NULL = 0,
ZOID_EXIT_1a,
ZOID_EXIT_1c,
ZOID_EXIT_1d,
ZOID_EXIT_2a,
ZOID_EXIT_2c,
ZOID_EXIT_2d,
ZOID_EXIT_3c,
ZOID_EXIT_3s,
ZOID_EXIT_3s2,
ZOID_EXIT_3d2,
ZOID_EXIT_3a2
} zoidExitPoint;
*/
/*** Most of these factors are the result of a lot of tweaking. Change with caution.***/
#define PLANNER_QUEUE_SIZE ((uint8_t)48) // Suggest 12 min. Limit is 255
@@ -292,7 +275,7 @@ typedef enum {
#define Veq2_lo 1.0
#define VELOCITY_ROUGHLY_EQ(v0,v1) ( (v0 > Vthr2) ? fabs(v0-v1) < Veq2_hi : fabs(v0-v1) < Veq2_lo )
/* Diagnostics */
/* Planner Diagnostics */
//#define __PLANNER_DIAGNOSTICS // comment this out to drop diagnostics
+3 -15
View File
@@ -44,18 +44,9 @@
#include "MotateDebug.h"
/* Note: stepper_debug statements removed 1/16/17 in SHA eb0905ccae03c04f99e6f471cbe029002f0324c6. See earlier commits to recover
// Unless debugging, this should always read "#if 0 && ..."
// DON'T COMMIT with anything else!
//
#if 0 && (IN_DEBUGGER == 1)
template<int32_t len>
void stepper_debug(const char (&str)[len]) { Motate::debug.write(str); };
#else
template<int32_t len>
void stepper_debug(const char (&str)[len]) { ; };
#endif
*/
/* Note: stepper_debug statements removed 1/16/17 in SHA eb0905ccae03c04f99e6f471cbe029002f0324c6.
* See earlier commits to recover
*/
/**** Allocate structures ****/
@@ -67,9 +58,6 @@ static stRunSingleton_t st_run;
static void _load_move(void);
// handy macro
//#define _f_to_period(f) (uint16_t)((float)F_CPU / (float)f)
/**** Setup motate ****/
using namespace Motate;
+75 -18
View File
@@ -50,24 +50,6 @@ using Motate::SysTickTimer;
/****** Global Scope Variables and Functions ******/
//*** debug utilities ***
#pragma GCC push_options
#pragma GCC optimize ("O0")
//#pragma GCC reset_options
inline void _debug_trap(const char *reason) {
// We might be able to put a print here, but it MIGHT interrupt other output
// and might be deep in an ISR, so we had better just _NOP() and hope for the best.
__NOP();
#ifdef IN_DEBUGGER
__asm__("BKPT");
#endif
}
#pragma GCC reset_options
void LAGER(const char * msg);
void LAGER_cm(const char * msg);
//*** vector utilities ***
extern float vector[AXES]; // vector of axes for passing to subroutines
@@ -178,4 +160,79 @@ inline T avg(const T a,const T b) {return (a+b)/2; }
// return count_>1 ? (hold=*t, *t=*(t+(count_-1)), *(t+(count_-1))=hold), c_strreverse(t+1, count_-2), count_ : count_;
//}
/*** Debug and DIAGNOSTICS ***
*
* This section collects debug and DIAGNOSTIC functions used by the project.
*
* The debug levels are set in the build line and may be one of:
* <omitted> - debug is off, IN_DEBUGGER == 0 (See Makefile for the logic)
* DEBUG=0 - debug is off, IN_DEBUGGER == 0
* DEBUG=1 - debug is on, IN_DEBUGGER == 0
* DEBUG=2 - debug is on, IN_DEBUGGER == 1. Requires HW debugger to be connected
* DEBUG=3 - debug is on, IN_DEBUGGER == 1. Requires HW debugger and Semihosting to be enabled and running in the debugger
*
* These settings are applied in the Makefile.
* In addition, MotateDebug.h contains the bulk of the Semihosting definitions
*
* The *reason value is provided as it will be shown in the __asm__("BKPT") backtrace,
* or on the __NOP() if a breakpoint is set
*
* Try to use the functions provided below for debug statements to keep the code clean. If these
* are insufficient you can bracket diagnostics like so to enable then for any non-zero debug level:
*
#if IN_DEBUGGER == 1
if (block->exit_velocity > block->cruise_velocity) {
__asm__("BKPT"); // exit > cruise after calculate_block
}
#endif
*
* ...or add a new debug functions to the ones below
*/
/*
* _debug_trap() - trap unconditionally
* _debug_trap_if_zero() - trap if floating point value is zero
* _debug_trap_if_true() - trap if condition is true
*
* The 'reason' value will display in GDB (but maybe not in AS7), and can also be passed
* to a downstream logger if these are introduced into the function.
*
* Note that it may be possible to print or generate exceptions in _debug_trap(), but
* it MIGHT interrupt other output, or might have been called deep in an ISR,
* so we had better just _NOP() and hope for the best.
*/
#pragma GCC push_options
#pragma GCC optimize ("O0")
inline void __debug_trap(const char *reason) {
__NOP();
#if IN_DEBUGGER == 1
__asm__("BKPT");
#endif
}
inline void __debug_trap_if_zero(float value, const char *reason) {
if (fp_ZERO(value)) {
__NOP();
#if IN_DEBUGGER == 1
__asm__("BKPT");
#endif
}
}
inline void __debug_trap_if_true(bool condition, const char *reason) {
if (condition) {
__NOP();
#if IN_DEBUGGER == 1
__asm__("BKPT");
#endif
}
}
#pragma GCC reset_options
void LAGER(const char * msg);
void LAGER_cm(const char * msg);
#endif // End of include guard: UTIL_H_ONCE
Executable → Regular
+6 -6
View File
@@ -600,7 +600,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
char c = _data[_scan_offset];
if (c == 0) {
_debug_trap("scan ran into NULL");
__debug_trap("_scanBuffer() scan ran into NULL");
flush(); // consider the connection and all data trashed
return false;
}
@@ -624,7 +624,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
ends_line = true; // _at_start_of_line is already true, this is not the first.
}
}
// prevent going furnther if we are ignoring
// prevent going further if we are ignoring
else if (_ignore_until_next_line)
{
// don't do anything
@@ -747,14 +747,14 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
// Either way, _scan_offset is one past the end, so we don't care which.
if (_data[_line_start_offset] == 0) {
_debug_trap("read ran into NULL");
__debug_trap("readline() read ran into NULL");
}
// scan past any leftover CR or LF from the previous line
while ((_data[_line_start_offset] == '\n') || (_data[_line_start_offset] == '\r')) {
_line_start_offset = (_line_start_offset+1)&(_size-1);
if (_scan_offset == _line_start_offset) {
_debug_trap("read ran into scan (1)");
__debug_trap("readline() read ran into scan (1)");
}
}
@@ -802,7 +802,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
if (_data[_read_offset] == 0) {
_debug_trap("read ran into NULL");
__debug_trap("readline() read ran into NULL");
}
// scan past any leftover CR or LF from the previous line
@@ -810,7 +810,7 @@ struct LineRXBuffer : RXBuffer<_size, owner_type, char> {
while ((c == '\n') || (c == '\r')) {
_read_offset = (_read_offset+1)&(_size-1);
if (_scan_offset == _read_offset) {
_debug_trap("read ran into scan (2)");
__debug_trap("readline() read ran into scan (2)");
}
// this also counts as the beginning of a line
_skip_sections.skip(_read_offset);