36 #include <sys/types.h> 47 pthread_mutex_t
waiting = PTHREAD_MUTEX_INITIALIZER;
50 pthread_cond_t
done = PTHREAD_COND_INITIALIZER;
58 unsigned int event = *((
unsigned int*)voidEvent);
62 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
65 prussdrv_pru_wait_event(event);
68 pthread_cond_signal(&
done);
81 struct timespec abs_time;
88 clock_gettime(CLOCK_REALTIME, &abs_time);
89 abs_time.tv_sec += timeout;
93 err = pthread_cond_timedwait(&
done, &
waiting, &abs_time);
114 if ((fd = open(
"/dev/mem", O_RDWR | O_SYNC)) == -1) {
120 void* pru_mmap = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
123 if (pru_mmap == (
void*)-1) {
143 if (munmap(pru_mmap, size) == -1) {
159 prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (
unsigned int*)&state,
170 tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
172 if (prussdrv_open(PRU_EVTOUT_0) == -1) {
176 prussdrv_pruintc_init(&pruss_intc_initdata);
190 uint32_t avg_factor) {
192 uint32_t pru_sample_rate;
204 pru_sample_rate =
K1;
209 pru_sample_rate =
K1;
214 pru_sample_rate =
K1;
219 pru_sample_rate =
K1;
224 pru_sample_rate =
K2;
229 pru_sample_rate =
K4;
234 pru_sample_rate =
K8;
239 pru_sample_rate =
K16;
244 pru_sample_rate =
K32;
249 pru_sample_rate =
K64;
262 uint32_t buffer_size_bytes =
297 char* file_comment) {
300 uint32_t avg_factor = 1;
342 int web_buffer_element_size =
343 buffer_sizes[i] * num_web_channels *
sizeof(int64_t);
353 tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
354 prussdrv_pruintc_init(&pruss_intc_initdata);
359 unsigned int number_buffers =
361 unsigned int buffer_size_bytes =
367 if (2 * buffer_size_bytes > max_size) {
368 rl_log(
ERROR,
"not enough memory allocated. Run:\n rmmod uio_pruss\n " 369 "modprobe uio_pruss extram_pool_sz=0x%06x",
370 2 * buffer_size_bytes);
376 void* buffer1 = buffer0 + buffer_size_bytes;
388 file_header.
channel = file_channel;
405 struct rl_file_channel ambient_file_channel[conf->ambient.sensor_count];
412 ambient_file_header.
channel = ambient_file_channel;
424 prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (
unsigned int*)&pru,
428 if (prussdrv_exec_program(0,
PRU_CODE) < 0) {
441 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
446 uint32_t buffers_lost = 0;
447 uint32_t buffer_samples_count;
448 uint32_t num_files = 1;
449 uint8_t skipped_buffers = 0;
458 !(conf->mode ==
LIMIT && i >= number_buffers);
461 if (conf->file_format !=
NO_FILE) {
464 uint64_t file_size = (uint64_t)ftello(data_file);
466 conf->sample_rate *
sizeof(int32_t) * (
NUM_CHANNELS + 1) +
469 if (conf->max_file_size != 0 &&
470 file_size + margin > conf->max_file_size) {
478 strcpy(file_name, conf->file_name);
482 char* file_ending = file_name;
483 while (strchr(file_ending, target) != NULL) {
484 file_ending = strchr(file_ending, target);
491 sprintf(new_file_ending,
"_p%d", num_files);
492 strcat(new_file_ending, file_ending);
493 strcpy(file_ending, new_file_ending);
496 data_file = fopen64(file_name,
"w+");
503 if (conf->file_format ==
BIN) {
505 }
else if (conf->file_format ==
CSV) {
514 fclose(ambient_file);
517 strcpy(file_name, conf->ambient.file_name);
520 file_ending = file_name;
521 while (strchr(file_ending, target) != NULL) {
522 file_ending = strchr(file_ending, target);
529 sprintf(new_file_ending,
"_p%d", num_files);
530 strcat(new_file_ending, file_ending);
531 strcpy(file_ending, new_file_ending);
534 ambient_file = fopen64(file_name,
"w+");
543 rl_log(
INFO,
"new ambient-file: %s", file_name);
552 buffer_addr = buffer0;
554 buffer_addr = buffer1;
561 buffer_samples_count =
575 prussdrv_pru_wait_event(PRU_EVTOUT_0);
582 timestamp_realtime.
nsec -= (uint64_t)1e9 / conf->update_rate;
583 if (timestamp_realtime.
nsec < 0) {
584 timestamp_realtime.
sec -= 1;
585 timestamp_realtime.
nsec += (uint64_t)1e9;
587 timestamp_monotonic.
nsec -= (uint64_t)1e9 / conf->update_rate;
588 if (timestamp_monotonic.
nsec < 0) {
589 timestamp_monotonic.
sec -= 1;
590 timestamp_monotonic.
nsec += (uint64_t)1e9;
594 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
597 uint32_t buffer_index = *((uint32_t*)buffer_addr);
598 if (buffer_index != i) {
599 buffers_lost += (buffer_index - i);
601 "overrun: %d samples (%d buffer) lost (%d in total)",
602 (buffer_index - i) * pru.
buffer_size, buffer_index - i,
609 buffer_samples_count, ×tamp_realtime,
610 ×tamp_monotonic, conf);
613 if (conf->enable_web_server == 1) {
615 buffer_samples_count, ×tamp_realtime, conf);
619 if (conf->file_format !=
NO_FILE) {
623 buffer_samples_count / avg_factor;
625 if (conf->file_format ==
BIN) {
627 }
else if (conf->file_format ==
CSV) {
633 if (skipped_buffers + 1 >= conf->update_rate) {
638 ×tamp_monotonic, conf);
659 if (conf->enable_web_server == 1) {
660 int num_web_clients = semctl(sem_id,
WAIT_SEM, GETNCNT);
665 if (conf->mode ==
METER) {
685 if (conf->enable_web_server == 1) {
691 if (conf->mode ==
METER) {
716 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
726 prussdrv_pru_disable(0);
int write_status(struct rl_status *status)
Limited sampling mode (limited by number of samples to take)
struct ringbuffer buffer[WEB_RING_BUFFER_COUNT]
Array of ring buffers for different time scales.
#define NUM_DIGITAL_INPUTS
Number of RocketLogger digital channels.
struct web_shm * web_create_shm(void)
rl_mode mode
Sampling mode.
int pru_data_setup(struct pru_data_struct *pru, struct rl_conf *conf, uint32_t avg_factor)
void file_handle_data(FILE *data_file, void *buffer_addr, uint32_t sample_data_size, uint32_t samples_count, struct time_stamp *timestamp_realtime, struct time_stamp *timestamp_monotonic, struct rl_conf *conf)
void file_store_header_bin(FILE *data_file, struct rl_file_header *file_header)
void file_update_header_bin(FILE *data_file, struct rl_file_header *file_header)
void meter_print_buffer(struct rl_conf *conf, void *buffer_addr, uint32_t sample_size)
rl_pru_state state
Current PRU state.
struct rl_status status
Current status of RocketLogger.
int64_t sec
Seconds in UNIX time (UTC)
#define BUFFER1_SIZE
Size of 1s/div buffer.
#define NUM_WEB_POINTS
Number of data points in web plot.
void * pru_map_memory(void)
#define NUMBER_ADC_COMMANDS
Number of ADC commands.
#define NUM_SEMS
Number of semaphores in set.
#define AMBIENT_DATA_BLOCK_SIZE
void ambient_setup_lead_in(struct rl_file_lead_in *lead_in, struct rl_conf *conf)
void rl_log(rl_log_type type, const char *format,...)
#define SEM_KEY
Semaphore key (used for set creation)
int read_file_value(char filename[])
#define PRU_TIMEOUT
PRU time out in seconds.
#define BUFFER10_SIZE
Size of 10s/div buffer.
int set_sem(int sem_id, int sem_num, int val)
uint32_t num_channels
Number of channels sampled.
enum pru_state rl_pru_state
int ceil_div(int n, int d)
int digital_inputs
En-/disable digital inputs.
#define MAX_PATH_LENGTH
Maximum path length in characters.
uint64_t sample_count
Total sample count.
void ambient_setup_header(struct rl_file_header *file_header, struct rl_conf *conf, char *comment)
uint16_t channel_bin_count
Binary channel count.
void file_setup_header(struct rl_file_header *file_header, struct rl_conf *conf, char *comment)
int enable_web_server
En-/disable plots on web interface.
#define PRU_CODE
PRU binary file location.
void file_update_header_csv(FILE *data_file, struct rl_file_header *file_header)
void file_setup_lead_in(struct rl_file_lead_in *lead_in, struct rl_conf *conf)
int sem_id
ID of semaphore set.
#define DATA_SEM
Number of data semaphore in set (manages access to shared memory data)
Continuous sampling mode.
int create_sem(key_t key, int num_sems)
uint64_t samples_taken
Number of samples taken.
int remove_sem(int sem_id)
struct web_shm * web_data
Pointer to shared memory data.
void web_buffer_reset(struct ringbuffer *buffer, int element_size, int length)
uint32_t buffer_size
Shared buffer size.
int sample_limit
Sample limit (0 for continuous)
#define NUM_CHANNELS
Maximum number of RocketLogger channels.
#define CHANNEL_ENABLED
Channel sampling enabled.
uint32_t number_commands
Number of ADC commands to send.
#define BUFFER100_SIZE
Size of 100s/div buffer.
#define PRU_DIG_SIZE
Size of PRU digital information in bytes.
uint32_t sample_limit
Samples to take (0 for continuous)
void create_time_stamp(struct time_stamp *timestamp_realtime, struct time_stamp *timestamp_monotonic)
void web_handle_data(struct web_shm *web_data_ptr, int sem_id, void *buffer_addr, uint32_t sample_data_size, uint32_t samples_count, struct time_stamp *timestamp_realtime, struct rl_conf *conf)
int channels[NUM_CHANNELS]
Channels to sample.
uint16_t channel_count
Analog channel count.
void file_store_header_csv(FILE *data_file, struct rl_file_header *file_header)
#define PRU_BUFFER_STATUS_SIZE
Size of PRU buffer status in bytes.
void ambient_store_data(FILE *ambient_file, struct time_stamp *timestamp_realtime, struct time_stamp *timestamp_monotonic, struct rl_conf *conf)
rl_file_format file_format
File format.
uint32_t buffer_number
Number of buffers taken.
#define WEB_RING_BUFFER_COUNT
Number of ring buffers in shared memory.
uint32_t sample_size
Sample size in shared memory.
int update_rate
Data update rate.
uint32_t precision
ADC precision (in bit)
int sample_rate
Sampling rate.
void * pru_wait_event(void *voidEvent)
int pru_unmap_memory(void *pru_mmap)
pthread_cond_t done
Notification variable.
int buffer_sizes[WEB_RING_BUFFER_COUNT]
Buffer sizes for different time scales.
uint32_t buffer0_location
Pointer to shared buffer 0.
int pru_sample(FILE *data_file, FILE *ambient_file, struct rl_conf *conf, char *file_comment)
rl_sampling sampling
Sampling state.
int count_channels(int channels[NUM_CHANNELS])
uint32_t buffer1_location
Pointer to shared buffer 1.
#define MIN_ADC_RATE
Minimal ADC sampling rate.
uint32_t commands[NUMBER_ADC_COMMANDS]
ADC commands to send.
int pru_wait_event_timeout(unsigned int event, unsigned int timeout)
uint32_t data_block_count
Number of data blocks stored in the file.
Meter mode (display current values in terminal)
#define MMAP_FILE
Memory map file.
void pru_set_state(rl_pru_state state)
pthread_mutex_t waiting
PRU access mutex.
#define DIGITAL_INPUTS_ENABLED
Digital input sampling ensabled.