35 #include <sys/types.h> 46 pthread_mutex_t
waiting = PTHREAD_MUTEX_INITIALIZER;
49 pthread_cond_t
done = PTHREAD_COND_INITIALIZER;
57 unsigned int event = *((
unsigned int*)voidEvent);
61 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
64 prussdrv_pru_wait_event(event);
67 pthread_cond_signal(&
done);
80 struct timespec abs_time;
87 clock_gettime(CLOCK_REALTIME, &abs_time);
88 abs_time.tv_sec += timeout;
92 err = pthread_cond_timedwait(&
done, &
waiting, &abs_time);
113 if ((fd = open(
"/dev/mem", O_RDWR | O_SYNC)) == -1) {
119 void* pru_mmap = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
122 if (pru_mmap == (
void*)-1) {
142 if (munmap(pru_mmap, size) == -1) {
158 prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (
unsigned int*)&state,
169 tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
171 if (prussdrv_open(PRU_EVTOUT_0) == -1) {
175 prussdrv_pruintc_init(&pruss_intc_initdata);
189 uint32_t avg_factor) {
191 uint32_t pru_sample_rate;
203 pru_sample_rate =
K1;
208 pru_sample_rate =
K1;
213 pru_sample_rate =
K1;
218 pru_sample_rate =
K1;
223 pru_sample_rate =
K2;
228 pru_sample_rate =
K4;
233 pru_sample_rate =
K8;
238 pru_sample_rate =
K16;
243 pru_sample_rate =
K32;
248 pru_sample_rate =
K64;
261 uint32_t buffer_size_bytes =
296 char* file_comment) {
299 uint32_t avg_factor = 1;
341 int web_buffer_element_size =
342 buffer_sizes[i] * num_web_channels *
sizeof(int64_t);
352 tpruss_intc_initdata pruss_intc_initdata = PRUSS_INTC_INITDATA;
353 prussdrv_pruintc_init(&pruss_intc_initdata);
358 unsigned int number_buffers =
360 unsigned int buffer_size_bytes =
366 if (2 * buffer_size_bytes > max_size) {
367 rl_log(
ERROR,
"not enough memory allocated. Run:\n rmmod uio_pruss\n " 368 "modprobe uio_pruss extram_pool_sz=0x%06x",
369 2 * buffer_size_bytes);
375 void* buffer1 = buffer0 + buffer_size_bytes;
387 file_header.
channel = file_channel;
404 struct rl_file_channel ambient_file_channel[conf->ambient.sensor_count];
411 ambient_file_header.
channel = ambient_file_channel;
423 prussdrv_pru_write_memory(PRUSS0_PRU0_DATARAM, 0, (
unsigned int*)&pru,
427 if (prussdrv_exec_program(0,
PRU_CODE) < 0) {
440 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
445 uint32_t buffers_lost = 0;
446 uint32_t buffer_samples_count;
447 uint32_t num_files = 1;
448 uint8_t skipped_buffers = 0;
457 !(conf->mode ==
LIMIT && i >= number_buffers);
460 if (conf->file_format !=
NO_FILE) {
463 uint64_t file_size = (uint64_t)ftello(data_file);
465 conf->sample_rate *
sizeof(int32_t) * (
NUM_CHANNELS + 1) +
468 if (conf->max_file_size != 0 &&
469 file_size + margin > conf->max_file_size) {
477 strcpy(file_name, conf->file_name);
481 char* file_ending = file_name;
482 while (strchr(file_ending, target) != NULL) {
483 file_ending = strchr(file_ending, target);
490 sprintf(new_file_ending,
"_p%d", num_files);
491 strcat(new_file_ending, file_ending);
492 strcpy(file_ending, new_file_ending);
495 data_file = fopen(file_name,
"w+");
502 if (conf->file_format ==
BIN) {
504 }
else if (conf->file_format ==
CSV) {
513 fclose(ambient_file);
516 strcpy(file_name, conf->ambient.file_name);
519 file_ending = file_name;
520 while (strchr(file_ending, target) != NULL) {
521 file_ending = strchr(file_ending, target);
528 sprintf(new_file_ending,
"_p%d", num_files);
529 strcat(new_file_ending, file_ending);
530 strcpy(file_ending, new_file_ending);
533 ambient_file = fopen(file_name,
"w+");
542 rl_log(
INFO,
"new ambient-file: %s", file_name);
551 buffer_addr = buffer0;
553 buffer_addr = buffer1;
560 buffer_samples_count =
574 prussdrv_pru_wait_event(PRU_EVTOUT_0);
581 timestamp_realtime.
nsec -= (uint64_t)1e9 / conf->update_rate;
582 if (timestamp_realtime.
nsec < 0) {
583 timestamp_realtime.
sec -= 1;
584 timestamp_realtime.
nsec += (uint64_t)1e9;
586 timestamp_monotonic.
nsec -= (uint64_t)1e9 / conf->update_rate;
587 if (timestamp_monotonic.
nsec < 0) {
588 timestamp_monotonic.
sec -= 1;
589 timestamp_monotonic.
nsec += (uint64_t)1e9;
593 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
596 uint32_t buffer_index = *((uint32_t*)buffer_addr);
597 if (buffer_index != i) {
598 buffers_lost += (buffer_index - i);
600 "overrun: %d samples (%d buffer) lost (%d in total)",
601 (buffer_index - i) * pru.
buffer_size, buffer_index - i,
608 buffer_samples_count, ×tamp_realtime,
609 ×tamp_monotonic, conf);
612 if (conf->enable_web_server == 1) {
614 buffer_samples_count, ×tamp_realtime, conf);
618 if (conf->file_format !=
NO_FILE) {
622 buffer_samples_count / avg_factor;
624 if (conf->file_format ==
BIN) {
626 }
else if (conf->file_format ==
CSV) {
632 if (skipped_buffers + 1 >= conf->update_rate) {
637 ×tamp_monotonic, conf);
658 if (conf->enable_web_server == 1) {
659 int num_web_clients = semctl(sem_id,
WAIT_SEM, GETNCNT);
664 if (conf->mode ==
METER) {
684 if (conf->enable_web_server == 1) {
690 if (conf->mode ==
METER) {
715 prussdrv_pru_clear_event(PRU_EVTOUT_0, PRU0_ARM_INTERRUPT);
725 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.