39 #include <linux/limits.h>
40 #include <pruss_intc_mapping.h>
42 #include <sys/types.h>
58 tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
62 int ret = prussdrv_open(PRU_EVTOUT_0);
69 prussdrv_pruintc_init(&pruss_intc_initdata);
76 prussdrv_pru_disable(0);
81 rl_config_t const *
const config, uint32_t aggregates) {
83 if (aggregates == 0) {
107 uint32_t buffer_size_bytes =
112 void *pru_extmem_base;
113 prussdrv_map_extmem(&pru_extmem_base);
114 uint32_t pru_extmem_phys =
115 (uint32_t)prussdrv_get_phys_addr(pru_extmem_base);
123 int res = prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0,
124 (
unsigned int *)&state,
sizeof(state));
126 __sync_synchronize();
135 uint32_t aggregates = 1;
151 uint32_t pru_extmem_size = (uint32_t)prussdrv_extmem_size();
152 uint32_t pru_extmem_size_demand =
156 if (pru_extmem_size_demand > pru_extmem_size) {
158 "insufficient PRU memory allocated/available.\n"
159 "update uio_pruss configuration:"
160 "options uio_pruss extram_pool_sz=0x%06x",
161 pru_extmem_size_demand);
166 void const *buffer0 = prussdrv_get_virt_addr(pru.
buffer0_addr);
167 void const *buffer1 = prussdrv_get_virt_addr(pru.
buffer1_addr);
183 data_file_header.
channel = file_channel;
217 prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (
unsigned int *)&pru,
221 __sync_synchronize();
231 res = prussdrv_pru_wait_event_timeout(PRU_EVTOUT_0,
PRU_TIMEOUT_US);
235 errno, strerror(errno));
237 }
else if (res == 0) {
250 if (daemon(1, 1) < 0) {
252 "failed to create background process; %d message: %s", errno,
259 pid_t pid = getpid();
263 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
266 int32_t *
const analog_buffer = (int32_t *)malloc(
268 uint32_t *
const digital_buffer =
274 size_t sensor_buffer_size = 0;
275 uint32_t sensor_rate_counter = 0;
278 uint32_t buffers_lost = 0;
279 uint32_t num_files = 1;
280 bool web_failure_disable =
false;
283 uint32_t buffer_read_count =
302 uint64_t file_size = (uint64_t)ftello(data_file);
310 char file_name[PATH_MAX];
311 char new_file_ending[PATH_MAX];
316 char *file_ending = file_name;
317 while (strchr(file_ending, target) != NULL) {
318 file_ending = strchr(file_ending, target);
325 sprintf(new_file_ending,
"_p%d", num_files);
326 strcat(new_file_ending, file_ending);
327 strcpy(file_ending, new_file_ending);
330 data_file = fopen64(file_name,
"w+");
348 fclose(ambient_file);
351 char *ambient_file_name =
353 strcpy(file_name, ambient_file_name);
356 file_ending = file_name;
357 while (strchr(file_ending, target) != NULL) {
358 file_ending = strchr(file_ending, target);
365 sprintf(new_file_ending,
"_p%d", num_files);
366 strcat(new_file_ending, file_ending);
367 strcpy(file_ending, new_file_ending);
370 ambient_file = fopen64(file_name,
"w+");
378 &ambient_file_header);
395 if (i < buffer_read_count - 1 ||
404 sensor_buffer_size = 0;
413 sensor_rate_counter =
421 res = prussdrv_pru_wait_event_timeout(PRU_EVTOUT_0,
PRU_TIMEOUT_US);
424 }
while (res < 0 && errno == EINTR);
428 "Failed waiting for PRU interrupt; %d message: %s", errno,
432 }
else if (res == 0) {
441 timestamp_realtime.
nsec -= (int64_t)2048e3 * 490 / config->
update_rate;
442 if (timestamp_realtime.
nsec < 0) {
443 timestamp_realtime.
sec -= 1;
444 timestamp_realtime.
nsec += (int64_t)1e9;
446 timestamp_monotonic.
nsec -= (int64_t)2048e3 * 490 / config->
update_rate;
447 if (timestamp_monotonic.
nsec < 0) {
448 timestamp_monotonic.
sec -= 1;
449 timestamp_monotonic.
nsec += (int64_t)1e9;
453 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
456 __sync_synchronize();
462 "overrun: %d samples (%d buffer) lost (%d in total)",
469 for (
size_t i = 0; i < buffer_size; i++) {
475 uint32_t *
const digital_data = digital_buffer + i;
494 errno, strerror(errno));
498 if (config->
web_enable && !web_failure_disable) {
500 sensor_buffer, buffer_size,
501 sensor_buffer_size, ×tamp_realtime,
502 ×tamp_monotonic, config);
505 web_failure_disable =
true;
507 "Web server connection failed; %d message: %s", errno,
510 "Disabling web interface and continue sampling.");
518 data_file, analog_buffer, digital_buffer, buffer_size,
519 ×tamp_realtime, ×tamp_monotonic, config);
522 if (block_count < 0) {
524 "Adding data block to data file failed; %d message: %s",
525 errno, strerror(errno));
533 block_count * (buffer_size / aggregates);
546 ambient_file, sensor_buffer, sensor_buffer_size,
547 ×tamp_realtime, ×tamp_monotonic, config);
550 if (block_count < 0) {
553 "Adding data block to ambient file failed; %d message: %s",
554 errno, strerror(errno));
569 ×tamp_realtime, ×tamp_monotonic,
587 free(digital_buffer);
597 fflush(ambient_file);
598 free(ambient_file_header.
channel);
624 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
int rl_log(rl_log_level_t log_level, char const *const format,...)
@ RL_LOG_INFO
Information.
void meter_print_buffer(int32_t const *analog_buffer, uint32_t const *digital_buffer, size_t buffer_size, rl_timestamp_t const *const timestamp_realtime, rl_timestamp_t const *const timestamp_monotonic, rl_config_t const *const config)
int pru_sample(FILE *data_file, FILE *ambient_file, rl_config_t const *const config)
int pru_control_init(pru_control_t *const pru_control, rl_config_t const *const config, uint32_t aggregates)
int pru_set_state(pru_state_t state)
@ PRU_STATE_SAMPLE_FINITE
PRU off.
@ PRU_STATE_SAMPLE_CONTINUOUS
PRU sampling in finite mode.
#define PRU_BINARY_FILE
PRU binary file location.
#define PRU_BUFFER_STATUS_SIZE
Size of PRU buffer status in bytes.
#define PRU_SAMPLE_SIZE
Size of PRU channel data in bytes.
#define PRU_DIGITAL_SIZE
Overall size of FRU digital channels in bytes.
enum pru_state pru_state_t
#define PRU_TIMEOUT_US
PRU time out in micro seconds.
int rl_status_write(rl_status_t *const status)
int rl_pid_set(pid_t pid)
@ RL_FILE_FORMAT_RLD
CSV format.
#define RL_SENSOR_SAMPLE_RATE
Ambient sensor read out rate in samples per second.
#define RL_SAMPLE_RATE_MIN
Minimum native sample rate of the ADC in samples per second.
#define ERROR
Function return value for errors (use errno to indicate the error)
#define SUCCESS
Function return value for successful completion.
#define RL_CHANNEL_COUNT
Number of RocketLogger analog channels.
void rl_file_store_header_bin(FILE *file_handle, rl_file_header_t *const file_header)
void rl_file_update_header_bin(FILE *file_handle, rl_file_header_t const *const file_header)
int rl_file_add_data_block(FILE *data_file, int32_t const *analog_buffer, uint32_t const *digital_buffer, size_t buffer_size, rl_timestamp_t const *const timestamp_realtime, rl_timestamp_t const *const timestamp_monotonic, rl_config_t const *const config)
void rl_file_store_header_csv(FILE *file_handle, rl_file_header_t const *const file_header)
void rl_file_setup_ambient_lead_in(rl_file_lead_in_t *const lead_in, rl_config_t const *const config)
void rl_file_setup_ambient_header(rl_file_header_t *const header, rl_config_t const *const config)
void rl_file_update_header_csv(FILE *file_handle, rl_file_header_t const *const file_header)
int rl_file_add_ambient_block(FILE *ambient_file, int32_t const *ambient_buffer, size_t buffer_size, rl_timestamp_t const *const timestamp_realtime, rl_timestamp_t const *const timestamp_monotonic, rl_config_t const *const config)
void rl_file_setup_data_header(rl_file_header_t *const header, rl_config_t const *const config)
char * rl_file_get_ambient_file_name(char const *const data_file_name)
void rl_file_setup_data_lead_in(rl_file_lead_in_t *const lead_in, rl_config_t const *const config)
#define RL_FILE_AMBIENT_DATA_BLOCK_SIZE
Ambient sensor data file block size in measurements.
int rl_socket_handle_data(int32_t const *analog_buffer, uint32_t const *digital_buffer, int32_t const *ambient_buffer, size_t buffer_size, size_t ambient_buffer_size, rl_timestamp_t const *const timestamp_realtime, rl_timestamp_t const *const timestamp_monotonic, rl_config_t const *const config)
int sensors_read(int32_t *const sensor_data, bool const sensor_available[SENSOR_REGISTRY_SIZE])
#define SENSOR_REGISTRY_SIZE
Number of sensor registered.
uint32_t index
buffer index
pru_data_t const data[]
the data blocks
uint32_t sample_rate
Sample rate of the ADC (in kSPS)
uint32_t sample_limit
Samples to take (0 for continuous)
uint32_t buffer0_addr
Memory address of the shared buffer 0.
uint32_t buffer1_addr
Memory address of the shared buffer 1.
pru_state_t state
Current PRU state.
uint32_t buffer_length
Shared buffer length in number of data elements.
int32_t channel_analog[RL_CHANNEL_COUNT]
double scales[RL_CHANNEL_COUNT]
Channel scales.
int offsets[RL_CHANNEL_COUNT]
Channel offsets (in bit)
char file_name[PATH_MAX]
Data file name.
bool interactive_enable
Display measurement data interactively in CLI while sampling.
uint64_t file_size
Maximum data file size.
bool background_enable
Put the measurement process in background after successful start.
bool ambient_enable
Enable logging of ambient sensor.
uint64_t sample_limit
Sample limit (0 for continuous)
bool web_enable
Enable web interface connection.
rl_file_format_t file_format
File format.
uint32_t sample_rate
Sampling rate.
uint32_t update_rate
Data update rate.
bool file_enable
Enable storing measurements to file.
uint64_t sample_count
Total sample count.
uint16_t channel_count
Analog channel count.
uint32_t data_block_count
Number of data blocks stored in the file.
uint16_t channel_bin_count
Binary channel count.
uint64_t buffer_count
Number of buffers taken.
bool error
Whether the logger is in an error state.
bool sampling
Sampling state, true: sampling, false: idle.
uint32_t disk_use_rate
Disk space in bytes required per minute when sampling.
uint16_t sensor_count
Number of sensors found connected to the system.
bool sensor_available[RL_SENSOR_COUNT_MAX]
Identifiers of sensors found.
uint64_t sample_count
Number of samples taken.
int64_t sec
Seconds in UNIX time (UTC)
int div_ceil(int n, int d)
void create_time_stamp(rl_timestamp_t *const timestamp_realtime, rl_timestamp_t *const timestamp_monotonic)