Skip to content

Commit

Permalink
Merge pull request #548 from whoenig/feature-improved-error-handling
Browse files Browse the repository at this point in the history
Improve ASSERT error handling and reporting
  • Loading branch information
krichardsson authored Feb 5, 2020
2 parents e27cd17 + f953c98 commit 030de69
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 21 deletions.
2 changes: 2 additions & 0 deletions src/drivers/interface/motors.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ void motorsDeInit(const MotorPerifDef** motorMapSelect);
*/
bool motorsTest(void);

void motorsDisable(void);

/**
* Set the PWM ratio of the motor 'id'
*/
Expand Down
7 changes: 7 additions & 0 deletions src/drivers/src/motors.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,13 @@ bool motorsTest(void)
return isInit;
}

void motorsDisable(void)
{
for (int id = 0; id < NBR_OF_MOTORS; ++id) {
motorsSetRatio(id, 0);
}
}

// Ithrust is thrust mapped for 65536 <==> 60 grams
void motorsSetRatio(uint32_t id, uint16_t ithrust)
{
Expand Down
22 changes: 17 additions & 5 deletions src/drivers/src/nvic.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,17 @@ void DONT_DISCARD printHardFault(uint32_t* hardfaultArgs)
ledClearAll();
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);

storeAssertSnapshotData(__FILE__, __LINE__);
motorsDisable();

storeAssertHardfaultData(
stacked_r0,
stacked_r1,
stacked_r2,
stacked_r3,
stacked_r12,
stacked_lr,
stacked_pc,
stacked_psr);
while (1)
{}
}
Expand All @@ -157,8 +166,9 @@ void DONT_DISCARD MemManage_Handler(void)
ledClearAll();
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
motorsDisable();

storeAssertSnapshotData(__FILE__, __LINE__);
storeAssertTextData("MemManage");
while (1)
{}
}
Expand All @@ -177,8 +187,9 @@ void DONT_DISCARD BusFault_Handler(void)
ledClearAll();
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
motorsDisable();

storeAssertSnapshotData(__FILE__, __LINE__);
storeAssertTextData("BusFault");
while (1)
{}
}
Expand All @@ -197,8 +208,9 @@ void DONT_DISCARD UsageFault_Handler(void)
ledClearAll();
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
motorsDisable();

storeAssertSnapshotData(__FILE__, __LINE__);
storeAssertTextData("UsageFault");
while (1)
{}
}
Expand Down
17 changes: 11 additions & 6 deletions src/hal/src/freeRTOSdebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,30 @@
#include "debug.h"
#include "nvicconf.h"
#include "led.h"
#include "motors.h"

uint32_t traceTickCount;

void vApplicationMallocFailedHook( void )
{
portDISABLE_INTERRUPTS();
DEBUG_PRINT("\nMalloc failed!\n");
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
while(1);
portDISABLE_INTERRUPTS();
DEBUG_PRINT("\nMalloc failed!\n");
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
motorsDisable();
storeAssertTextData("Malloc failed");
while(1);
}

#if (configCHECK_FOR_STACK_OVERFLOW == 1)
#if (configCHECK_FOR_STACK_OVERFLOW > 0)
void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed portCHAR *pcTaskName)
{
portDISABLE_INTERRUPTS();
DEBUG_PRINT("\nStack overflow!\n");
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
motorsDisable();
storeAssertTextData("Stack overflow");
while(1);
}
#endif
Expand Down
22 changes: 21 additions & 1 deletion src/utils/interface/cfassert.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ void printAssertSnapshotData();
/**
* Store assert snapshot data to be read at startup if a reset is triggered (watchdog)
*/
void storeAssertSnapshotData(char *file, int line);
void storeAssertFileData(const char *file, int line);
/**
* Store hardfault data to be read at startup if a reset is triggered (watchdog)
* Line information can be printed using:
* > make gdb
* gdb> info line *0x<PC>
*/
void storeAssertHardfaultData(
unsigned int r0,
unsigned int r1,
unsigned int r2,
unsigned int r3,
unsigned int r12,
unsigned int lr,
unsigned int pc,
unsigned int psr);

/**
* Store assert data to be read at startup if a reset is triggered (watchdog)
*/
void storeAssertTextData(const char *text);

#endif //__CFASSERT_H__
95 changes: 86 additions & 9 deletions src/utils/src/cfassert.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,50 @@

#define MAGIC_ASSERT_INDICATOR 0x2f8a001f

enum snapshotType_e
{
SnapshotTypeInvalid = 0,
SnapshotTypeFile = 1,
SnapshotTypeHardFault = 2,
SnapshotTypeText = 3,
};

typedef struct SNAPSHOT_DATA {
uint32_t magicNumber;
char* fileName;
int line;
enum snapshotType_e type;
union {
struct {
const char* fileName;
int line;
} file;
struct {
unsigned int r0;
unsigned int r1;
unsigned int r2;
unsigned int r3;
unsigned int r12;
unsigned int lr;
unsigned int pc;
unsigned int psr;
} hardfault;
struct {
const char* text;
} text;
};
} SNAPSHOT_DATA;

// The .nzds section is not cleared at startup, data here will survive a
// reset (by the watch dog for instance)
SNAPSHOT_DATA snapshot __attribute__((section(".nzds"))) = {
.magicNumber = 0,
.fileName = "",
.line = 0
.type = SnapshotTypeInvalid,
};


void assertFail(char *exp, char *file, int line)
{
portDISABLE_INTERRUPTS();
storeAssertSnapshotData(file, line);
storeAssertFileData(file, line);
DEBUG_PRINT("Assert failed %s:%d\n", file, line);

motorsSetRatio(MOTOR_M1, 0);
Expand All @@ -64,21 +89,73 @@ void assertFail(char *exp, char *file, int line)
ledClearAll();
ledSet(ERR_LED1, 1);
ledSet(ERR_LED2, 1);
motorsDisable();

while (1);
}

void storeAssertSnapshotData(char *file, int line)
void storeAssertFileData(const char *file, int line)
{
snapshot.magicNumber = MAGIC_ASSERT_INDICATOR;
snapshot.type = SnapshotTypeFile;
snapshot.file.fileName = file;
snapshot.file.line = line;
}

void storeAssertHardfaultData(
unsigned int r0,
unsigned int r1,
unsigned int r2,
unsigned int r3,
unsigned int r12,
unsigned int lr,
unsigned int pc,
unsigned int psr)
{
snapshot.magicNumber = MAGIC_ASSERT_INDICATOR;
snapshot.type = SnapshotTypeHardFault;
snapshot.hardfault.r0 = r0;
snapshot.hardfault.r1 = r1;
snapshot.hardfault.r2 = r2;
snapshot.hardfault.r3 = r3;
snapshot.hardfault.r12 = r12;
snapshot.hardfault.lr = lr;
snapshot.hardfault.pc = pc;
snapshot.hardfault.psr = psr;
}

void storeAssertTextData(const char *text)
{
snapshot.magicNumber = MAGIC_ASSERT_INDICATOR;
snapshot.fileName = file;
snapshot.line = line;
snapshot.type = SnapshotTypeText;
snapshot.text.text = text;
}

void printAssertSnapshotData()
{
if (MAGIC_ASSERT_INDICATOR == snapshot.magicNumber) {
DEBUG_PRINT("Assert failed at %s:%d\n", snapshot.fileName, snapshot.line);
switch (snapshot.type) {
case SnapshotTypeFile:
DEBUG_PRINT("Assert failed at %s:%d\n", snapshot.file.fileName, snapshot.file.line);
break;
case SnapshotTypeHardFault:
DEBUG_PRINT("Hardfault. r0: %X, r1: %X, r2: %X, r3: %X, r12: %X, lr: %X, pc: %X, psr: %X\n",
snapshot.hardfault.r0,
snapshot.hardfault.r1,
snapshot.hardfault.r2,
snapshot.hardfault.r3,
snapshot.hardfault.r12,
snapshot.hardfault.lr,
snapshot.hardfault.pc,
snapshot.hardfault.psr);
break;
case SnapshotTypeText:
DEBUG_PRINT("Assert failed: %s\n", snapshot.text.text);
break;
default:
DEBUG_PRINT("Assert failed, but unknown type\n");
break;
}
} else {
DEBUG_PRINT("No assert information found\n");
}
Expand Down

0 comments on commit 030de69

Please sign in to comment.