@@ -73,9 +73,7 @@ extern "C"
73
73
74
74
75
75
// Globals that describe the ThreadMRI singleton.
76
- static HardwareSerial* g_pSerial;
77
- static IRQn_Type g_irq;
78
- static uint32_t g_baudRate;
76
+ static DebugCommInterface* g_pComm;
79
77
static bool g_breakInSetup;
80
78
81
79
// The ID of the halted thread being debugged.
@@ -110,8 +108,6 @@ volatile uint32_t mriThreadOrigHardFault;
110
108
volatile uint32_t mriThreadOrigMemManagement;
111
109
volatile uint32_t mriThreadOrigBusFault;
112
110
volatile uint32_t mriThreadOrigUsageFault;
113
- // Address of the original Serial peripheral ISR to be hooked.
114
- void (*g_origSerialISR)(void );
115
111
116
112
// Entries to track the chunks of the context in a scatter list.
117
113
#if MRI_DEVICE_HAS_FPU
@@ -151,9 +147,8 @@ static void resumeApplicationThreads();
151
147
static void readThreadContext (osThreadId_t thread);
152
148
static void switchRtxHandlersToDebugStubsForSingleStepping ();
153
149
static void restoreRtxHandlers ();
154
- static void callSerialBeginFromSetup ();
150
+ static void callAttachFromSetup ();
155
151
static int justEnteredSetupCallback (void * pv);
156
- static void hookSerialISR ();
157
152
static bool isThreadMode (uint32_t excReturn);
158
153
static bool hasEncounteredDebugEvent ();
159
154
static bool hasControlCBeenDetected ();
@@ -174,35 +169,16 @@ static void setControlCFlag();
174
169
175
170
176
171
177
-
178
- ThreadMRI::ThreadMRI (HardwareSerial& serial, IRQn_Type IRQn, uint32_t baudRate, bool breakInSetup /* =true */ )
179
- {
180
- init (serial, IRQn, baudRate, breakInSetup);
181
- }
182
-
183
-
184
- ThreadMRI::ThreadMRI (HardwareSerial& serial, bool breakInSetup /* =true */ )
172
+ ThreadMRI::ThreadMRI (DebugCommInterface* pCommInterface, bool breakInSetup /* =true*/ )
185
173
{
186
- init (serial, SysTick_IRQn, 115200 , breakInSetup);
187
- }
188
-
189
-
190
- ThreadMRI::ThreadMRI (HardwareSerial& serial, IRQn_Type IRQn)
191
- {
192
- init (serial, IRQn, 0 , false );
193
- }
194
-
195
- void ThreadMRI::init (HardwareSerial& serial, IRQn_Type IRQn, uint32_t baudRate, bool breakInSetup)
196
- {
197
- if (g_pSerial != NULL ) {
174
+ if (g_pComm != NULL ) {
198
175
// Only allow 1 ThreadMRI object to be initialized.
199
176
return ;
200
177
}
201
178
202
179
// Setup the singleton.
203
- g_irq = IRQn;
204
- g_baudRate = baudRate;
205
180
g_breakInSetup = breakInSetup;
181
+ g_pComm = pCommInterface;
206
182
207
183
// Initialize the MRI core.
208
184
mriInit (" " );
@@ -225,10 +201,7 @@ void ThreadMRI::init(HardwareSerial& serial, IRQn_Type IRQn, uint32_t baudRate,
225
201
return ;
226
202
}
227
203
228
- g_pSerial = &serial;
229
- if (g_baudRate != 0 ) {
230
- callSerialBeginFromSetup ();
231
- }
204
+ callAttachFromSetup ();
232
205
}
233
206
234
207
static __NO_RETURN void mriMain (void *pv)
@@ -364,32 +337,19 @@ static void restoreRtxHandlers()
364
337
NVIC_SetVector (SysTick_IRQn, mriThreadOrigSysTick);
365
338
}
366
339
367
- static void callSerialBeginFromSetup ()
340
+ static void callAttachFromSetup ()
368
341
{
369
342
mriCore_SetTempBreakpoint ((uint32_t )setup, justEnteredSetupCallback, NULL );
370
343
}
371
344
372
345
static int justEnteredSetupCallback (void * pv)
373
346
{
374
- g_pSerial->begin (g_baudRate);
375
- // while (!g_pSerial) {}
376
-
377
- if (g_irq != SysTick_IRQn) {
378
- hookSerialISR ();
379
- } else {
380
- (static_cast <USBSerial*>(g_pSerial))->attach (serialISRHook);
381
- }
347
+ g_pComm->attach (serialISRHook);
382
348
383
349
// Return 0 to indicate that we want to halt execution at the beginning of setup() or 1 to not force a halt.
384
350
return g_breakInSetup ? 0 : 1 ;
385
351
}
386
352
387
- static void hookSerialISR ()
388
- {
389
- g_origSerialISR = (void (*)(void ))NVIC_GetVector (g_irq);
390
- NVIC_SetVector (g_irq, (uint32_t )serialISRHook);
391
- }
392
-
393
353
394
354
ThreadMRI::~ThreadMRI () {
395
355
// IMPORTANT NOTE: You are attempting to destroy the connection to GDB which isn't allowed.
@@ -441,20 +401,20 @@ static void recordAndSwitchFaultHandlersToDebugger()
441
401
442
402
uint32_t Platform_CommHasReceiveData (void )
443
403
{
444
- return g_pSerial ->available ();
404
+ return g_pComm ->available ();
445
405
}
446
406
447
407
int Platform_CommReceiveChar (void )
448
408
{
449
- while (!g_pSerial ->available ()) {
409
+ while (!g_pComm ->available ()) {
450
410
// Busy wait.
451
411
}
452
- return g_pSerial ->read ();
412
+ return g_pComm ->read ();
453
413
}
454
414
455
415
void Platform_CommSendChar (int character)
456
416
{
457
- g_pSerial ->write (character);
417
+ g_pComm ->write (character);
458
418
}
459
419
460
420
@@ -693,10 +653,7 @@ static void clearFaultStatusBits()
693
653
694
654
static void serialISRHook ()
695
655
{
696
- if (g_origSerialISR) {
697
- g_origSerialISR ();
698
- }
699
- if (!isDebuggerActive () && g_pSerial->available () > 0 ) {
656
+ if (!isDebuggerActive () && g_pComm->available ()) {
700
657
// Pend a halt into the debug monitor now that there is data from GDB ready to be read by it.
701
658
setControlCFlag ();
702
659
setMonitorPending ();
@@ -712,3 +669,97 @@ static void setControlCFlag()
712
669
{
713
670
mriCortexMFlags |= CORTEXM_FLAGS_CTRL_C;
714
671
}
672
+
673
+
674
+
675
+
676
+ DebugCommInterface::~DebugCommInterface ()
677
+ {
678
+ }
679
+
680
+ UartDebugCommInterface::UartDebugCommInterface (PinName txPin, PinName rxPin, uint32_t baudRate) :
681
+ _pCallback(NULL ), _serial(txPin, rxPin, baudRate), _read(0 ), _write(0 )
682
+ {
683
+ }
684
+
685
+ UartDebugCommInterface::~UartDebugCommInterface ()
686
+ {
687
+ }
688
+
689
+ bool UartDebugCommInterface::available ()
690
+ {
691
+ return _read != _write;
692
+ }
693
+
694
+ uint8_t UartDebugCommInterface::read ()
695
+ {
696
+ // This read should never block since Platform_CommReceiveChar() always checks available() first.
697
+ ASSERT ( available () );
698
+
699
+ uint8_t byte = _queue[_read];
700
+ _read = wrappingIncrement (_read);
701
+ return byte;
702
+ }
703
+
704
+ uint32_t UartDebugCommInterface::wrappingIncrement (uint32_t val)
705
+ {
706
+ return (val + 1 ) & (sizeof (_queue) - 1 );
707
+ }
708
+
709
+ void UartDebugCommInterface::write (uint8_t c)
710
+ {
711
+ _serial.write (&c, 1 );
712
+ }
713
+
714
+ void UartDebugCommInterface::attach (void (*pCallback)())
715
+ {
716
+ _pCallback = pCallback;
717
+ _serial.attach (mbed::callback (this , &UartDebugCommInterface::onReceivedData));
718
+ }
719
+
720
+ void UartDebugCommInterface::onReceivedData ()
721
+ {
722
+ while (_serial.readable ()) {
723
+ uint8_t byte;
724
+ _serial.read (&byte, 1 );
725
+ if (wrappingIncrement (_write) != _read) {
726
+ // _queue isn't full so we can add this byte to it.
727
+ _queue[_write] = byte;
728
+ _write = wrappingIncrement (_write);
729
+ }
730
+ }
731
+
732
+ ASSERT ( _pCallback != NULL );
733
+ _pCallback ();
734
+ }
735
+
736
+
737
+
738
+ UsbDebugCommInterface::UsbDebugCommInterface (arduino::USBSerial* pSerial) :
739
+ _pSerial(pSerial)
740
+ {
741
+ }
742
+
743
+ UsbDebugCommInterface::~UsbDebugCommInterface ()
744
+ {
745
+ }
746
+
747
+ bool UsbDebugCommInterface::available ()
748
+ {
749
+ return _pSerial->available () > 0 ;
750
+ }
751
+
752
+ uint8_t UsbDebugCommInterface::read ()
753
+ {
754
+ return _pSerial->read ();
755
+ }
756
+
757
+ void UsbDebugCommInterface::write (uint8_t c)
758
+ {
759
+ _pSerial->write (c);
760
+ }
761
+
762
+ void UsbDebugCommInterface::attach (void (*pCallback)())
763
+ {
764
+ _pSerial->attach (pCallback);
765
+ }
0 commit comments