Compare commits
6 Commits
9f43e07e44
...
old_master
| Author | SHA1 | Date | |
|---|---|---|---|
|
4eb2da17ab
|
|||
|
c8dd8553ba
|
|||
|
21038c1f8e
|
|||
|
11cf03910b
|
|||
|
613fdb998f
|
|||
|
d0578a0c0d
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
*.csv
|
||||
*.tmp
|
||||
build
|
||||
BF_companion
|
||||
BIN
BF_companion
BIN
BF_companion
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build/main.o
BIN
build/main.o
Binary file not shown.
@ -1 +0,0 @@
|
||||
../BFfirmware_0/build/release/bin/l502-BFfirmware0.ldr
|
||||
BIN
l502-BFfirmware0.ldr
Normal file
BIN
l502-BFfirmware0.ldr
Normal file
Binary file not shown.
10
long_trace_AVG_RPI.cmd
Normal file
10
long_trace_AVG_RPI.cmd
Normal file
@ -0,0 +1,10 @@
|
||||
// Default configuration for BF_companion main_state
|
||||
// Format: field value // optional comment
|
||||
|
||||
run_mode INF_RUN // TEST | FINITE_RUN | INF_RUN
|
||||
BF_mode FFT // TRANSPARENT | AVG | FFT
|
||||
run_length 50 // milliseconds
|
||||
runs_N 1000 // total runs (used in FINITE_RUN)
|
||||
run_I 0 // starting run index
|
||||
//data_path /home/feda/MIPT/RadioPhotonic_Subserface_radar/Receiver_GUI/data // base directory for output files
|
||||
data_path tmp
|
||||
239
main.c
239
main.c
@ -59,10 +59,6 @@
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@ -173,9 +169,6 @@ typedef struct main_state_typedef{
|
||||
uint32_t run_I; // № current run
|
||||
uint32_t runs_N; // total number of runs
|
||||
char data_path[200]; // base directory for data files
|
||||
char pipe_path[200]; // path to named pipe (FIFO) for streaming data
|
||||
int pipe_fd; // file descriptor for the pipe
|
||||
int save_to_files; // flag: save data to files (0=false, 1=true)
|
||||
} main_state;
|
||||
|
||||
static void main_state_set_defaults(main_state* st) {
|
||||
@ -187,10 +180,6 @@ static void main_state_set_defaults(main_state* st) {
|
||||
st->runs_N = 1;
|
||||
strncpy(st->data_path, "data", sizeof(st->data_path));
|
||||
st->data_path[sizeof(st->data_path)-1] = '\0';
|
||||
strncpy(st->pipe_path, "/tmp/radar_data_pipe", sizeof(st->pipe_path));
|
||||
st->pipe_path[sizeof(st->pipe_path)-1] = '\0';
|
||||
st->pipe_fd = -1;
|
||||
st->save_to_files = 0; // default: false
|
||||
}
|
||||
|
||||
static char* f_trim(char* s) {
|
||||
@ -265,15 +254,6 @@ static void parse_cmd_file(const char* filename, main_state* st) {
|
||||
} else if (strcmp(field, "data_path") == 0) {
|
||||
strncpy(st->data_path, value, sizeof(st->data_path));
|
||||
st->data_path[sizeof(st->data_path)-1] = '\0';
|
||||
} else if (strcmp(field, "pipe_path") == 0) {
|
||||
strncpy(st->pipe_path, value, sizeof(st->pipe_path));
|
||||
st->pipe_path[sizeof(st->pipe_path)-1] = '\0';
|
||||
} else if (strcmp(field, "save_to_files") == 0) {
|
||||
if (strcmp(value, "true") == 0 || strcmp(value, "1") == 0) {
|
||||
st->save_to_files = 1;
|
||||
} else if (strcmp(value, "false") == 0 || strcmp(value, "0") == 0) {
|
||||
st->save_to_files = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
@ -387,7 +367,6 @@ static t_x502_hnd f_dev_select_open(int argc, char** argv) {
|
||||
fnd_devcnt = f_get_all_devrec(&devrec_list, ip_dev_list, ip_cnt);
|
||||
|
||||
if (fnd_devcnt == 0) {
|
||||
|
||||
printf("Не найдено ни одного модуля\n");
|
||||
} else {
|
||||
// выводим информацию по списку модулей //
|
||||
@ -715,159 +694,9 @@ void insert_marker_to_file(char* logfilename, char* marker_text){
|
||||
fclose(logfile_ptr);
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
// Function to check if pipe reader is present and ready
|
||||
// Returns: 1 if ready to write, 0 if should wait, -1 on error
|
||||
int check_pipe_ready(int pipe_fd) {
|
||||
if (pipe_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct pollfd pfd;
|
||||
pfd.fd = pipe_fd;
|
||||
pfd.events = POLLOUT;
|
||||
pfd.revents = 0;
|
||||
|
||||
// Check with 0 timeout (non-blocking check)
|
||||
int ret = poll(&pfd, 1, 0);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error polling pipe: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
// Timeout - pipe buffer is full, reader is slow or absent
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
||||
if (pfd.revents & POLLERR) {
|
||||
fprintf(stderr, "Pipe error detected\n");
|
||||
}
|
||||
if (pfd.revents & POLLHUP) {
|
||||
fprintf(stderr, "Pipe hangup - reader disconnected\n");
|
||||
}
|
||||
if (pfd.revents & POLLNVAL) {
|
||||
fprintf(stderr, "Invalid pipe fd\n");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// POLLOUT is set - ready to write
|
||||
if (pfd.revents & POLLOUT) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Function to wait for pipe to become ready
|
||||
// Returns: 1 if ready, 0 if interrupted, -1 on error
|
||||
int wait_for_pipe_reader(int pipe_fd) {
|
||||
if (pipe_fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Waiting for pipe reader to become ready...\n");
|
||||
|
||||
struct pollfd pfd;
|
||||
pfd.fd = pipe_fd;
|
||||
pfd.events = POLLOUT;
|
||||
|
||||
while (1) {
|
||||
pfd.revents = 0;
|
||||
|
||||
// Wait with 1 second timeout
|
||||
int ret = poll(&pfd, 1, 1000);
|
||||
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR) {
|
||||
// Interrupted by signal, continue
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "Error waiting for pipe: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
// Timeout - print status and continue waiting
|
||||
printf("Still waiting for pipe reader...\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for errors
|
||||
if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
|
||||
fprintf(stderr, "Pipe error while waiting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Ready to write
|
||||
if (pfd.revents & POLLOUT) {
|
||||
printf("Pipe reader is ready!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function to initialize named pipe (FIFO)
|
||||
int init_pipe(const char* pipe_path) {
|
||||
// Remove existing pipe if it exists
|
||||
unlink(pipe_path);
|
||||
|
||||
// Create named pipe with read/write permissions
|
||||
if (mkfifo(pipe_path, 0666) != 0) {
|
||||
if (errno != EEXIST) {
|
||||
fprintf(stderr, "Error creating pipe %s: %s\n", pipe_path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Named pipe created: %s\n", pipe_path);
|
||||
|
||||
// Try to open in non-blocking mode first to check if reader is present
|
||||
int fd = open(pipe_path, O_WRONLY | O_NONBLOCK);
|
||||
if (fd < 0) {
|
||||
if (errno == ENXIO) {
|
||||
// No reader present, try blocking mode
|
||||
printf("No reader detected. Waiting for reader to connect...\n");
|
||||
printf("(You can start the reader program now, e.g.: ./pipe_reader_test.py)\n");
|
||||
|
||||
// Open in blocking mode - will wait for reader
|
||||
fd = open(pipe_path, O_WRONLY);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Error opening pipe for writing: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
printf("Reader connected!\n");
|
||||
} else {
|
||||
fprintf(stderr, "Warning: Could not open pipe for writing: %s\n", strerror(errno));
|
||||
fprintf(stderr, "Pipe will be skipped. Data will only be saved to file.\n");
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
printf("Reader already connected!\n");
|
||||
// Set back to blocking mode for writes
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
|
||||
}
|
||||
|
||||
printf("Pipe opened successfully (fd=%d)\n", fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
// Function to close pipe
|
||||
void close_pipe(int pipe_fd, const char* pipe_path) {
|
||||
if (pipe_fd >= 0) {
|
||||
close(pipe_fd);
|
||||
unlink(pipe_path);
|
||||
printf("Pipe closed and removed\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words, uint32_t timeout, int pipe_fd){
|
||||
void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint32_t max_total_words, uint32_t timeout){
|
||||
|
||||
|
||||
|
||||
@ -876,7 +705,7 @@ void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint
|
||||
// fprintf(logfile_ptr, "0xFF00000 \n");
|
||||
|
||||
// uint32_t timeout = 100;
|
||||
uint32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, timeout);
|
||||
int32_t recv_Err_code = X502_Recv(hnd, inp_buff, max_total_words, timeout);
|
||||
printf("receive code: %d\n", recv_Err_code);
|
||||
|
||||
if (recv_Err_code > 0){
|
||||
@ -894,47 +723,10 @@ void receive_to_file(t_x502_hnd hnd, char* logfilename, uint32_t* inp_buff, uint
|
||||
printf("received %ld words\n", received_words);
|
||||
fclose(logfile_ptr);
|
||||
rename(logfilename_tmp, logfilename);
|
||||
|
||||
#ifndef _WIN32
|
||||
// Write data to pipe if it's open
|
||||
if (pipe_fd >= 0) {
|
||||
// Check if pipe is ready before writing
|
||||
int pipe_status = check_pipe_ready(pipe_fd);
|
||||
|
||||
if (pipe_status == 0) {
|
||||
// Pipe not ready (buffer full or no reader) - wait for reader
|
||||
printf("Pipe not ready - waiting for reader to catch up...\n");
|
||||
int wait_result = wait_for_pipe_reader(pipe_fd);
|
||||
if (wait_result != 1) {
|
||||
fprintf(stderr, "Warning: Could not write to pipe\n");
|
||||
return;
|
||||
}
|
||||
} else if (pipe_status < 0) {
|
||||
fprintf(stderr, "Warning: Pipe error detected, skipping pipe write\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Pipe is ready, write data
|
||||
ssize_t bytes_written = write(pipe_fd, inp_buff, received_words * sizeof(uint32_t));
|
||||
if (bytes_written < 0) {
|
||||
if (errno == EPIPE) {
|
||||
fprintf(stderr, "Warning: Broken pipe (reader disconnected)\n");
|
||||
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
fprintf(stderr, "Warning: Pipe write would block\n");
|
||||
} else {
|
||||
fprintf(stderr, "Warning: Error writing to pipe: %s\n", strerror(errno));
|
||||
}
|
||||
} else if (bytes_written < (ssize_t)(received_words * sizeof(uint32_t))) {
|
||||
printf("Warning: Partial write to pipe: %zd of %zu bytes\n",
|
||||
bytes_written, received_words * sizeof(uint32_t));
|
||||
} else {
|
||||
printf("Written %zd bytes to pipe\n", bytes_written);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}else if (recv_Err_code == 0){
|
||||
printf("no data received. timeout\n");
|
||||
}else{
|
||||
sleep(1);
|
||||
printf("receive error: %d\n======================\n", recv_Err_code);
|
||||
}
|
||||
}
|
||||
@ -998,9 +790,9 @@ int main(int argc, char** argv) {
|
||||
main_state_set_defaults(&state);
|
||||
parse_cmd_file(cmd_filename, &state);
|
||||
// отладочный вывод принятых значений
|
||||
printf("Parsed state: run_mode=%d, BF_mode=%d, BlackFin_mode=%d, run_length=%u, runs_N=%u, run_I=%u, data_path=%s, save_to_files=%d\n",
|
||||
printf("Parsed state: run_mode=%d, BF_mode=%d, BlackFin_mode=%d, run_length=%u, runs_N=%u, run_I=%u, data_path=%s\n",
|
||||
(int)state.run_mode, (int)state.BF_mode, (int)state.BlackFin_mode,
|
||||
state.run_length, state.runs_N, state.run_I, state.data_path, state.save_to_files);
|
||||
state.run_length, state.runs_N, state.run_I, state.data_path);
|
||||
|
||||
/* Removed unused temporary buffers and FFT/LFSM placeholders */
|
||||
|
||||
@ -1085,13 +877,6 @@ int main(int argc, char** argv) {
|
||||
streams_start_Err = X502_StreamsStart(hnd);
|
||||
printf("Streams start err: %d \n", streams_start_Err);
|
||||
|
||||
#ifndef _WIN32
|
||||
// Initialize named pipe
|
||||
printf("Initializing named pipe: %s\n", state.pipe_path);
|
||||
state.pipe_fd = init_pipe(state.pipe_path);
|
||||
#else
|
||||
state.pipe_fd = -1;
|
||||
#endif
|
||||
|
||||
if (state.run_mode == RUN_MODE_FINITE){
|
||||
if (state.BF_mode == BF_MODE_TRANSPARENT){
|
||||
@ -1126,7 +911,7 @@ int main(int argc, char** argv) {
|
||||
//sprintf(&logfilename, "data/received_data_%ld.csv", seconds);
|
||||
snprintf(tmp_data_filename, sizeof(tmp_data_filename), "%s/received_data_%ld.%ld.csv", state.data_path, ts.tv_sec, ts.tv_nsec);
|
||||
printf("%u/%u dumping to file: %s\n", (unsigned)state.run_I, (unsigned)state.runs_N, tmp_data_filename);
|
||||
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, state.run_length, state.pipe_fd);
|
||||
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, state.run_length);
|
||||
if (runs_since_streams_clean >= 10){
|
||||
runs_since_streams_clean = 0;
|
||||
X502_StreamsStop(hnd);
|
||||
@ -1135,9 +920,6 @@ int main(int argc, char** argv) {
|
||||
state.run_I++;
|
||||
runs_since_streams_clean++; }
|
||||
free(inp_buff);
|
||||
#ifndef _WIN32
|
||||
close_pipe(state.pipe_fd, state.pipe_path);
|
||||
#endif
|
||||
X502_Close(hnd);
|
||||
// освобождаем описатель
|
||||
X502_Free(hnd);
|
||||
@ -1178,7 +960,7 @@ int main(int argc, char** argv) {
|
||||
//sprintf(&logfilename, "data/received_data_%ld.csv", seconds);
|
||||
snprintf(tmp_data_filename, sizeof(tmp_data_filename), "%s/received_data_%ld.%ld.csv", state.data_path, ts.tv_sec, ts.tv_nsec);
|
||||
printf("%u dumping to file: %s\n", (unsigned)state.run_I, tmp_data_filename);
|
||||
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, state.run_length, state.pipe_fd);
|
||||
receive_to_file(hnd, tmp_data_filename, inp_buff, max_total_words, state.run_length);
|
||||
if (runs_since_streams_clean >= 10){
|
||||
runs_since_streams_clean = 0;
|
||||
X502_StreamsStop(hnd);
|
||||
@ -1188,9 +970,6 @@ int main(int argc, char** argv) {
|
||||
runs_since_streams_clean++;
|
||||
}
|
||||
free(inp_buff);
|
||||
#ifndef _WIN32
|
||||
close_pipe(state.pipe_fd, state.pipe_path);
|
||||
#endif
|
||||
X502_Close(hnd);
|
||||
// освобождаем описатель
|
||||
X502_Free(hnd);
|
||||
@ -1322,7 +1101,7 @@ int main(int argc, char** argv) {
|
||||
struct timespec time_receive_started, time_receive_ended;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &time_receive_started);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000, state.pipe_fd);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
|
||||
clock_gettime(CLOCK_MONOTONIC, &time_receive_ended);
|
||||
|
||||
|
||||
@ -1358,7 +1137,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// printf("\n dbg value: ");
|
||||
// BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000, state.pipe_fd);
|
||||
receive_to_file(hnd, logfilename, inp_buff, max_total_words, 10000);
|
||||
printf("\n dbg value: ");
|
||||
BF_exec_cmd_simple(hnd, 0x800A, 10, 1);
|
||||
|
||||
|
||||
66
pipe_reader_test.py
Executable file
66
pipe_reader_test.py
Executable file
@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to read radar data from named pipe (FIFO)
|
||||
|
||||
This script demonstrates how to read binary data from the named pipe
|
||||
created by the radar acquisition program.
|
||||
"""
|
||||
|
||||
import struct
|
||||
import sys
|
||||
import os
|
||||
|
||||
def read_from_pipe(pipe_path="/tmp/radar_data_pipe"):
|
||||
"""
|
||||
Read uint32_t data from named pipe
|
||||
|
||||
Args:
|
||||
pipe_path: Path to the named pipe (FIFO)
|
||||
"""
|
||||
print(f"Opening pipe: {pipe_path}")
|
||||
print("Waiting for radar data...")
|
||||
|
||||
try:
|
||||
# Open pipe for reading (this will block until writer connects)
|
||||
with open(pipe_path, 'rb') as pipe:
|
||||
print("Connected to pipe! Reading data...")
|
||||
|
||||
word_count = 0
|
||||
while True:
|
||||
# Read 4 bytes (one uint32_t)
|
||||
data = pipe.read(4)
|
||||
|
||||
if not data:
|
||||
print("\nEnd of stream or pipe closed")
|
||||
break
|
||||
|
||||
if len(data) < 4:
|
||||
print(f"\nWarning: incomplete data read ({len(data)} bytes)")
|
||||
break
|
||||
|
||||
# Unpack as uint32_t (little-endian)
|
||||
value = struct.unpack('<I', data)[0]
|
||||
|
||||
# Print first 10 values and then every 1000th value
|
||||
if word_count < 10 or word_count % 1000 == 0:
|
||||
print(f"Word {word_count}: 0x{value:08X} ({value})")
|
||||
|
||||
word_count += 1
|
||||
|
||||
# Optional: process the data here
|
||||
# For example, convert to voltage, apply filters, etc.
|
||||
|
||||
print(f"\nTotal words received: {word_count}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\n\nInterrupted by user")
|
||||
print(f"Total words received: {word_count}")
|
||||
except FileNotFoundError:
|
||||
print(f"Error: Pipe {pipe_path} does not exist")
|
||||
print("Make sure the radar acquisition program is running first")
|
||||
except Exception as e:
|
||||
print(f"Error reading from pipe: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
pipe_path = sys.argv[1] if len(sys.argv) > 1 else "/tmp/radar_data_pipe"
|
||||
read_from_pipe(pipe_path)
|
||||
@ -1,4 +1,3 @@
|
||||
#!/usr/bin/bash
|
||||
sudo mount -t tmpfs -o size=1G tmpfs tmp
|
||||
./BF_companion 100 #should generate approx 500 MB of data by running 10 secs
|
||||
rm tmp/*
|
||||
# sudo mount -t tmpfs -o size=1G tmpfs tmp
|
||||
./BF_companion long_trace_AVG_RPI.cmd
|
||||
Reference in New Issue
Block a user