提交 9e159a6f 编写于 作者: M manjaro

Add stdout redirect

上级 8036b7b5
......@@ -113,7 +113,7 @@ static inline quint64 time_ms(void)
CPlotter::CPlotter(QWidget *parent)
: QFrame(parent)
, m_maxSize(1920,1080)
, m_maxSize(1024,768)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setFocusPolicy(Qt::StrongFocus);
......
......@@ -12,7 +12,8 @@ specWidget::specWidget(QWidget *parent) :
m_attenMod(new QStandardItemModel(this)),
m_runth(new uhd_io_thread(this)),
m_saveth(new uhd_io_thread(this)),
m_bSaveToFile(false)
m_bSaveToFile(false),
watcher(new stdout_watcher(this))
{
ui->setupUi(this);
Bookmarks::create();
......@@ -47,15 +48,15 @@ specWidget::specWidget(QWidget *parent) :
connect (ui->plotter,&CPlotter::pandapterRangeChanged,this, &specWidget::evt_pandapterRangeChanged);
connect (ui->plotter,&CPlotter::newZoomLevel,this, &specWidget::evt_newZoomLevel);
connect (ui->freqCtrl,&CFreqCtrl::newFrequency,this, &specWidget::setCenterFreq);
connect (watcher,&stdout_watcher::evt_stdata,this,&specWidget::slot_msg,Qt::QueuedConnection);
loadSettings();
watcher->start();
}
specWidget::~specWidget()
{
freeFFT();
watcher->stop_and_wait();
delete ui;
}
......@@ -75,6 +76,11 @@ void specWidget::slot_newDemodFreq(qint64 freq, qint64 delta)/* delta is the off
}
void specWidget::slot_msg(QByteArray s, bool bStdErr)
{
ui->plainTextEdit_msg->appendPlainText(s);
}
void specWidget::setNewFftData(const double * rfftData, int size)
{
ui->plotter->setNewFftData(rfftData,size);
......@@ -285,6 +291,10 @@ void specWidget::loadSettings()
const int spinBox_gain = settings.value("spectrum/spinBox_gain",0).toInt();
ui->spinBox_gain->setValue(spinBox_gain);
const int spinBox_bw = settings.value("spectrum/spinBox_bw",200).toInt();
ui->spinBox_bw->setValue(spinBox_bw);
const double doubleSpinBox_range_max = settings.value("spectrum/doubleSpinBox_range_max",0).toInt();
ui->doubleSpinBox_range_max->setValue(doubleSpinBox_range_max);
......@@ -313,6 +323,8 @@ void specWidget::saveSettings()
settings.setValue("spectrum/comboBox_atn",comboBox_atn);
const int spinBox_gain = ui->spinBox_gain->value();
settings.setValue("spectrum/spinBox_gain",spinBox_gain);
const int spinBox_bw = ui->spinBox_bw->value();
settings.setValue("spectrum/spinBox_bw",spinBox_bw);
const int spinBox_chan = ui->spinBox_chan->value();
settings.setValue("spectrum/spinBox_chan",spinBox_chan);
const double doubleSpinBox_range_max = ui->doubleSpinBox_range_max->value();
......@@ -381,11 +393,18 @@ void specWidget::resetFFT()
int updateIntelv = 1000.0 /ui->spinBox_fftUpdate->value() + .5;
m_channel = ui->spinBox_chan->value();
//watcher->m_bStop = false;
//watcher->start(QThread::HighPriority);
if (!usrp)
{
open_device();
}
if (!usrp)
{
//watcher->stop_and_wait();
return;
}
//开始
setSampleRate(getSampleRate());
......@@ -395,7 +414,6 @@ void specWidget::resetFFT()
usrp->set_rx_antenna(atn.toStdString(),m_channel);
on_spinBox_gain_valueChanged(ui->spinBox_gain->value());
m_runth->setRunner([&](void){
run_IO();
});
......@@ -449,6 +467,8 @@ void specWidget::resetFFT()
if (fOut.isOpen())
fOut.close();
});
//End watch
//watcher->stop_and_wait();
m_runth->start();
m_saveth->start();
m_nTimerID = startTimer(updateIntelv);
......
......@@ -29,6 +29,7 @@
#include <vector>
#include <QStandardItemModel>
#include "uhd_device.h"
#include "stdout_watcher.h"
namespace Ui {
class specWidget;
}
......@@ -56,6 +57,7 @@ signals:
void evt_newCtrlFreq(qint64);
public slots:
void slot_newDemodFreq(qint64 freq, qint64 delta); /* delta is the offset from the center */
void slot_msg(QByteArray , bool);
public:
void appendWavComplex(const double (* pWav)[2], const int count, double voltage_ref = 16384);
public:
......@@ -94,23 +96,14 @@ private slots:
void on_pushButton_reset_clicked();
void on_doubleSpinBox_center_2_valueChanged(double arg1);
void on_comboBox_fftSize_activated(int index);
void on_doubleSpinBox_center_valueChanged(double arg1);
void on_spinBox_gain_valueChanged(int arg1);
void on_doubleSpinBox_range_max_valueChanged(double arg1);
void on_doubleSpinBox_range_min_valueChanged(double arg1);
void on_comboBox_atn_currentIndexChanged(const QString &arg1);
void on_spinBox_chan_valueChanged(int arg1);
void on_toolButton_br_clicked();
void on_checkBox_save_stateChanged(int arg1);
void on_spinBox_bw_valueChanged(int arg1);
private:
......@@ -137,6 +130,8 @@ private:
std::atomic<long long> save_count;
std::atomic<bool> m_bSaveToFile;
QString m_strFolder;
//stdout reader
stdout_watcher * watcher = nullptr;
};
#endif // SPECWIDGET_H
......@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>793</width>
<height>466</height>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
......@@ -15,19 +15,7 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
......@@ -237,43 +225,18 @@
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>370</height>
<width>310</width>
<height>450</height>
</rect>
</property>
<attribute name="label">
<string>Radio</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="7" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>289</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_dev"/>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_spr">
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>0.000001000000000</double>
</property>
<property name="maximum">
<double>1024.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Device</string>
</property>
</widget>
</item>
......@@ -293,20 +256,20 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_gain"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Gain</string>
<string>Antenna</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="spinBox_gain"/>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_chan">
<property name="maximum">
<number>1</number>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Center Freq(Mhz)</string>
</property>
</widget>
</item>
......@@ -317,31 +280,40 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Sample Rate(Mhz)</string>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_chan">
<property name="maximum">
<number>1</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Center Freq(Mhz)</string>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="doubleSpinBox_spr">
<property name="decimals">
<number>6</number>
</property>
<property name="minimum">
<double>0.000001000000000</double>
</property>
<property name="maximum">
<double>1024.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<item row="6" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Device</string>
<string>BW(Khz)</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_10">
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Antenna</string>
<string>Sample Rate(Mhz)</string>
</property>
</widget>
</item>
......@@ -352,17 +324,13 @@
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>BW(Khz)</string>
</property>
</widget>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_dev"/>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="spinBox_bw">
<property name="minimum">
<number>2</number>
<number>200</number>
</property>
<property name="maximum">
<number>200000</number>
......@@ -370,8 +338,31 @@
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>1000</number>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Gain</string>
</property>
</widget>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_view">
......@@ -379,14 +370,83 @@
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>370</height>
<width>310</width>
<height>165</height>
</rect>
</property>
<attribute name="label">
<string>View</string>
</attribute>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Ref Max</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="spinBox_fftUpdate">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QDoubleSpinBox" name="doubleSpinBox_range_max">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-150.000000000000000</double>
</property>
<property name="maximum">
<double>30.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Ref Min</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QDoubleSpinBox" name="doubleSpinBox_range_min">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-300.000000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>-150.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Update Interval</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
......@@ -454,76 +514,7 @@
</item>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Update Interval</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QSpinBox" name="spinBox_fftUpdate">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>30</number>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Ref Max</string>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QDoubleSpinBox" name="doubleSpinBox_range_max">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-150.000000000000000</double>
</property>
<property name="maximum">
<double>30.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Ref Min</string>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QDoubleSpinBox" name="doubleSpinBox_range_min">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-300.000000000000000</double>
</property>
<property name="maximum">
<double>0.000000000000000</double>
</property>
<property name="singleStep">
<double>1.000000000000000</double>
</property>
<property name="value">
<double>-150.000000000000000</double>
</property>
</widget>
</item>
<item row="4" column="1" colspan="2">
<item row="4" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
......@@ -531,20 +522,48 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="log">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>310</width>
<height>450</height>
</rect>
</property>
<attribute name="label">
<string>Log</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit_msg">
<property name="lineWrapMode">
<enum>QPlainTextEdit::NoWrap</enum>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="plainText">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="save">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>370</height>
<width>310</width>
<height>450</height>
</rect>
</property>
<attribute name="label">
......
#include "stdout_watcher.h"
#include <stdio.h>
#include <thread>
#ifdef __GNUC__
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
stdout_watcher::stdout_watcher(QObject *parent) : QThread(parent),
m_bStop(false)
{
}
void stdout_watcher::stop_and_wait()
{
m_bStop = true;
wait();
}
#ifdef __GNUC__
void stdout_watcher::run()
{
auto pt = [&](FILE * stda,bool stderrb)->void{
int stdout_bk; //is fd for stdout backup
stdout_bk = dup(fileno(stda));
int pfd_stdout[2];
pipe2(pfd_stdout,O_NONBLOCK); // O_NONBLOCK);
// What used to be stdout will now go to the pipe.
dup2(pfd_stdout[1], fileno(stda));
while (!m_bStop)
{
char buf[1024];
int red = 0;
if ((red = read(pfd_stdout[0], buf, 1024)) >0 )
emit evt_stdata(QByteArray(buf,red),stderrb);
else
msleep(10);
}
close(pfd_stdout[1]);
close(pfd_stdout[0]);
dup2(stdout_bk, fileno(stda));//restore
};
std::thread t1(pt, stderr,true);
//std::thread t2(pt, stdout,false);
t1.join();
//t2.join();
}
#endif
#ifndef STDOUT_WATCHER_H
#define STDOUT_WATCHER_H
#include <QThread>
#include <atomic>
class stdout_watcher : public QThread
{
Q_OBJECT
public:
explicit stdout_watcher(QObject *parent = nullptr);
void run() override;
void stop_and_wait();
signals:
void evt_stdata(QByteArray,bool stderrb);
public:
std::atomic<bool> m_bStop;
};
#endif // STDOUT_WATCHER_H
#include "uhd_device.h"
#include <QThread>
#include <QCoreApplication>
using uhd::tune_request_t;
using uhd::tx_streamer;
using uhd::usrp::multi_usrp;
......@@ -80,7 +81,27 @@ std::string uhd_device::devArgs() const
bool uhd_device::open_device()
{
string ref = "internal";
usrp = multi_usrp::make(m_dev_args);
std::atomic<bool> finished(false);
std::thread thr([&]()->void{
try{
usrp = multi_usrp::make(m_dev_args);
}
catch (...)
{
fprintf (stderr,"Error in USRP init.\n");
}
finished = true;
});
while (!finished)
{
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
QThread::msleep(20);
}
thr.join();
if (!usrp)
return false;
usrp->set_clock_source(ref,multi_usrp::ALL_MBOARDS);
......@@ -122,21 +143,26 @@ void uhd_device::run_IO()
stream_cmd.time_spec = uhd::time_spec_t();
streaming = true;
rx_stream->issue_stream_cmd(stream_cmd);
while (!stop_signal_called)
{
vec_buffersz[rx_count % bufsz] = rx_stream->recv((void *)(vec_buffer[rx_count % bufsz].get()),m_spb_size,md_rx,0.1,false);
//md_rx可以读取时戳
vec_buffer_tm[rx_count % bufsz] = md_rx.time_spec;
++rx_count;
if (md_rx.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
fputs("Time out.",stderr);
else if (md_rx.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW)
fputs("Over flow",stderr);
else if (md_rx.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE)
try {
while (!stop_signal_called)
{
cerr << "Receiver error: "<< md_rx.strerror() << endl ;
stop_signal_called = true;
vec_buffersz[rx_count % bufsz] = rx_stream->recv((void *)(vec_buffer[rx_count % bufsz].get()),m_spb_size,md_rx,0.1,false);
//md_rx可以读取时戳
vec_buffer_tm[rx_count % bufsz] = md_rx.time_spec;
++rx_count;
if (md_rx.error_code == uhd::rx_metadata_t::ERROR_CODE_TIMEOUT)
fputs("Time out.",stderr);
else if (md_rx.error_code == uhd::rx_metadata_t::ERROR_CODE_OVERFLOW)
fputs("Over flow",stderr);
else if (md_rx.error_code != uhd::rx_metadata_t::ERROR_CODE_NONE)
{
cerr << "Receiver error: "<< md_rx.strerror() << endl ;
stop_signal_called = true;
}
}
} catch (...) {
stop_signal_called = true;
}
stream_cmd.stream_now = false;
rx_stream->issue_stream_cmd(stream_cmd);
......@@ -144,11 +170,11 @@ void uhd_device::run_IO()
};
//启动线程
uhd_io_thread * rx_thread = new uhd_io_thread(thcall_rx,0);
rx_thread->start(QThread::HighestPriority);
rx_thread->start(QThread::TimeCriticalPriority);
//主线程不断打印状态
while (!stop_signal_called)
{
cerr<<"RX" << rx_count<<"\r";
//cerr<<"RX" << rx_count<<"\r";
std::this_thread::sleep_for(std::chrono::milliseconds(400));
}
//退出
......
......@@ -23,6 +23,7 @@ SOURCES += \
qtgui/meter.cpp \
qtgui/plotter.cpp \
specwidget.cpp \
stdout_watcher.cpp \
uhd_device.cpp
HEADERS += \
......@@ -33,6 +34,7 @@ HEADERS += \
qtgui/meter.h \
qtgui/plotter.h \
specwidget.h \
stdout_watcher.h \
uhd_device.h
FORMS += \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册