Skip to content

Commit 037d83d

Browse files
committed
Updates to kernel MRI library
Pulling over changes from MRI repository, many of which were made to ease future porting efforts and better integrate thread support. Switch __mri prefix to mri: * Dropping the initial "__" from MRI symbols with external scope so that they don't conflict with the Standard C Library reserved prefix. Refactor context as scatter gather list: * Rather than copying the thread context from the various portions of its stack, use a scatter gather list of pointers into the stack itself. It requires less assembly language code in mriExceptionHandler() since most of the context can be prepared in the mriCortexMExceptionHandler() C code now. * I updated code to use existing Platform_Get/SetProgramCounter() to manipulate the value of the PC register rather than grabbing it directly from the context which is now a bit more involved as it has to go through the scatter gather data structure. * Added unit tests to get 100% code coverage of the new ScatterGather code. I also pulled mriCortexMDebuggerStack and mriCortexMFlags objects out of CortexMState object to make it easier for assembly language code to access. Before the assembly language code needed to know the offset of these fields in the structure when accessing them. Now it can just refer to the individual globals directly. Differentiate CortexM code to support both Thread and Handler mode debugging based on setting of MRI_THREAD_MRI macro. Thread mode MRI is used to debug user mode code in an RTOS environment, leaving core code to run in the background. The updates includes: * Added fields to mriCortexMState to hold the value of the SP pointed to in the context scatter gather structure. Also added fields to track the fault cause such as exceptionNumber, DFSR, HFSR, etc. since for ThreadMRI it is better to capture these earlier in the exception handler before handing off to the main debugger thread as was done before in armv7-m.c Not a bad idea to do it earlier in the case of handler mode MRI either. * Handler mode MRI will still include system registers like MSP, PSP, etc. in the context while ThreadMRI will not. * In mriCortexMInit(), skip the setting of SVCall, SysTick, and PendSV priorities for ThreadMRI. ThreadMRI also sets DebugMon to the lowest priority while handler mode MRI sets it to the highest priority. Suppress fault display on startup: * If GDB is just attaching, we don't want to send the verbose output indicating the cause of a fault since GDB gets very confused by it. This confusion will even result in a 2 second timeout before MRI and GDB re-synchronize. Now uses the CORTEXM_FLAGS_CTRL_C flag to determine if SIGINT should be returned from Platform_DetermineCauseOfException() as the cause of a debug halt. Previously it was hardcoded to use the exception numbers of the LPC176x UART handlers. Platform_EnteringDebugger() in armv7-m.c now takes care of setting the the CORTEXM_FLAGS_ACTIVE_DEBUG and Platform_LeavingDebugger() takes care of clearing it so that handler/thread mode specific code doesn't have to anymore. mriCortexMInit() now takes a highestExternalIrq parameter that can be passed in from device specific init routines to indicate how many external interrupt sources should be defaulted to sub-zero priorities. Previously each particular device had its own loop to lower the priority of its external interrupts. That duplicate code across multiple devices is now gone. Add debugMonPriority parameter mriCortexMInit() function to allow port to specify the priority it desires for the DebugMonitor interrupt handler. Typically this will be 0, the highest priority, but there are cases when you might have code that should continue to run at the highest priority in the background, even when halted in GDB. In these cases, it makes sense for the background ISRs to be given a priority of 0 and DebugMonitor a priority of 1. The other default handler priorities are lowered to fall below DebugMonitor by mriCortexMInit() so that they can be debugged. Expose mriCortexMSetPriority() API which can be used by device/board specific code to set interrupt priority using MRI code that doesn't rely on __NVIC_PRIO_BITS being set correctly in the CMSIS headers. It instead determines the number of sub-priority bits at runtime. Expose the mriCortexMGetPriority() API publicly. This function also uses the runtime calculated sub-priority bit count. Increase size of mriCortexMDebuggerStack now that more of the context is pushed onto the stack to be later pointed to by ScatterGatherEntry objects. The debugger stack also now has different sizes based on whether a particular device has a FPU or not. Increased size of g_fakeStack for devices with FPU as its exception stack may need more room for autostacked floats. Updated target XML to mark LR as a code pointer as well so that GDB knows to try looking up the matching symbol when dumping it. Default baud rate to 230400. Largest supported across macOS, Windows, and Linux. Simplify device porting: * Now handle spurious UART interrupts in CortexM code rather than having all CortexM devices contain duplicated code to handle it. This means that ports no longer need to implement: * Platform_CommCausedInterrupt() * Platform_CommClearInterrupt() * Ports no longer need to implement: mriPlatform_CommUartIndex() * Remove com. port sharing and autobaud. Ports no longer need to implement: * mriPlatform_CommShouldWaitForGdbConnect() * mriPlatform_CommSharingWithApplication() * mriPlatform_CommPrepareToWaitForGdbConnection() * mriPlatform_CommIsWaitingForGdbToConnect() * mriPlatform_CommWaitForReceiveDataToStop() * Cortex-M7 names their system handler priority register array SHPR instead of SHP like the rest of the ARMv7-M family for some reason. Added a macro to take care of this name change.
1 parent 0455a56 commit 037d83d

34 files changed

+1358
-1088
lines changed

libraries/MRI/src/architectures/armv7-m/armv7-m.c

Lines changed: 512 additions & 85 deletions
Large diffs are not rendered by default.

libraries/MRI/src/architectures/armv7-m/armv7-m.h

Lines changed: 74 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,17 @@
1414
*/
1515
/* Routines and globals which expose the Cortex-M functionality to the mri debugger. Also describes global architecture
1616
state which is shared between cortex-m.c and cortex-m_asm.S */
17-
#ifndef _CORTEXM_H_
18-
#define _CORTEXM_H_
17+
#ifndef CORTEXM_H_
18+
#define CORTEXM_H_
1919

20-
/* Definitions used by C and Assembler code. */
21-
/* Flag bits used in CortexMState::flags field. */
22-
#define CORTEXM_FLAGS_ACTIVE_DEBUG 1
23-
#define CORTEXM_FLAGS_FAULT_DURING_DEBUG 2
24-
#define CORTEXM_FLAGS_SINGLE_STEPPING 4
25-
#define CORTEXM_FLAGS_RESTORE_BASEPRI 8
26-
#define CORTEXM_FLAGS_SVC_STEP 16
27-
28-
/* Constants related to special memory area used by the debugger for its stack so that it doesn't interfere with
29-
the task's stack contents. */
30-
#define CORTEXM_DEBUGGER_STACK_SIZE 39
31-
#define CORTEXM_DEBUGGER_STACK_SIZE_IN_BYTES (CORTEXM_DEBUGGER_STACK_SIZE * 8)
32-
#define CORTEXM_DEBUGGER_STACK_FILL 0xDEADBEEF
3320

34-
/* Offsets of fields within the CortexMState structure defined below. These are used to access the fields of the
35-
structure from within assembly language code. */
36-
#define CORTEXM_STATE_DEBUGGER_STACK_OFFSET 0
37-
#define CORTEXM_STATE_FLAGS_OFFSET (CORTEXM_STATE_DEBUGGER_STACK_OFFSET + CORTEXM_DEBUGGER_STACK_SIZE_IN_BYTES)
38-
#define CORTEXM_STATE_TASK_SP_OFFSET (CORTEXM_STATE_FLAGS_OFFSET + 4)
39-
#define CORTEXM_STATE_CONTEXT_OFFSET (CORTEXM_STATE_TASK_SP_OFFSET + 4)
40-
#define CORTEXM_STATE_SAVED_MSP_OFFSET (CORTEXM_STATE_CONTEXT_OFFSET + 17 * 4)
21+
// UNDONE:
22+
#define MRI_THREAD_MRI 0
4123

42-
// In some other build systems, MRI_DEVICE_HAS_FPU won't be passed in on compiler's command line so use the
43-
// target Cortex-M type to determine if it has a FPU or not.
24+
/* Definitions used by C and Assembler code. */
25+
/* In some other build systems, MRI_DEVICE_HAS_FPU won't be passed in on compiler's command line so use the
26+
target Cortex-M type to determine if it has a FPU or not.
27+
*/
4428
#ifndef MRI_DEVICE_HAS_FPU
4529
#ifdef __ARM_ARCH_7EM__
4630
#define MRI_DEVICE_HAS_FPU 1
@@ -49,101 +33,92 @@
4933
#endif
5034
#endif
5135

36+
/* Flag bits used in mriCortexMFlags global. */
37+
#define CORTEXM_FLAGS_ACTIVE_DEBUG (1 << 0)
38+
#define CORTEXM_FLAGS_FAULT_DURING_DEBUG (1 << 1)
39+
#define CORTEXM_FLAGS_SINGLE_STEPPING (1 << 2)
40+
#define CORTEXM_FLAGS_RESTORE_BASEPRI (1 << 3)
41+
#define CORTEXM_FLAGS_SVC_STEP (1 << 4)
42+
#define CORTEXM_FLAGS_CTRL_C (1 << 5)
43+
44+
/* Special memory area used by the debugger for its stack so that it doesn't interfere with the task's
45+
stack contents.
46+
47+
The stack sizes below are based on actual test runs on LPC1768 (non-FPU) and LPC4330 (FPU) based boards with a
48+
roughly 25% reservation for future growth.
49+
*/
50+
#define CORTEXM_DEBUGGER_STACK_FILL 0xDEADBEEF
51+
#if MRI_DEVICE_HAS_FPU
52+
#define CORTEXM_DEBUGGER_STACK_SIZE 90
53+
#else
54+
#define CORTEXM_DEBUGGER_STACK_SIZE 45
55+
#endif
56+
57+
58+
5259
/* Definitions only required from C code. */
5360
#if !__ASSEMBLER__
5461

5562
#include <stdint.h>
5663
#include <core/token.h>
57-
58-
/* NOTE: The MriExceptionHandler function definition in mriasm.S is dependent on the layout of this structure. It
59-
is also dictated by the version of gdb which supports the ARM processors. It should only be changed if the
60-
gdb ARM support code is modified and then the context saving and restoring code will need to be modified to
61-
use the correct offsets as well.
62-
*/
63-
typedef struct
64-
{
65-
uint32_t R0;
66-
uint32_t R1;
67-
uint32_t R2;
68-
uint32_t R3;
69-
uint32_t R4;
70-
uint32_t R5;
71-
uint32_t R6;
72-
uint32_t R7;
73-
uint32_t R8;
74-
uint32_t R9;
75-
uint32_t R10;
76-
uint32_t R11;
77-
uint32_t R12;
78-
uint32_t SP;
79-
uint32_t LR;
80-
uint32_t PC;
81-
uint32_t CPSR;
82-
uint32_t MSP;
83-
uint32_t PSP;
84-
uint32_t PRIMASK;
85-
uint32_t BASEPRI;
86-
uint32_t FAULTMASK;
87-
uint32_t CONTROL;
64+
#include <core/scatter_gather.h>
65+
66+
67+
/* Give friendly names to the indices of important registers in the context scatter gather list. */
68+
#define R0 0
69+
#define R1 1
70+
#define R2 2
71+
#define R3 3
72+
#define R7 7
73+
#define SP 13
74+
#define LR 14
75+
#define PC 15
76+
#define CPSR 16
77+
#define BASEPRI 20
78+
79+
80+
#if MRI_THREAD_MRI
81+
#define SPECIAL_REGISTER_COUNT 0
82+
#else
83+
#define SPECIAL_REGISTER_COUNT 6
84+
#endif
8885
#if MRI_DEVICE_HAS_FPU
89-
uint32_t S0;
90-
uint32_t S1;
91-
uint32_t S2;
92-
uint32_t S3;
93-
uint32_t S4;
94-
uint32_t S5;
95-
uint32_t S6;
96-
uint32_t S7;
97-
uint32_t S8;
98-
uint32_t S9;
99-
uint32_t S10;
100-
uint32_t S11;
101-
uint32_t S12;
102-
uint32_t S13;
103-
uint32_t S14;
104-
uint32_t S15;
105-
uint32_t S16;
106-
uint32_t S17;
107-
uint32_t S18;
108-
uint32_t S19;
109-
uint32_t S20;
110-
uint32_t S21;
111-
uint32_t S22;
112-
uint32_t S23;
113-
uint32_t S24;
114-
uint32_t S25;
115-
uint32_t S26;
116-
uint32_t S27;
117-
uint32_t S28;
118-
uint32_t S29;
119-
uint32_t S30;
120-
uint32_t S31;
121-
uint32_t FPSCR;
86+
#define CONTEXT_SIZE (17 + 33 + SPECIAL_REGISTER_COUNT)
87+
#else
88+
#define CONTEXT_SIZE (17 + SPECIAL_REGISTER_COUNT)
12289
#endif
123-
} Context;
12490

12591
/* NOTE: The largest buffer is required for receiving the 'G' command which receives the contents of the registers from
12692
the debugger as two hex digits per byte. Also need a character for the 'G' command itself. */
127-
#define CORTEXM_PACKET_BUFFER_SIZE (1 + 2 * sizeof(Context))
93+
#define CORTEXM_PACKET_BUFFER_SIZE (1 + 2 * sizeof(uint32_t) * CONTEXT_SIZE)
12894

12995
typedef struct
13096
{
131-
uint64_t debuggerStack[CORTEXM_DEBUGGER_STACK_SIZE];
132-
volatile uint32_t flags;
133-
volatile uint32_t taskSP;
134-
Context context;
97+
ScatterGather context;
98+
uint32_t taskSP;
99+
uint32_t sp;
100+
uint32_t exceptionNumber;
101+
uint32_t dfsr;
102+
uint32_t hfsr;
103+
uint32_t cfsr;
104+
uint32_t mmfar;
105+
uint32_t bfar;
135106
uint32_t originalPC;
136107
uint32_t originalBasePriority;
108+
uint32_t subPriorityBitCount;
137109
int maxStackUsed;
138110
char packetBuffer[CORTEXM_PACKET_BUFFER_SIZE];
139111
} CortexMState;
140112

141-
extern CortexMState __mriCortexMState;
142-
extern const uint32_t __mriCortexMFakeStack[8];
113+
extern uint64_t mriCortexMDebuggerStack[CORTEXM_DEBUGGER_STACK_SIZE];
114+
extern volatile uint32_t mriCortexMFlags;
115+
extern CortexMState mriCortexMState;
143116

144-
void __mriCortexMInit(Token* pParameterTokens);
117+
void mriCortexMInit(Token* pParameterTokens, uint8_t debugMonPriority, IRQn_Type highestExternalIrq);
118+
void mriCortexMSetPriority(IRQn_Type irq, uint8_t priority, uint8_t subPriority);
119+
uint8_t mriCortexMGetPriority(IRQn_Type irq);
145120

146-
#endif /* !__ASSEMBLER__ */
147121

122+
#endif /* !__ASSEMBLER__ */
148123

149-
#endif /* _CORTEXM_H_ */
124+
#endif /* CORTEXM_H_ */

0 commit comments

Comments
 (0)