Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SoftwareReset.h « Hardware « src - github.com/Duet3D/RepRapFirmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e0119f41d298e0e665766a5d90609fefd3f51159 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
 * SoftwareReset.h
 *
 *  Created on: 15 Nov 2019
 *      Author: David
 */

#ifndef SRC_SOFTWARERESET_H_
#define SRC_SOFTWARERESET_H_

#include <RepRapFirmware.h>

#if SAM3XA
# include <DueFlashStorage.h>
#endif

// Enumeration describing the reasons for a software reset.
// The spin state gets or'ed into this, so keep the lower 5 bits unused.
// IMPORTANT! When changing this, also update table SoftwareResetReasonText
enum class SoftwareResetReason : uint16_t
{
	user = 0u,						// M999 command
	erase = 1u << 5,				// special M999 command to erase firmware and reset
	NMI = 2u << 5,
	hardFault = 3u << 5,			// most exceptions get escalated to a hard fault
	stuckInSpin = 4u << 5,			// we got stuck in a Spin() function in the Main task for too long
	wdtFault = 5u << 5,				// secondary watchdog
	usageFault = 6u << 5,
	otherFault = 7u << 5,
	stackOverflow = 8u << 5,		// FreeRTOS detected stack overflow
	assertCalled = 9u << 5,			// FreeRTOS assertion failure
	heaterWatchdog = 10u << 5,		// the Heat task didn't kick the watchdog often enough
	memFault = 11u << 5,			// the MPU raised a fault
	terminateCalled = 12u << 5,		// std::terminate was called
	pureOrDeletedVirtual = 13u << 5,
	outOfMemory = 14u << 5,
	//unused = 15u << 5,

	mainReasonMask = 0x0F << 5,		// mask to pick out the  main reason in a uint16_t

	// Bits that are or'ed in
	unusedBit = 0x0200,				// spare bit
	unused2 = 0x0400,				// spare bit
	inAuxOutput = 0x0800,			// this bit is or'ed in if we were in aux output at the time
	unused_was_inLwipSpin = 0x2000,	// no longer used
	inUsbOutput = 0x4000,			// this bit is or'ed in if we were in USB output at the time
	deliberate = 0x8000				// this but it or'ed in if we deliberately caused a fault
};

// These are the structures used to hold our non-volatile data.
// We store the software reset data in the 512-byte user signature area of the SAM4E, SAM4S and SAME70 processors.
// It must be a multiple of 4 bytes long.
struct SoftwareResetData
{
	uint16_t magic;								// the magic number, including the version
	uint16_t resetReason;						// this records why we did a software reset, for diagnostic purposes
	int32_t neverUsedRam;						// the amount of never used RAM at the last abnormal software reset
	uint32_t hfsr;								// hard fault status register
	uint32_t cfsr;								// configurable fault status register
	uint32_t icsr;								// interrupt control and state register
	uint32_t bfar;								// bus fault address register
	uint32_t sp;								// stack pointer
	uint32_t when;								// value of the RTC when the software reset occurred
	uint32_t taskName;							// first 4 bytes of the task name, or 'none'
	uint32_t stackOffset;						// how many spare words of stack the running task has
	uint32_t stackMarkerValid : 1,				// true if the stack low marker wasn't overwritten
			 spare : 31;						// unused at present
	// The stack length is set to 27 words because that is the most we can print in a single message using our 256-byte format buffer
	uint32_t stack[27];							// stack when the exception occurred, with the link register and program counter at the bottom

	bool IsVacant() const noexcept;				// return true if this struct can be written without erasing it first
	bool IsValid() const noexcept { return magic == magicValue; }
	void Clear() noexcept;
	void Populate(uint16_t reason, const uint32_t *stk) noexcept;
	void Print(MessageType mtype, unsigned int slot) const noexcept;

	static constexpr uint16_t versionValue = 9;		// increment this whenever this struct changes
	static constexpr uint16_t magicValue = 0x7D00 | versionValue;	// value we use to recognise that all the flash data has been written

	static const char *const ReasonText[];
	static uint8_t extraDebugInfo;				// 3 bits of extra info for debugging can be stored here
};

#endif /* SRC_SOFTWARERESET_H_ */