How do I access the data from rp_remote_acquire?

770 Views Asked by At

I currently have a python program that (very slowly) recieves data from a Red Pitaya board by recursively calling: redpitaya_scpi.scpi(192.169.1.100).rx_txt()

I would like to use rp_remote_acquire to achieve a higher throughput with a ring buffer.

I am able to execute ./rp_remote_acquire on both the Red Pitaya (server) and a linux machine (client) thanks to stackoverflow.

I get some unique content in /tmp/out every time I execute the following commands on the Red Pitaya (which suggests that the program on the server has access to the data from its hardware).

rm /tmp/out
./rp_remote_acquire -m 3
cat /tmp/out

In order to transfer data from the Red Pitaya (client) to the linux machine (server), I launch ./rp_remote_acquire with the following parameters:

Server (192.169.1.100): ./rp_remote_acquire -m 2 -a 192.169.1.102 -p 14000

Client (192.169.1.102): ./rp_remote_acquire -m 1 -a 192.169.1.100 -p 14000

Where:

-m  --mode <(1|client)|(2|server)|(3|file)>
        operating mode (default client)

-a  --address <ip_address>
        target address in client mode (default empty)

-p  --port <port_num>
        port number in client and server mode (default 14000)

Both machines are able ping eachother and the machines are able to establish a connection (ie. int connection_start(option_fields_t *options, struct handles *handles) at transfer.c:251 returns zero).

The client ends up executing the following code snippet from transfer.c

533     while (!size || transferred < size) {
(gdb) n
534         if (pos == buf_size)
(gdb) n
539         if (pos + CHUNK <= curr) {
(gdb) n
552         memcpy(buf, mapped_base + pos, len);
(gdb) n
554         if (handles->sock >= 0) {
(gdb) n
552         memcpy(buf, mapped_base + pos, len);
(gdb) n
554         if (handles->sock >= 0) {
(gdb) n
555             if (send_buffer(handles->sock, options, buf, len) < 0) {
(gdb) n
569         pos += len;
(gdb) n
533     while (!size || transferred < size) {

It seems like the client is effectively just doing the following (note size = 0 by default):

533     while (!size || transferred < size) {
552         memcpy(buf, mapped_base + pos, len);
552         memcpy(buf, mapped_base + pos, len);
569         pos += len;
        }

This behaviour seems to be the intention of the programmer because the client stops as soon as the server is halted:

554         if (handles->sock >= 0) {
(gdb) 
556                 if (!interrupted)

the program doesn't get stuck in this loop when I change size such that it is not equal to zero (=> smaller packets?).

I would like to be able to access the data that is (hopefully) being sent from the Red Pitaya (server) to the linux machine (client) and somehow make this data available to a python program on the client machine.

My question(s):

  • What is going on here and how can I access the data?

  • Do I need to synchronously run a second program on the client that somehow reads the data that rp_remote_acquire is copying into the clients memory?

1

There are 1 best solutions below

0
On BEST ANSWER

The solution is surprisingly simple.

When it is running properly in server mode, rp_remote_acquire writes the data to a socket:

/*
 * transfers samples to socket via read() call on rpad_scope
 */
static u_int64_t transfer_readwrite(struct scope_parameter *param,
                                    option_fields_t *options, struct handles *handles)

In client mode it reads the data from the socket and does something with it.

Since we are working with sockets here, we don't need to care what rp_remote_acquire does in client mode. We can simply create our own socket with a python script and recieve the data in the script (which is where I want to have the data).

This is an example from @otobrzo:

import socket
import numpy as np
import matplotlib.pyplot as plt


client  = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

ip=socket.gethostbyname("XX.XX.XX.XX") # IP of redpitaya in server mode: 

# run cat ddrdump.bit > /dev/xdevcfg
#compiled and run on redpitay  ./rp_remote_acquire -m 2 -k 0 -c 0 -d 0


port=14000 # default port for TCP 

address=(ip,port)
client.connect(address)  

Nl = 10000

#while True:
for x in range(0, Nl):
#    print("test1")
    bytes_data = client.recv(1024) # set the amount data transferred

    if x == 0: 
        data = np.frombuffer(bytes_data, dtype=np.int16) # from 16bit data to int16 
        data = np.array(data, dtype=float)
        data_all = data
    else: 
        data = np.frombuffer(bytes_data, dtype=np.int16) # from 16bit data to int16 
        data = np.array(data, dtype=float)  
        data_all= np.hstack((data_all,data)) 

#%%
FPS = 125e6        
time = np.arange(0,np.size(data_all))/FPS

plt.plot(time,data_all)