@@ -73,9 +73,7 @@ extern "C"
7373
7474
7575// 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;
7977static bool g_breakInSetup;
8078
8179// The ID of the halted thread being debugged.
@@ -110,8 +108,6 @@ volatile uint32_t mriThreadOrigHardFault;
110108volatile uint32_t mriThreadOrigMemManagement;
111109volatile uint32_t mriThreadOrigBusFault;
112110volatile uint32_t mriThreadOrigUsageFault;
113- // Address of the original Serial peripheral ISR to be hooked.
114- void (*g_origSerialISR)(void );
115111
116112// Entries to track the chunks of the context in a scatter list.
117113#if MRI_DEVICE_HAS_FPU
@@ -151,9 +147,8 @@ static void resumeApplicationThreads();
151147static void readThreadContext (osThreadId_t thread);
152148static void switchRtxHandlersToDebugStubsForSingleStepping ();
153149static void restoreRtxHandlers ();
154- static void callSerialBeginFromSetup ();
150+ static void callAttachFromSetup ();
155151static int justEnteredSetupCallback (void * pv);
156- static void hookSerialISR ();
157152static bool isThreadMode (uint32_t excReturn);
158153static bool hasEncounteredDebugEvent ();
159154static bool hasControlCBeenDetected ();
@@ -174,35 +169,16 @@ static void setControlCFlag();
174169
175170
176171
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*/ )
185173{
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 ) {
198175 // Only allow 1 ThreadMRI object to be initialized.
199176 return ;
200177 }
201178
202179 // Setup the singleton.
203- g_irq = IRQn;
204- g_baudRate = baudRate;
205180 g_breakInSetup = breakInSetup;
181+ g_pComm = pCommInterface;
206182
207183 // Initialize the MRI core.
208184 mriInit (" " );
@@ -225,10 +201,7 @@ void ThreadMRI::init(HardwareSerial& serial, IRQn_Type IRQn, uint32_t baudRate,
225201 return ;
226202 }
227203
228- g_pSerial = &serial;
229- if (g_baudRate != 0 ) {
230- callSerialBeginFromSetup ();
231- }
204+ callAttachFromSetup ();
232205}
233206
234207static __NO_RETURN void mriMain (void *pv)
@@ -364,32 +337,19 @@ static void restoreRtxHandlers()
364337 NVIC_SetVector (SysTick_IRQn, mriThreadOrigSysTick);
365338}
366339
367- static void callSerialBeginFromSetup ()
340+ static void callAttachFromSetup ()
368341{
369342 mriCore_SetTempBreakpoint ((uint32_t )setup, justEnteredSetupCallback, NULL );
370343}
371344
372345static int justEnteredSetupCallback (void * pv)
373346{
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);
382348
383349 // Return 0 to indicate that we want to halt execution at the beginning of setup() or 1 to not force a halt.
384350 return g_breakInSetup ? 0 : 1 ;
385351}
386352
387- static void hookSerialISR ()
388- {
389- g_origSerialISR = (void (*)(void ))NVIC_GetVector (g_irq);
390- NVIC_SetVector (g_irq, (uint32_t )serialISRHook);
391- }
392-
393353
394354ThreadMRI::~ThreadMRI () {
395355 // IMPORTANT NOTE: You are attempting to destroy the connection to GDB which isn't allowed.
@@ -441,20 +401,20 @@ static void recordAndSwitchFaultHandlersToDebugger()
441401
442402uint32_t Platform_CommHasReceiveData (void )
443403{
444- return g_pSerial ->available ();
404+ return g_pComm ->available ();
445405}
446406
447407int Platform_CommReceiveChar (void )
448408{
449- while (!g_pSerial ->available ()) {
409+ while (!g_pComm ->available ()) {
450410 // Busy wait.
451411 }
452- return g_pSerial ->read ();
412+ return g_pComm ->read ();
453413}
454414
455415void Platform_CommSendChar (int character)
456416{
457- g_pSerial ->write (character);
417+ g_pComm ->write (character);
458418}
459419
460420
@@ -693,10 +653,7 @@ static void clearFaultStatusBits()
693653
694654static void serialISRHook ()
695655{
696- if (g_origSerialISR) {
697- g_origSerialISR ();
698- }
699- if (!isDebuggerActive () && g_pSerial->available () > 0 ) {
656+ if (!isDebuggerActive () && g_pComm->available ()) {
700657 // Pend a halt into the debug monitor now that there is data from GDB ready to be read by it.
701658 setControlCFlag ();
702659 setMonitorPending ();
@@ -712,3 +669,97 @@ static void setControlCFlag()
712669{
713670 mriCortexMFlags |= CORTEXM_FLAGS_CTRL_C;
714671}
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