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?
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)