aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Tsou <tom@tsou.cc>2013-09-28 18:04:19 -0400
committerThomas Tsou <tom@tsou.cc>2013-10-18 13:10:17 -0400
commit92c16df87586283894decd761561cdc4890752fa (patch)
tree2b55a66cd4adfdf432207a94bac41b3a3c2ed43b
parentd5a80c3dc6cd2ed8e3c016988b980c6bc7fe4552 (diff)
Transceiver52M: Separate main transmit and receive drive threads
This patch primarily addresses observed repeated overrun conditions in embedded environments - namely ARM. The heartbeat of the transceiver is derived from the receive sample stream, which drives the main GSM clock. Detach the transmit thread from the receive loop to avoid interfering with the receive I/O, which is sensitive to overrun conditions if pull process is interrupted. Signed-off-by: Thomas Tsou <tom@tsou.cc>
-rw-r--r--Transceiver52M/Transceiver.cpp27
-rw-r--r--Transceiver52M/Transceiver.h12
2 files changed, 24 insertions, 15 deletions
diff --git a/Transceiver52M/Transceiver.cpp b/Transceiver52M/Transceiver.cpp
index 0a515b1..03aa3c1 100644
--- a/Transceiver52M/Transceiver.cpp
+++ b/Transceiver52M/Transceiver.cpp
@@ -59,7 +59,8 @@ Transceiver::Transceiver(int wBasePort,
{
GSM::Time startTime(random() % gHyperframe,0);
- mFIFOServiceLoopThread = new Thread(32768); ///< thread to push bursts into transmit FIFO
+ mRxServiceLoopThread = new Thread(32768);
+ mTxServiceLoopThread = new Thread(32768);
mControlServiceLoopThread = new Thread(32768); ///< thread to process control messages from GSM core
mTransmitPriorityQueueServiceLoopThread = new Thread(32768);///< thread to process transmit bursts from GSM core
@@ -504,7 +505,8 @@ void Transceiver::driveControl()
mRadioInterface->start();
// Start radio interface threads.
- mFIFOServiceLoopThread->start((void * (*)(void*))FIFOServiceLoopAdapter,(void*) this);
+ mTxServiceLoopThread->start((void * (*)(void*))TxServiceLoopAdapter,(void*) this);
+ mRxServiceLoopThread->start((void * (*)(void*))RxServiceLoopAdapter,(void*) this);
mTransmitPriorityQueueServiceLoopThread->start((void * (*)(void*))TransmitPriorityQueueServiceLoopAdapter,(void*) this);
writeClockInterface();
@@ -768,11 +770,9 @@ void Transceiver::driveTransmitFIFO()
pushRadioVector(mTransmitDeadlineClock);
mTransmitDeadlineClock.incTN();
}
-
}
- // FIXME -- This should not be a hard spin.
- // But any delay here causes us to throw omni_thread_fatal.
- //else radioClock->wait();
+
+ radioClock->wait();
}
@@ -789,17 +789,22 @@ void Transceiver::writeClockInterface()
mLastClockUpdateTime = mTransmitDeadlineClock;
-}
-
-
-
+}
-void *FIFOServiceLoopAdapter(Transceiver *transceiver)
+void *RxServiceLoopAdapter(Transceiver *transceiver)
{
transceiver->setPriority();
while (1) {
transceiver->driveReceiveFIFO();
+ pthread_testcancel();
+ }
+ return NULL;
+}
+
+void *TxServiceLoopAdapter(Transceiver *transceiver)
+{
+ while (1) {
transceiver->driveTransmitFIFO();
pthread_testcancel();
}
diff --git a/Transceiver52M/Transceiver.h b/Transceiver52M/Transceiver.h
index 3175213..3e4f784 100644
--- a/Transceiver52M/Transceiver.h
+++ b/Transceiver52M/Transceiver.h
@@ -56,7 +56,8 @@ private:
VectorFIFO* mTransmitFIFO; ///< radioInterface FIFO of transmit bursts
VectorFIFO* mReceiveFIFO; ///< radioInterface FIFO of receive bursts
- Thread *mFIFOServiceLoopThread; ///< thread to push/pull bursts into transmit/receive FIFO
+ Thread *mRxServiceLoopThread; ///< thread to pull bursts into receive FIFO
+ Thread *mTxServiceLoopThread; ///< thread to push bursts into transmit FIFO
Thread *mControlServiceLoopThread; ///< thread to process control messages from GSM core
Thread *mTransmitPriorityQueueServiceLoopThread;///< thread to process transmit bursts from GSM core
@@ -191,7 +192,9 @@ protected:
*/
bool driveTransmitPriorityQueue();
- friend void *FIFOServiceLoopAdapter(Transceiver *);
+ friend void *RxServiceLoopAdapter(Transceiver *);
+
+ friend void *TxServiceLoopAdapter(Transceiver *);
friend void *ControlServiceLoopAdapter(Transceiver *);
@@ -204,8 +207,9 @@ protected:
};
-/** FIFO thread loop */
-void *FIFOServiceLoopAdapter(Transceiver *);
+/** Main drive threads */
+void *RxServiceLoopAdapter(Transceiver *);
+void *TxServiceLoopAdapter(Transceiver *);
/** control message handler thread loop */
void *ControlServiceLoopAdapter(Transceiver *);