[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] r7640 - in usrp2/trunk/host: . apps lib
From: |
eb |
Subject: |
[Commit-gnuradio] r7640 - in usrp2/trunk/host: . apps lib |
Date: |
Mon, 11 Feb 2008 23:15:24 -0700 (MST) |
Author: eb
Date: 2008-02-11 23:15:24 -0700 (Mon, 11 Feb 2008)
New Revision: 7640
Added:
usrp2/trunk/host/apps/rx_streaming_samples.cc
Modified:
usrp2/trunk/host/apps/
usrp2/trunk/host/apps/Makefile.am
usrp2/trunk/host/configure.ac
usrp2/trunk/host/lib/gri_ethernet.cc
Log:
work-in-progress on streaming samples
Property changes on: usrp2/trunk/host/apps
___________________________________________________________________
Name: svn:ignore
- *-stamp
*.a
*.bin
*.dump
*.log
*.rom
.deps
.libs
Makefile
Makefile.in
aclocal.m4
autom4te.cache
blink_leds
blink_leds2
build
compile
config.h
config.h.in
config.log
config.status
configure
depcomp
eth_test
gen_eth_packets
ibs_rx_test
ibs_tx_test
install-sh
libtool
ltmain.sh
missing
py-compile
rcv_eth_packets
run_tests.sh
stamp-h1
test1
test_phy_comm
timer_test
buf_ram_test
buf_ram_zero
hello
find_usrps
rx_samples
tx_samples
gen_const
samples.dat
u2_burn_mac_addr
+ *-stamp
*.a
*.bin
*.dump
*.log
*.rom
.deps
.libs
Makefile
Makefile.in
aclocal.m4
autom4te.cache
blink_leds
blink_leds2
build
compile
config.h
config.h.in
config.log
config.status
configure
depcomp
eth_test
gen_eth_packets
ibs_rx_test
ibs_tx_test
install-sh
libtool
ltmain.sh
missing
py-compile
rcv_eth_packets
run_tests.sh
stamp-h1
test1
test_phy_comm
timer_test
buf_ram_test
buf_ram_zero
hello
find_usrps
rx_samples
tx_samples
gen_const
samples.dat
u2_burn_mac_addr
rx_streaming_samples
Modified: usrp2/trunk/host/apps/Makefile.am
===================================================================
--- usrp2/trunk/host/apps/Makefile.am 2008-02-12 03:52:46 UTC (rev 7639)
+++ usrp2/trunk/host/apps/Makefile.am 2008-02-12 06:15:24 UTC (rev 7640)
@@ -24,12 +24,14 @@
bin_PROGRAMS = \
find_usrps \
rx_samples \
+ rx_streaming_samples \
tx_samples \
gen_const \
u2_burn_mac_addr
find_usrps_SOURCES = find_usrps.cc
rx_samples_SOURCES = rx_samples.cc
+rx_streaming_samples_SOURCES = rx_streaming_samples.cc
tx_samples_SOURCES = tx_samples.cc
gen_const_SOURCES = gen_const.cc
u2_burn_mac_addr = u2_burn_mac_addr.cc
Copied: usrp2/trunk/host/apps/rx_streaming_samples.cc (from rev 7638,
usrp2/trunk/host/apps/rx_samples.cc)
===================================================================
--- usrp2/trunk/host/apps/rx_streaming_samples.cc
(rev 0)
+++ usrp2/trunk/host/apps/rx_streaming_samples.cc 2008-02-12 06:15:24 UTC
(rev 7640)
@@ -0,0 +1,380 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 Free Software Foundation, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "usrp2_basic.h"
+#include <iostream>
+#include <complex>
+#include <getopt.h>
+#include <string.h>
+#include "strtod_si.h"
+#include <signal.h>
+#include <stdexcept>
+#include "gri_if_stats.h"
+#include <gr_realtime.h>
+#include <gr_buffer.h>
+#include <omnithread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+
+
+typedef std::complex<float> fcomplex;
+
+static volatile bool signaled = false;
+static volatile bool stop_writer = false;
+
+static void
+sig_handler(int sig)
+{
+ signaled = true;
+ stop_writer = true;
+}
+
+static void
+install_sig_handler(int signum,
+ void (*new_handler)(int))
+{
+ struct sigaction new_action;
+ memset (&new_action, 0, sizeof (new_action));
+
+ new_action.sa_handler = new_handler;
+ sigemptyset (&new_action.sa_mask);
+ new_action.sa_flags = 0;
+
+ if (sigaction (signum, &new_action, 0) < 0){
+ perror ("sigaction (install new)");
+ throw std::runtime_error ("sigaction");
+ }
+}
+
+// ------------------------------------------------------------------------
+
+
+class ringbuffer {
+public:
+ gr_buffer_sptr d_writer;
+ gr_buffer_reader_sptr d_reader;
+ omni_semaphore d_not_full;
+ omni_semaphore d_not_empty;
+
+ ringbuffer(size_t nsamples);
+ bool touch_and_mlock();
+};
+
+ringbuffer::ringbuffer(size_t nsamples)
+{
+ d_writer = gr_make_buffer(nsamples, sizeof(uint32_t));
+ d_reader = gr_buffer_add_reader(d_writer, 0);
+}
+
+bool
+ringbuffer::touch_and_mlock()
+{
+ size_t pagesize = 4096;
+
+ uint32_t *p = (uint32_t *) d_writer->write_pointer();
+ for (int i = 0; i < d_writer->space_available(); i += pagesize /
sizeof(uint32_t))
+ p[i] = 0;
+
+ int r = mlockall(MCL_CURRENT | MCL_FUTURE);
+ if (r == -1){
+ perror("mlockall");
+ return false;
+ }
+ return true;
+}
+
+typedef boost::shared_ptr<ringbuffer> ringbuffer_sptr;
+
+// ------------------------------------------------------------------------
+
+class file_writer : public omni_thread
+{
+public:
+ int d_fd;
+ ringbuffer_sptr d_rb;
+
+ file_writer(int fd, ringbuffer_sptr ringbuffer)
+ : d_fd(fd), d_rb(ringbuffer){
+ }
+
+ /*
+ * Invokes the top-level of the new thread (name kind of sucks);
+ */
+ void *run_undetached(void *arg);
+};
+
+void *
+file_writer::run_undetached(void *ignored)
+{
+ while (1){
+ int navail_samples = d_rb->d_reader->items_available();
+
+ if (navail_samples == 0){
+ if (stop_writer)
+ return 0;
+ else {
+ d_rb->d_not_empty.wait();
+ continue;
+ }
+ }
+
+ ::write(d_fd, d_rb->d_reader->read_pointer(), navail_samples *
sizeof(uint32_t));
+ d_rb->d_reader->update_read_pointer(navail_samples);
+ d_rb->d_not_full.post();
+ }
+}
+
+// ------------------------------------------------------------------------
+
+
+/*
+ * Vectorize me!
+ */
+void
+convert_samples_to_complex(size_t nsamples,
+ uint32_t *i_samples,
+ fcomplex *c_samples)
+{
+ uint32_t *p = i_samples;
+ for (size_t i = 0; i < nsamples; i++){
+ int16_t si = ((int16_t) (p[i] >> 16));
+ int16_t sq = ((int16_t) (p[i] & 0xffff));
+ c_samples[i] = fcomplex((float) si, (float) sq);
+ }
+}
+
+
+static void
+usage(const char *progname)
+{
+ const char *p = strrchr(progname, '/'); // drop leading directory path
+ if (p)
+ p++;
+
+ if (strncmp(p, "lt-", 3) == 0) // drop lt- libtool prefix
+ p += 3;
+
+ fprintf(stderr, "Usage: %s [options]\n\n", p);
+ fprintf(stderr, "Options:\n");
+ fprintf(stderr, " -h show this message and exit\n");
+ fprintf(stderr, " -e ETH_INTERFACE specify ethernet interface
[default=eth0]\n");
+ fprintf(stderr, " -m MAC_ADDR mac address of USRP2 HH:HH
[default=first one found]\n");
+ fprintf(stderr, " -o OUTPUT_FILE set output filename
[default=samples.dat]\n");
+ fprintf(stderr, " -f FREQ set frequency to FREQ
[default=0]\n");
+ fprintf(stderr, " -d DECIM set decimation rate to DECIM
[default=32]\n");
+ fprintf(stderr, " -N NSAMPLES total number of samples to receive
[default=2.5e6]\n");
+ fprintf(stderr, " -F SAMPLES_PER_FRAME number of samples in each frame
[default=371]\n");
+ fprintf(stderr, " -S SCALE fpga scaling factor for I & Q
[default=256]\n");
+}
+
+struct pkt_info {
+ int d_nsamples;
+ int d_timestamp;
+ unsigned int d_seqno;
+
+ pkt_info(int nsamples, int timestamp, int seqno)
+ : d_nsamples(nsamples),
+ d_timestamp(timestamp),
+ d_seqno(seqno) {}
+};
+
+int
+main(int argc, char **argv)
+{
+
+ // options and their defaults
+ const char *interface = "eth0";
+ const char *mac_addr_str = 0;
+ const char *output_filename = "samples.dat";
+ double freq = 0;
+ int32_t decim = 32;
+ int32_t nsamples = static_cast<int32_t>(2.5e6);
+ int32_t samples_per_frame = 371;
+ int32_t scale = 256;
+
+ int ch;
+ double tmp;
+ u2_mac_addr_t mac_addr;
+
+ setvbuf(stdout, 0, _IOFBF, 64 * 1024); // make stdout fully buffered
+
+ while ((ch = getopt(argc, argv, "he:m:o:f:d:N:F:S")) != EOF){
+ switch (ch){
+
+ case 'e':
+ interface = optarg;
+ break;
+
+ case 'm':
+ mac_addr_str = optarg;
+ if (!usrp2_basic::parse_mac_addr(optarg, &mac_addr)){
+ std::cerr << "invalid mac addr: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+
+ case 'o':
+ output_filename = optarg;
+ break;
+
+ case 'f':
+ if (!strtod_si(optarg, &freq)){
+ std::cerr << "invalid number: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ break;
+
+ case 'N':
+ if (!strtod_si(optarg, &tmp)){
+ std::cerr << "invalid number: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ nsamples = static_cast<int32_t>(tmp);
+ break;
+
+ case 'F':
+ samples_per_frame = strtol(optarg, 0, 0);
+ break;
+
+ case 'd':
+ decim = strtol(optarg, 0, 0);
+ break;
+
+ case 'S':
+ if (!strtod_si(optarg, &tmp)){
+ std::cerr << "invalid number: " << optarg << std::endl;
+ usage(argv[0]);
+ exit(1);
+ }
+ scale = static_cast<int32_t>(tmp);
+ break;
+
+ case 'h':
+ default:
+ usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ if (argc - optind != 0){
+ usage(argv[0]);
+ exit(1);
+ }
+
+ size_t buffer_size = static_cast<size_t>(12.5e6);
+ //buffer_size = (buffer_size + 4095) & ~4095;
+ ringbuffer_sptr rb(new ringbuffer(buffer_size));
+
+ rb->touch_and_mlock();
+
+ int ofd = 1; // stdout
+ if (output_filename){
+ ofd = ::open(output_filename, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE,
0664);
+ if (ofd == -1){
+ perror(output_filename);
+ exit (1);
+ }
+ }
+
+ usrp2_basic *u2 = new usrp2_basic();
+
+ if (!u2->open(interface)){
+ std::cerr << "couldn't open " << interface << std::endl;
+ return 0;
+ }
+
+ install_sig_handler(SIGINT, sig_handler);
+
+ std::vector<op_id_reply_t> r = u2->find_usrps();
+
+ for (size_t i = 0; i < r.size(); i++){
+ std::cout << r[i] << std::endl;
+ }
+
+ if (r.size() == 0){
+ std::cerr << "No USRP2 found.\n";
+ return 1;
+ }
+
+ u2_mac_addr_t which = r[0].addr; // pick the first one
+
+
+ gr_rt_status_t rt = gr_enable_realtime_scheduling();
+ if (rt != RT_OK)
+ std::cerr << "failed to enable realtime scheduling\n";
+
+
+ // create writer thread
+ class file_writer *writer = new file_writer(ofd, rb);
+ writer->start_undetached();
+
+
+ if (!u2->start_rx(which, freq, decim, nsamples, samples_per_frame, scale,
scale)){
+ std::cerr << "start_rx failed\n";
+ return 1;
+ }
+
+
+ long total_samples_recvd = 0;
+
+ while (!signaled && total_samples_recvd < nsamples){
+ u2_eth_samples_t pkt;
+
+ // read samples
+ int n = u2->read_samples(which, &pkt);
+ if (n <= 0)
+ break;
+
+ total_samples_recvd += n;
+
+ // copy the samples into the ring buffer as soon as there's room
+
+ while (rb->d_writer->space_available() < n)
+ rb->d_not_full.wait();
+
+ memcpy(rb->d_writer->write_pointer(),
+ pkt.samples,
+ n * sizeof(uint32_t));
+
+ rb->d_writer->update_write_pointer(n);
+ rb->d_not_empty.post();
+ }
+
+ stop_writer = true;
+ // smp_wmb()
+ rb->d_not_empty.post(); // wake up file writer
+
+ if (!u2->stop_rx(which)){
+ std::cerr << "stop_rx failed\n";
+ return 1;
+ }
+
+ void *ignored_result;
+ writer->join(&ignored_result);
+
+ return 0;
+}
Modified: usrp2/trunk/host/configure.ac
===================================================================
--- usrp2/trunk/host/configure.ac 2008-02-12 03:52:46 UTC (rev 7639)
+++ usrp2/trunk/host/configure.ac 2008-02-12 06:15:24 UTC (rev 7640)
@@ -115,7 +115,7 @@
dnl AC_CHECK_HEADERS(linux/ppdev.h sys/mman.h sys/select.h sys/types.h)
dnl AC_CHECK_HEADERS(sys/resource.h stdint.h sched.h signal.h sys/syscall.h)
-AC_CHECK_HEADERS(arpa/inet.h netinet/in.h byteswap.h sys/select.h)
+AC_CHECK_HEADERS(arpa/inet.h netinet/in.h byteswap.h sys/select.h
linux/if_packet.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
Modified: usrp2/trunk/host/lib/gri_ethernet.cc
===================================================================
--- usrp2/trunk/host/lib/gri_ethernet.cc 2008-02-12 03:52:46 UTC (rev
7639)
+++ usrp2/trunk/host/lib/gri_ethernet.cc 2008-02-12 06:15:24 UTC (rev
7640)
@@ -35,6 +35,9 @@
#include <linux/types.h>
#include <linux/filter.h> // packet filter
+#ifdef HAVE_LINUX_IF_PACKET_H
+#include <linux/if_packet.h> // circular buffer defs for PF_PACKET
+#endif
static int
open_packet_socket (std::string ifname, int protocol)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Commit-gnuradio] r7640 - in usrp2/trunk/host: . apps lib,
eb <=