RocketLogger  2.0.0
pru.c
Go to the documentation of this file.
1 
32 #include <errno.h>
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 
39 #include <linux/limits.h>
40 #include <pruss_intc_mapping.h>
41 #include <prussdrv.h>
42 #include <sys/types.h>
43 #include <unistd.h>
44 
45 #include "calibration.h"
46 #include "log.h"
47 #include "meter.h"
48 #include "rl.h"
49 #include "rl_file.h"
50 #include "rl_socket.h"
51 #include "sem.h"
52 #include "sensor/sensor.h"
53 #include "util.h"
54 
55 #include "pru.h"
56 
57 int pru_init(void) {
58  tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
59 
60  // initialize and open PRU device
61  prussdrv_init();
62  int ret = prussdrv_open(PRU_EVTOUT_0);
63  if (ret != 0) {
64  rl_log(RL_LOG_ERROR, "failed to open PRUSS driver");
65  return ERROR;
66  }
67 
68  // setup PRU interrupt mapping
69  prussdrv_pruintc_init(&pruss_intc_initdata);
70 
71  return SUCCESS;
72 }
73 
74 void pru_deinit(void) {
75  // disable PRU and close memory mappings
76  prussdrv_pru_disable(0);
77  prussdrv_exit();
78 }
79 
81  rl_config_t const *const config, uint32_t aggregates) {
82  // zero aggregates value is also considered no aggregation
83  if (aggregates == 0) {
84  aggregates = 1;
85  }
86 
87  // set state
88  if (config->sample_limit > 0) {
90  } else {
92  }
93 
94  // set native sample rate in kSPS
95  if (config->sample_rate <= RL_SAMPLE_RATE_MIN) {
97  } else {
98  pru_control->sample_rate = config->sample_rate / 1000;
99  }
100 
101  // set sample limit and data buffer size
102  pru_control->sample_limit = config->sample_limit * aggregates;
104  1000 * pru_control->sample_rate / config->update_rate;
105 
106  // get shared buffer addresses
107  uint32_t buffer_size_bytes =
111 
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);
116  pru_control->buffer0_addr = pru_extmem_phys;
117  pru_control->buffer1_addr = pru_extmem_phys + buffer_size_bytes;
118 
119  return SUCCESS;
120 }
121 
123  int res = prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0,
124  (unsigned int *)&state, sizeof(state));
125  // PRU memory write fence
126  __sync_synchronize();
127  return res;
128 }
129 
130 int pru_sample(FILE *data_file, FILE *ambient_file,
131  rl_config_t const *const config) {
132  int res;
133 
134  // average (for low rates)
135  uint32_t aggregates = 1;
136  if (config->sample_rate < RL_SAMPLE_RATE_MIN) {
137  aggregates = (uint32_t)(RL_SAMPLE_RATE_MIN / config->sample_rate);
138  }
139 
140  // PRU SETUP
141 
142  // initialize PRU data structure
143  pru_control_t pru;
144  res = pru_control_init(&pru, config, aggregates);
145  if (res != SUCCESS) {
146  rl_log(RL_LOG_ERROR, "failed initializing PRU data structure");
147  return ERROR;
148  }
149 
150  // check max PRU buffer size
151  uint32_t pru_extmem_size = (uint32_t)prussdrv_extmem_size();
152  uint32_t pru_extmem_size_demand =
153  2 * (pru.buffer_length *
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);
162  pru.state = PRU_STATE_OFF;
163  }
164 
165  // get user space mapped PRU memory addresses
166  void const *buffer0 = prussdrv_get_virt_addr(pru.buffer0_addr);
167  void const *buffer1 = prussdrv_get_virt_addr(pru.buffer1_addr);
168 
169  // data file headers
170  rl_file_header_t data_file_header;
171  rl_file_header_t ambient_file_header;
172 
173  // DATA FILE STORING
174  if (config->file_enable) {
175 
176  // data file header lead-in
177  rl_file_setup_data_lead_in(&(data_file_header.lead_in), config);
178 
179  // channel array
180  int total_channel_count = data_file_header.lead_in.channel_bin_count +
181  data_file_header.lead_in.channel_count;
182  rl_file_channel_t file_channel[total_channel_count];
183  data_file_header.channel = file_channel;
184 
185  // complete file header
186  rl_file_setup_data_header(&data_file_header, config);
187 
188  // store header
189  if (config->file_format == RL_FILE_FORMAT_RLD) {
190  rl_file_store_header_bin(data_file, &data_file_header);
191  } else if (config->file_format == RL_FILE_FORMAT_CSV) {
192  rl_file_store_header_csv(data_file, &data_file_header);
193  }
194 
195  // AMBIENT FILE STORING
196 
197  // file header lead-in
198  if (config->ambient_enable) {
199 
200  rl_file_setup_ambient_lead_in(&(ambient_file_header.lead_in),
201  config);
202 
203  // allocate channel array
204  ambient_file_header.channel =
205  malloc(rl_status.sensor_count * sizeof(rl_file_channel_t));
206 
207  // complete file header
208  rl_file_setup_ambient_header(&ambient_file_header, config);
209 
210  // store header
211  rl_file_store_header_bin(ambient_file, &ambient_file_header);
212  }
213  }
214  // EXECUTION
215 
216  // write configuration to PRU memory
217  prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (unsigned int *)&pru,
218  sizeof(pru));
219 
220  // PRU memory write fence
221  __sync_synchronize();
222 
223  // run SPI on PRU0
224  res = prussdrv_exec_program(0, PRU_BINARY_FILE);
225  if (res < 0) {
226  rl_log(RL_LOG_ERROR, "Failed starting PRU, binary not found");
227  return ERROR;
228  }
229 
230  // wait for PRU event (returns 0 on timeout, -1 on error with errno)
231  res = prussdrv_pru_wait_event_timeout(PRU_EVTOUT_0, PRU_TIMEOUT_US);
232  if (res < 0) {
233  // error checking interrupt occurred
234  rl_log(RL_LOG_ERROR, "Failed waiting for PRU interrupt; %d message: %s",
235  errno, strerror(errno));
236  return ERROR;
237  } else if (res == 0) {
238  // low level ADC timeout occurred
239  rl_log(RL_LOG_ERROR, "Failed starting PRU, PRU not responding");
240  return ERROR;
241  }
242 
243  // initialize interactive measurement display when enabled
244  if (config->interactive_enable) {
245  meter_init();
246  }
247 
248  // create daemon after if requested to run in background
249  if (config->background_enable) {
250  if (daemon(1, 1) < 0) {
252  "failed to create background process; %d message: %s", errno,
253  strerror(errno));
254  return ERROR;
255  }
256  }
257 
258  // write PID in file (only after potential forking using daemon)
259  pid_t pid = getpid();
260  rl_pid_set(pid);
261 
262  // clear event
263  prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
264 
265  // CHANNEL DATA MEMORY ALLOCATION
266  int32_t *const analog_buffer = (int32_t *)malloc(
267  pru.buffer_length * RL_CHANNEL_COUNT * sizeof(int32_t));
268  uint32_t *const digital_buffer =
269  (uint32_t *)malloc(pru.buffer_length * sizeof(uint32_t));
270  int32_t sensor_buffer[SENSOR_REGISTRY_SIZE];
271 
272  pru_buffer_t const *pru_buffer = NULL;
273  size_t buffer_size; // number of data samples per buffer
274  size_t sensor_buffer_size = 0;
275  uint32_t sensor_rate_counter = 0;
276  rl_timestamp_t timestamp_monotonic;
277  rl_timestamp_t timestamp_realtime;
278  uint32_t buffers_lost = 0;
279  uint32_t num_files = 1; // number of files stored
280  bool web_failure_disable = false;
281 
282  // buffers to read in finite mode
283  uint32_t buffer_read_count =
284  div_ceil(config->sample_limit * aggregates, pru.buffer_length);
285 
286  // sampling started
287  rl_status.sampling = true;
288  res = rl_status_write(&rl_status);
289  if (res < 0) {
290  rl_log(RL_LOG_WARNING, "Failed writing status; %d message: %s", errno,
291  strerror(errno));
292  }
293 
294  // continuous sampling loop
295  for (uint32_t i = 0; rl_status.sampling &&
296  !(config->sample_limit > 0 && i >= buffer_read_count);
297  i++) {
298 
299  if (config->file_enable) {
300 
301  // check if max file size reached
302  uint64_t file_size = (uint64_t)ftello(data_file);
303  if (config->file_size > 0 &&
304  file_size + rl_status.disk_use_rate > config->file_size) {
305 
306  // close old data file
307  fclose(data_file);
308 
309  // determine new file name
310  char file_name[PATH_MAX];
311  char new_file_ending[PATH_MAX];
312  strcpy(file_name, config->file_name);
313 
314  // search for last .
315  char target = '.';
316  char *file_ending = file_name;
317  while (strchr(file_ending, target) != NULL) {
318  file_ending = strchr(file_ending, target);
319  file_ending++; // Increment file_ending, otherwise we'll
320  // find target at the same location
321  }
322  file_ending--;
323 
324  // add file number
325  sprintf(new_file_ending, "_p%d", num_files);
326  strcat(new_file_ending, file_ending);
327  strcpy(file_ending, new_file_ending);
328 
329  // open new data file
330  data_file = fopen64(file_name, "w+");
331 
332  // update header for new file
333  data_file_header.lead_in.data_block_count = 0;
334  data_file_header.lead_in.sample_count = 0;
335 
336  // store header
337  if (config->file_format == RL_FILE_FORMAT_RLD) {
338  rl_file_store_header_bin(data_file, &data_file_header);
339  } else if (config->file_format == RL_FILE_FORMAT_CSV) {
340  rl_file_store_header_csv(data_file, &data_file_header);
341  }
342 
343  rl_log(RL_LOG_INFO, "Creating new data file: %s", file_name);
344 
345  // AMBIENT FILE
346  if (config->ambient_enable) {
347  // close old ambient file
348  fclose(ambient_file);
349 
350  // determine new file name
351  char *ambient_file_name =
353  strcpy(file_name, ambient_file_name);
354 
355  // search for last .
356  file_ending = file_name;
357  while (strchr(file_ending, target) != NULL) {
358  file_ending = strchr(file_ending, target);
359  file_ending++; // Increment file_ending, otherwise we'll
360  // find target at the same location
361  }
362  file_ending--;
363 
364  // add file number
365  sprintf(new_file_ending, "_p%d", num_files);
366  strcat(new_file_ending, file_ending);
367  strcpy(file_ending, new_file_ending);
368 
369  // open new ambient file
370  ambient_file = fopen64(file_name, "w+");
371 
372  // update header for new file
373  ambient_file_header.lead_in.data_block_count = 0;
374  ambient_file_header.lead_in.sample_count = 0;
375 
376  // store header
377  rl_file_store_header_bin(ambient_file,
378  &ambient_file_header);
379 
380  rl_log(RL_LOG_INFO, "new ambient-file: %s", file_name);
381  }
382 
383  num_files++;
384  }
385  }
386 
387  // select current buffer
388  if (i % 2 == 0) {
389  pru_buffer = buffer0;
390  } else {
391  pru_buffer = buffer1;
392  }
393 
394  // select buffer size, repecting non-full last buffer
395  if (i < buffer_read_count - 1 ||
396  pru.sample_limit % pru.buffer_length == 0) {
397  buffer_size = (size_t)pru.buffer_length;
398  } else {
399  // last buffer is not fully used
400  buffer_size = (size_t)(pru.sample_limit % pru.buffer_length);
401  }
402 
403  // trigger new ambient sensor read out if enabled
404  sensor_buffer_size = 0;
405  if (config->ambient_enable) {
406  // rate limit sampling of the ambient sensors
407  if (sensor_rate_counter < RL_SENSOR_SAMPLE_RATE) {
408  // trigger sensor readout
409  sensor_buffer_size =
410  sensors_read(sensor_buffer, rl_status.sensor_available);
411  }
412  // increment rate limiting counter
413  sensor_rate_counter =
414  (sensor_rate_counter + RL_SENSOR_SAMPLE_RATE) %
415  config->update_rate;
416  }
417 
418  // wait for PRU event indicating new data (repeat wait on interrupts)
419  do {
420  // wait for PRU event (returns 0 on timeout, -1 on error with errno)
421  res = prussdrv_pru_wait_event_timeout(PRU_EVTOUT_0, PRU_TIMEOUT_US);
422  // timestamp received data
423  create_time_stamp(&timestamp_realtime, &timestamp_monotonic);
424  } while (res < 0 && errno == EINTR);
425  if (res < 0) {
426  // error checking interrupt occurred
428  "Failed waiting for PRU interrupt; %d message: %s", errno,
429  strerror(errno));
430  rl_status.error = true;
431  break;
432  } else if (res == 0) {
433  // low level ADC timeout occurred
434  rl_log(RL_LOG_ERROR, "ADC not responsive");
435  rl_status.error = true;
436  break;
437  }
438 
439  // adjust data timestamps with buffer latency (adjusted relative
440  // nanoseconds)
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;
445  }
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;
450  }
451 
452  // clear event
453  prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
454 
455  // PRU memory sync before accessing data
456  __sync_synchronize();
457 
458  // check for overrun (compare buffer numbers)
459  if (pru_buffer->index != i) {
460  buffers_lost += (pru_buffer->index - i);
462  "overrun: %d samples (%d buffer) lost (%d in total)",
463  (pru_buffer->index - i) * pru.buffer_length,
464  pru_buffer->index - i, buffers_lost);
465  i = pru_buffer->index;
466  }
467 
468  // process new data: copy data and apply calibration
469  for (size_t i = 0; i < buffer_size; i++) {
470  // get PRU data buffer pointer
471  pru_data_t const *const pru_data = &(pru_buffer->data[i]);
472 
473  // get local data buffer pointers
474  int32_t *const analog_data = analog_buffer + i * RL_CHANNEL_COUNT;
475  uint32_t *const digital_data = digital_buffer + i;
476 
477  // copy digital channel data
478  *digital_data = pru_data->channel_digital;
479 
480  // copy and calibrate analog channel data
481  for (int j = 0; j < RL_CHANNEL_COUNT; j++) {
482  analog_data[j] = (int32_t)((pru_data->channel_analog[j] +
483  rl_calibration.offsets[j]) *
485  }
486  }
487 
488  // update and write state
489  rl_status.sample_count += buffer_size / aggregates;
490  rl_status.buffer_count = i + 1 - buffers_lost;
491  res = rl_status_write(&rl_status);
492  if (res < 0) {
493  rl_log(RL_LOG_WARNING, "Failed writing status; %d message: %s",
494  errno, strerror(errno));
495  }
496 
497  // process data for web when enabled
498  if (config->web_enable && !web_failure_disable) {
499  res = rl_socket_handle_data(analog_buffer, digital_buffer,
500  sensor_buffer, buffer_size,
501  sensor_buffer_size, &timestamp_realtime,
502  &timestamp_monotonic, config);
503  if (res < 0) {
504  // disable web interface on failure, but continue sampling
505  web_failure_disable = true;
507  "Web server connection failed; %d message: %s", errno,
508  strerror(errno));
510  "Disabling web interface and continue sampling.");
511  }
512  }
513 
514  // update and write header
515  if (config->file_enable) {
516  // write the data buffer to file
517  int block_count = rl_file_add_data_block(
518  data_file, analog_buffer, digital_buffer, buffer_size,
519  &timestamp_realtime, &timestamp_monotonic, config);
520 
521  // stop sampling on file error
522  if (block_count < 0) {
524  "Adding data block to data file failed; %d message: %s",
525  errno, strerror(errno));
526  rl_status.error = true;
527  break;
528  }
529 
530  // update and store data file header
531  data_file_header.lead_in.data_block_count += block_count;
532  data_file_header.lead_in.sample_count +=
533  block_count * (buffer_size / aggregates);
534 
535  if (config->file_format == RL_FILE_FORMAT_RLD) {
536  rl_file_update_header_bin(data_file, &data_file_header);
537  } else if (config->file_format == RL_FILE_FORMAT_CSV) {
538  rl_file_update_header_csv(data_file, &data_file_header);
539  }
540  }
541 
542  // handle ambient data if enabled and available
543  if (config->ambient_enable && sensor_buffer_size > 0) {
544  // fetch and write data
545  int block_count = rl_file_add_ambient_block(
546  ambient_file, sensor_buffer, sensor_buffer_size,
547  &timestamp_realtime, &timestamp_monotonic, config);
548 
549  // stop sampling on file error
550  if (block_count < 0) {
551  rl_log(
552  RL_LOG_ERROR,
553  "Adding data block to ambient file failed; %d message: %s",
554  errno, strerror(errno));
555  rl_status.error = true;
556  break;
557  }
558 
559  // update and write header
560  ambient_file_header.lead_in.data_block_count += block_count;
561  ambient_file_header.lead_in.sample_count +=
562  block_count * RL_FILE_AMBIENT_DATA_BLOCK_SIZE;
563  rl_file_update_header_bin(ambient_file, &ambient_file_header);
564  }
565 
566  // print meter output if enabled
567  if (config->interactive_enable) {
568  meter_print_buffer(analog_buffer, digital_buffer, buffer_size,
569  &timestamp_realtime, &timestamp_monotonic,
570  config);
571  }
572  }
573 
574  // stop PRU
575  pru_stop();
576 
577  // sampling stopped, update status
578  rl_status.sampling = false;
579  res = rl_status_write(&rl_status);
580  if (res < 0) {
581  rl_log(RL_LOG_WARNING, "Failed writing status; %d message: %s", errno,
582  strerror(errno));
583  }
584 
585  // CLEANUP CHANNEL DATA MEMORY ALLOCATION
586  free(analog_buffer);
587  free(digital_buffer);
588 
589  // deinitialize interactive measurement display when enabled
590  if (config->interactive_enable) {
591  meter_deinit();
592  }
593 
594  // FILE FINISH (flush)
595  // flush ambient data and cleanup file header
596  if (config->ambient_enable) {
597  fflush(ambient_file);
598  free(ambient_file_header.channel);
599  }
600 
601  if (config->file_enable && !(rl_status.error)) {
602  fflush(data_file);
603  rl_log(RL_LOG_INFO, "stored %llu samples to file",
605  }
606 
607  // STATE
608  if (rl_status.error) {
609  return ERROR;
610  }
611 
612  return SUCCESS;
613 }
614 
615 void pru_stop(void) {
616 
617  // write OFF to PRU state (so PRU can clean up)
619 
620  // wait for interrupt (if no ERROR occurred) and clear event
621  if (!(rl_status.error)) {
622  // wait for PRU event (returns 0 on timeout, -1 on error with errno)
623  prussdrv_pru_wait_event_timeout(PRU_EVTOUT_0, PRU_TIMEOUT_US);
624  prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
625  }
626 }
int rl_log(rl_log_level_t log_level, char const *const format,...)
Definition: log.c:82
@ RL_LOG_ERROR
Error.
Definition: log.h:49
@ RL_LOG_WARNING
Warning.
Definition: log.h:50
@ RL_LOG_INFO
Information.
Definition: log.h:51
void meter_init(void)
Definition: meter.c:56
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)
Definition: meter.c:68
void meter_deinit(void)
Definition: meter.c:66
int pru_sample(FILE *data_file, FILE *ambient_file, rl_config_t const *const config)
Definition: pru.c:130
void pru_deinit(void)
Definition: pru.c:74
int pru_control_init(pru_control_t *const pru_control, rl_config_t const *const config, uint32_t aggregates)
Definition: pru.c:80
void pru_stop(void)
Definition: pru.c:615
int pru_init(void)
Definition: pru.c:57
int pru_set_state(pru_state_t state)
Definition: pru.c:122
@ PRU_STATE_OFF
Definition: pru.h:70
@ PRU_STATE_SAMPLE_FINITE
PRU off.
Definition: pru.h:71
@ PRU_STATE_SAMPLE_CONTINUOUS
PRU sampling in finite mode.
Definition: pru.h:72
#define PRU_BINARY_FILE
PRU binary file location.
Definition: pru.h:41
#define PRU_BUFFER_STATUS_SIZE
Size of PRU buffer status in bytes.
Definition: pru.h:48
#define PRU_SAMPLE_SIZE
Size of PRU channel data in bytes.
Definition: pru.h:46
#define PRU_DIGITAL_SIZE
Overall size of FRU digital channels in bytes.
Definition: pru.h:44
enum pru_state pru_state_t
Definition: pru.h:78
#define PRU_TIMEOUT_US
PRU time out in micro seconds.
Definition: pru.h:64
int rl_status_write(rl_status_t *const status)
Definition: rl.c:641
int rl_pid_set(pid_t pid)
Definition: rl.c:521
@ RL_FILE_FORMAT_RLD
CSV format.
Definition: rl.h:143
@ RL_FILE_FORMAT_CSV
Definition: rl.h:142
#define RL_SENSOR_SAMPLE_RATE
Ambient sensor read out rate in samples per second.
Definition: rl.h:66
#define RL_SAMPLE_RATE_MIN
Minimum native sample rate of the ADC in samples per second.
Definition: rl.h:62
#define ERROR
Function return value for errors (use errno to indicate the error)
Definition: rl.h:46
#define SUCCESS
Function return value for successful completion.
Definition: rl.h:44
#define RL_CHANNEL_COUNT
Number of RocketLogger analog channels.
Definition: rl.h:56
void rl_file_store_header_bin(FILE *file_handle, rl_file_header_t *const file_header)
Definition: rl_file.c:218
void rl_file_update_header_bin(FILE *file_handle, rl_file_header_t const *const file_header)
Definition: rl_file.c:325
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)
Definition: rl_file.c:351
void rl_file_store_header_csv(FILE *file_handle, rl_file_header_t const *const file_header)
Definition: rl_file.c:255
void rl_file_setup_ambient_lead_in(rl_file_lead_in_t *const lead_in, rl_config_t const *const config)
Definition: rl_file.c:161
void rl_file_setup_ambient_header(rl_file_header_t *const header, rl_config_t const *const config)
Definition: rl_file.c:207
void rl_file_update_header_csv(FILE *file_handle, rl_file_header_t const *const file_header)
Definition: rl_file.c:335
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)
Definition: rl_file.c:518
void rl_file_setup_data_header(rl_file_header_t *const header, rl_config_t const *const config)
Definition: rl_file.c:196
char * rl_file_get_ambient_file_name(char const *const data_file_name)
Definition: rl_file.c:95
void rl_file_setup_data_lead_in(rl_file_lead_in_t *const lead_in, rl_config_t const *const config)
Definition: rl_file.c:119
#define RL_FILE_AMBIENT_DATA_BLOCK_SIZE
Ambient sensor data file block size in measurements.
Definition: rl_file.h:65
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)
Definition: rl_socket.c:144
int sensors_read(int32_t *const sensor_data, bool const sensor_available[SENSOR_REGISTRY_SIZE])
Definition: sensor.c:198
#define SENSOR_REGISTRY_SIZE
Number of sensor registered.
Definition: sensor.h:47
uint32_t index
buffer index
Definition: pru.h:129
pru_data_t const data[]
the data blocks
Definition: pru.h:131
uint32_t sample_rate
Sample rate of the ADC (in kSPS)
Definition: pru.h:87
uint32_t sample_limit
Samples to take (0 for continuous)
Definition: pru.h:89
uint32_t buffer0_addr
Memory address of the shared buffer 0.
Definition: pru.h:93
uint32_t buffer1_addr
Memory address of the shared buffer 1.
Definition: pru.h:95
pru_state_t state
Current PRU state.
Definition: pru.h:85
uint32_t buffer_length
Shared buffer length in number of data elements.
Definition: pru.h:91
Definition: pru.h:106
int32_t channel_analog[RL_CHANNEL_COUNT]
Definition: pru.h:116
uint32_t channel_digital
Definition: pru.h:111
double scales[RL_CHANNEL_COUNT]
Channel scales.
Definition: calibration.h:53
int offsets[RL_CHANNEL_COUNT]
Channel offsets (in bit)
Definition: calibration.h:51
Definition: rl.h:154
char file_name[PATH_MAX]
Data file name.
Definition: rl.h:184
bool interactive_enable
Display measurement data interactively in CLI while sampling.
Definition: rl.h:160
uint64_t file_size
Maximum data file size.
Definition: rl.h:188
bool background_enable
Put the measurement process in background after successful start.
Definition: rl.h:158
bool ambient_enable
Enable logging of ambient sensor.
Definition: rl.h:180
uint64_t sample_limit
Sample limit (0 for continuous)
Definition: rl.h:162
bool web_enable
Enable web interface connection.
Definition: rl.h:176
rl_file_format_t file_format
File format.
Definition: rl.h:186
uint32_t sample_rate
Sampling rate.
Definition: rl.h:164
uint32_t update_rate
Data update rate.
Definition: rl.h:166
bool file_enable
Enable storing measurements to file.
Definition: rl.h:182
rl_file_channel_t * channel
Channels definitions (binary and normal)
Definition: rl_file.h:170
rl_file_lead_in_t lead_in
File header lead in (constant size)
Definition: rl_file.h:166
uint64_t sample_count
Total sample count.
Definition: rl_file.h:120
uint16_t channel_count
Analog channel count.
Definition: rl_file.h:132
uint32_t data_block_count
Number of data blocks stored in the file.
Definition: rl_file.h:118
uint16_t channel_bin_count
Binary channel count.
Definition: rl_file.h:130
Definition: rl.h:201
uint64_t buffer_count
Number of buffers taken.
Definition: rl.h:209
bool error
Whether the logger is in an error state.
Definition: rl.h:205
bool sampling
Sampling state, true: sampling, false: idle.
Definition: rl.h:203
uint32_t disk_use_rate
Disk space in bytes required per minute when sampling.
Definition: rl.h:219
uint16_t sensor_count
Number of sensors found connected to the system.
Definition: rl.h:221
bool sensor_available[RL_SENSOR_COUNT_MAX]
Identifiers of sensors found.
Definition: rl.h:223
uint64_t sample_count
Number of samples taken.
Definition: rl.h:207
int64_t nsec
Nanoseconds.
Definition: util.h:53
int64_t sec
Seconds in UNIX time (UTC)
Definition: util.h:51
int div_ceil(int n, int d)
Definition: util.c:82
void create_time_stamp(rl_timestamp_t *const timestamp_realtime, rl_timestamp_t *const timestamp_monotonic)
Definition: util.c:90