@@ -39,12 +39,12 @@ extern "C"
3939// ---------------------------------------------------------------------------------------------------------------------
4040// Configuration Parameters
4141// ---------------------------------------------------------------------------------------------------------------------
42- // The size of the mriThread () stack in uint64_t objects.
42+ // The size of the mriMain () stack in uint64_t objects.
4343#define MRI_THREAD_STACK_SIZE 128
44- // The maximum number of active threads that can be handled by the debugger .
45- #define MAXIMUM_ACTIVE_THREADS 64
44+ // The size of the mriIdle() stack in uint64_t objects .
45+ #define IDLE_THREAD_STACK_SIZE 40
4646
47- // Threads with these names will not be suspended when a debug event is occurred.
47+ // Threads with these names will not be suspended when a debug event has occurred.
4848// Typically these will be threads used by the communication stack to communicate with GDB or other important system
4949// threads.
5050static const char * g_threadNamesToIgnore[] = {
@@ -119,15 +119,15 @@ static uint32_t g_threadCount;
119119static uint32_t g_threadIndex;
120120// Buffer to be used for storing extra thread info.
121121static char g_threadExtraInfo[64 ];
122- // The ID of the rtx_idle thread to be skipped when providing list of threads to GDB.
123- static osThreadId_t g_idleThread;
124122
125123// This flag is set to a non-zero value if the DebugMon handler is to re-enable DWT watchpoints and FPB breakpoints
126124// after being disabled by the HardFault handler when a debug event is encounted in handler mode.
127125static volatile uint32_t g_enableDWTandFPB;
128126
129127// The ID of the mriMain() thread.
130128volatile osThreadId_t mriThreadId;
129+ // The ID of the mriIdle() thread.
130+ static osThreadId_t g_mriIdleThreadId;
131131
132132// If non-NULL, this is the thread that we want to single step.
133133// If NULL, single stepping is not enabled.
@@ -183,6 +183,7 @@ extern "C" void mriPendSVHandlerStub(void);
183183extern " C" void mriSysTickHandlerStub (void );
184184
185185// Forward Function Declarations
186+ static __NO_RETURN void mriIdle (void *pv);
186187static __NO_RETURN void mriMain (void *pv);
187188static void suspendAllApplicationThreads ();
188189static bool isThreadToIgnore (osThreadId_t thread);
@@ -199,7 +200,6 @@ static void wakeMriMainToDebugCurrentThread();
199200static void stopSingleStepping ();
200201static void recordAndSwitchFaultHandlersToDebugger ();
201202static void skipNullThreadIds ();
202- static bool isNullOrIdleThread (osThreadId_t threadId);
203203static const char * getThreadStateName (uint8_t threadState);
204204static bool isDebugThreadActive ();
205205static void setFaultDetectedFlag ();
@@ -234,27 +234,53 @@ ThreadDebug::ThreadDebug(DebugCommInterface* pCommInterface, bool breakInSetup,
234234 // Initialize the MRI core.
235235 mriInit (" " );
236236
237+ // Start the debugger's idle thread and suspend it for now.
238+ static uint64_t idleStack[IDLE_THREAD_STACK_SIZE];
239+ static osRtxThread_t idleThreadTcb;
240+ static const osThreadAttr_t idleThreadAttr =
241+ {
242+ .name = " mriIdle" ,
243+ .attr_bits = osThreadDetached,
244+ .cb_mem = &idleThreadTcb,
245+ .cb_size = sizeof (idleThreadTcb),
246+ .stack_mem = idleStack,
247+ .stack_size = sizeof (idleStack),
248+ .priority = (osPriority_t)(osPriorityIdle + 1 )
249+ };
250+ g_mriIdleThreadId = osThreadNew (mriIdle, NULL , &idleThreadAttr);
251+ if (g_mriIdleThreadId == NULL ) {
252+ return ;
253+ }
254+ osThreadSuspend (g_mriIdleThreadId);
255+
237256 // Start the debugger thread.
238- static uint64_t stack [MRI_THREAD_STACK_SIZE];
239- static osRtxThread_t threadTcb ;
240- static const osThreadAttr_t threadAttr =
257+ static uint64_t mainStack [MRI_THREAD_STACK_SIZE];
258+ static osRtxThread_t mainThreadTcb ;
259+ static const osThreadAttr_t mainThreadAttr =
241260 {
242261 .name = " mriMain" ,
243262 .attr_bits = osThreadDetached,
244- .cb_mem = &threadTcb ,
245- .cb_size = sizeof (threadTcb ),
246- .stack_mem = stack ,
247- .stack_size = sizeof (stack ),
263+ .cb_mem = &mainThreadTcb ,
264+ .cb_size = sizeof (mainThreadTcb ),
265+ .stack_mem = mainStack ,
266+ .stack_size = sizeof (mainStack ),
248267 .priority = osPriorityNormal
249268 };
250- mriThreadId = osThreadNew (mriMain, NULL , &threadAttr );
269+ mriThreadId = osThreadNew (mriMain, NULL , &mainThreadAttr );
251270 if (mriThreadId == NULL ) {
252271 return ;
253272 }
254273
255274 callAttachFromSetup ();
256275}
257276
277+ static __NO_RETURN void mriIdle (void *pv)
278+ {
279+ while (true ) {
280+ // Infinite loop at low priority if nothing else to do while debugging.
281+ }
282+ }
283+
258284static __NO_RETURN void mriMain (void *pv)
259285{
260286 // Run the code which suspends, resumes, etc the other threads at highest priority so that it doesn't context
@@ -271,9 +297,11 @@ static __NO_RETURN void mriMain(void *pv)
271297 restoreRtxHandlers ();
272298 }
273299
300+ osThreadResume (g_mriIdleThreadId);
274301 osThreadSetPriority (osThreadGetId (), osPriorityNormal);
275302 mriDebugException (&mriCortexMState.context );
276303 osThreadSetPriority (osThreadGetId (), osPriorityISR);
304+ osThreadSuspend (g_mriIdleThreadId);
277305
278306 if (Platform_IsSingleStepping ()) {
279307 mriThreadSingleStepThreadId = g_haltedThreadId;
@@ -287,20 +315,12 @@ static __NO_RETURN void mriMain(void *pv)
287315static void suspendAllApplicationThreads ()
288316{
289317 // Suspend application threads by setting their priorities to the lowest setting, osPriorityIdle.
290- // Bump rtx_idle thread up one priority level so that it will run instead of the 'suspended' application threads if
291- // the debug related threads go idle.
292- g_idleThread = 0 ;
293318 g_threadCount = osThreadGetCount ();
294319 ASSERT ( g_threadCount <= g_maxThreadCount );
295320 osThreadEnumerate (g_pSuspendedThreads, g_maxThreadCount);
296321 for (uint32_t i = 0 ; i < g_threadCount ; i++) {
297322 osThreadId_t thread = g_pSuspendedThreads[i];
298323 osPriority_t newPriority = osPriorityIdle;
299- const char * pThreadName = osThreadGetName (thread);
300- if (strcmp (pThreadName, " rtx_idle" ) == 0 ) {
301- newPriority = (osPriority_t)(osPriorityIdle + 1 );
302- g_idleThread = thread;
303- }
304324
305325 if (isThreadToIgnore (thread)) {
306326 g_pSuspendedThreads[i] = 0 ;
@@ -315,8 +335,8 @@ static void suspendAllApplicationThreads()
315335
316336static bool isThreadToIgnore (osThreadId_t thread)
317337{
318- if (thread == mriThreadId) {
319- // Don't want to suspend the debugger thread itself .
338+ if (thread == mriThreadId || thread == g_mriIdleThreadId ) {
339+ // Don't want to suspend the debugger threads themselves .
320340 return true ;
321341 }
322342
@@ -589,15 +609,10 @@ uint32_t Platform_RtosGetNextThreadId(void)
589609
590610static void skipNullThreadIds ()
591611{
592- while (g_threadIndex < g_threadCount && isNullOrIdleThread ( g_pSuspendedThreads[g_threadIndex]) )
612+ while (g_threadIndex < g_threadCount && g_pSuspendedThreads[g_threadIndex] == 0 )
593613 g_threadIndex++;
594614}
595615
596- static bool isNullOrIdleThread (osThreadId_t threadId)
597- {
598- return threadId == 0 || threadId == g_idleThread;
599- }
600-
601616const char * Platform_RtosGetExtraThreadInfo (uint32_t threadId)
602617{
603618 const char * pThreadName = osThreadGetName ((osThreadId)threadId);
@@ -823,7 +838,7 @@ static void clearFaultStatusBits()
823838
824839static void serialISRHook ()
825840{
826- if (!isDebuggerActive () && g_pComm->readable ()) {
841+ if (!isDebuggerActive () && ! isThreadToIgnore ( osThreadGetId ()) && g_pComm->readable ()) {
827842 // Pend a halt into the debug monitor now that there is data from GDB ready to be read by it.
828843 setControlCFlag ();
829844 setMonitorPending ();
0 commit comments