2021-05-02 00:02:49 +02:00
|
|
|
//
|
|
|
|
// Written for Computer Networks and Systems lab classes
|
|
|
|
// AUTHOR : Sergiusz Warga
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include "CircBuffer.h"
|
2021-05-03 20:23:01 +02:00
|
|
|
#include "funs.h"
|
2021-05-02 00:02:49 +02:00
|
|
|
|
2021-05-03 20:23:01 +02:00
|
|
|
void handle_arguments(int argc, char *argv[]) {
|
|
|
|
if (argc != 3) {
|
|
|
|
fprintf(stderr, "Usage: %s REFRESHING_FREQUENCY ALPHA\n", argv[0]);
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strtol(argv[1], NULL, 10) < 2) {
|
|
|
|
fprintf(stderr, "Refreshing frequency should be at least 2Hz!\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strtod(argv[2], NULL) > 1 || strtod(argv[2], NULL) < 0) {
|
|
|
|
fprintf(stderr, "Alpha coefficient should be in range [0, 1]!\n");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
}
|
2021-05-02 00:02:49 +02:00
|
|
|
|
2021-05-03 20:23:01 +02:00
|
|
|
_Noreturn void k_avg(int fd, int refreshing_frequency, double alpha) {
|
|
|
|
// Exponential Moving Average
|
2021-05-02 00:02:49 +02:00
|
|
|
printf("A k_avg has been called\n");
|
|
|
|
|
2021-05-03 20:23:01 +02:00
|
|
|
//----- Initialize the buffer -----
|
2021-05-02 00:02:49 +02:00
|
|
|
struct CircBuffer *buffer;
|
2021-05-03 20:23:01 +02:00
|
|
|
buffer = mmap(NULL, sizeof(struct CircBuffer), PROT_READ, MAP_SHARED, fd, 0);
|
2021-05-02 00:02:49 +02:00
|
|
|
if (buffer == MAP_FAILED) {
|
|
|
|
fprintf(stderr, "mmap: ");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2021-05-03 20:23:01 +02:00
|
|
|
struct timespec delay, tic, toc;
|
2021-05-02 00:02:49 +02:00
|
|
|
delay.tv_sec = 0;
|
2021-05-03 20:23:01 +02:00
|
|
|
delay.tv_nsec = (1./refreshing_frequency * NSEC_PER_SEC); // 1/f in nanoseconds
|
|
|
|
clock_gettime(CLOCK_REALTIME, &tic);
|
2021-05-02 00:02:49 +02:00
|
|
|
|
|
|
|
double ema;
|
2021-05-03 20:23:01 +02:00
|
|
|
int read_idx;
|
|
|
|
|
|
|
|
read_idx = buffer->info.free_idx - 1;
|
|
|
|
ema = buffer->data[read_idx];
|
|
|
|
printf("Refreshing period = %ldms\n", delay.tv_nsec/1000000);
|
2021-05-02 00:02:49 +02:00
|
|
|
|
|
|
|
while (1) {
|
2021-05-03 20:23:01 +02:00
|
|
|
clock_gettime(CLOCK_REALTIME, &toc);
|
|
|
|
if (timespec_diff_nano(&toc, &tic) > delay.tv_nsec) {
|
|
|
|
printf("EMA = %f\n", ema);
|
|
|
|
clock_gettime(CLOCK_REALTIME, &tic);
|
|
|
|
}
|
|
|
|
while (read_idx == ((buffer->info.free_idx - 1) % buffer->info.size)) {};
|
|
|
|
read_idx = ++read_idx % buffer->info.size;
|
|
|
|
ema = alpha * buffer->data[read_idx] + (1 - alpha) * ema;
|
2021-05-02 00:02:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
|
|
|
2021-05-03 20:23:01 +02:00
|
|
|
handle_arguments(argc, argv);
|
|
|
|
|
2021-05-02 00:02:49 +02:00
|
|
|
//----- Open a shared memory -----
|
|
|
|
const char *memory_name = "/dsp";
|
|
|
|
int fd = shm_open(memory_name, O_RDONLY, 0777);
|
|
|
|
if (fd < 0) {
|
|
|
|
fprintf(stderr, "shm_open: ");
|
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
printf("Shared memory file descriptor: %d\n", fd);
|
|
|
|
|
2021-05-03 20:23:01 +02:00
|
|
|
k_avg(fd, strtol(argv[1], NULL, 10), strtod(argv[2], NULL));
|
2021-05-02 00:02:49 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|