From 87440963121e8b03f4f9b4e14f1e7436f1fd4da9 Mon Sep 17 00:00:00 2001 From: Sergiusz Warga Date: Sun, 2 May 2021 00:02:49 +0200 Subject: [PATCH] 200-cell CircBuffer works --- Task-8/CircBuffer.h | 10 +++++ Task-8/k_avg.c | 80 +++++++++++++++++++++++++++++++++++ Task-8/producer.c | 87 ++++++++++++++++++++++++++++++++++++++ Task-8/task_8_2.c | 100 -------------------------------------------- 4 files changed, 177 insertions(+), 100 deletions(-) create mode 100644 Task-8/CircBuffer.h create mode 100644 Task-8/k_avg.c create mode 100644 Task-8/producer.c delete mode 100644 Task-8/task_8_2.c diff --git a/Task-8/CircBuffer.h b/Task-8/CircBuffer.h new file mode 100644 index 0000000..a7d330d --- /dev/null +++ b/Task-8/CircBuffer.h @@ -0,0 +1,10 @@ +struct CircBuffer { + union { + struct { + int size; + int free_idx; + } info; + char padding[1024]; + }; + double data[200]; +}; \ No newline at end of file diff --git a/Task-8/k_avg.c b/Task-8/k_avg.c new file mode 100644 index 0000000..ba527a7 --- /dev/null +++ b/Task-8/k_avg.c @@ -0,0 +1,80 @@ +// +// Written for Computer Networks and Systems lab classes +// AUTHOR : Sergiusz Warga + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CircBuffer.h" + +#define PI 3.14 +#define SIG_FREQ 100 +#define SAM_FREQ 2000 + +_Noreturn void k_avg(int fd) { + // Exponential Moving Average should be updated with f = 10Hz (i.e. every 200 samples). + int samples = 200; + printf("A k_avg has been called\n"); + + struct CircBuffer *buffer; + buffer = mmap(NULL, sizeof(struct CircBuffer*), PROT_READ, MAP_SHARED, fd, 0); + if (buffer == MAP_FAILED) { + fprintf(stderr, "mmap: "); + exit(EXIT_FAILURE); + } + + struct timespec delay; + delay.tv_sec = 0; + delay.tv_nsec = 100000000ULL*1; // 100ms == 100 000 000ns -> 10Hz + + + double alpha = 0.1; + double ema; + int start_idx = 0; + + + while (1) { + start_idx = buffer->info.free_idx; + ema = buffer->data[start_idx]; + printf("start_idx = %d\n", start_idx); + printf("EMA = %lf\n", ema); + nanosleep(&delay, NULL); + } + + + + // while (1) { + // start_idx = (buffer->info.free_idx - samples) % buffer->info.size; + // printf("start_idx = %d\n", start_idx); + // ema = buffer->data[start_idx]; + // for (int read_idx = start_idx + 1; read_idx < samples; read_idx = ++read_idx % buffer->info.size) { + // ema = alpha*buffer->data[read_idx] + (1 - alpha) * ema; + // printf("EMA[%d] = %lf\n", read_idx, ema); + // } + // printf("EMA = %lf\n", ema); + // nanosleep(&delay, NULL); + // } + +} + +int main(int argc, char *argv[]) { + + //----- 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); + + k_avg(fd); + + return 0; +} \ No newline at end of file diff --git a/Task-8/producer.c b/Task-8/producer.c new file mode 100644 index 0000000..471e8ff --- /dev/null +++ b/Task-8/producer.c @@ -0,0 +1,87 @@ +// +// Written for Computer Networks and Systems lab classes +// AUTHOR : Sergiusz Warga + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CircBuffer.h" + +#define PI 3.14 +#define SIG_FREQ 100 +#define SAM_FREQ 2000 + +double get_sample(int signal_frequeuncy, int sampling_frequency, int sample_no) { + // TODO: Just a sketch, gotta rewrite + double step = 2.*PI/200; + return sin(sample_no*step); +} + +_Noreturn void producer(int fd) { // That's something new I've learned and I think that + // function specifiers are cute. + printf("The producer has been called\n"); + + struct CircBuffer *buffer; + buffer = mmap(NULL, sizeof(struct CircBuffer), PROT_WRITE, MAP_SHARED, fd, 0); + if (buffer == MAP_FAILED) { + fprintf(stderr, "mmap: "); + exit(EXIT_FAILURE); + + } + + int i = 0; + int free_idx = 0; + + struct timespec delay; + delay.tv_sec = 0; + delay.tv_nsec = 500000ULL*1; // 0.5ms == 500 000ns -> 2kHz + + while (1) { + free_idx = buffer->info.free_idx; // For more readable code + buffer->data[free_idx] = get_sample(SIG_FREQ, SAM_FREQ, i+1); // Put a sample into the buffer + buffer->info.free_idx = (free_idx + 1 ) % buffer->info.size; // Increase the free-cell index + printf("CircBuffer[%d] = \t %lf\n", free_idx, buffer->data[free_idx]); + i = ++i % 200; + nanosleep(&delay, NULL); + } + +} + +int main(int argc, char *argv[]) { + + //----- Create a shared memory ----- + const char *memory_name = "/dsp"; + int fd = shm_open(memory_name, O_CREAT | O_RDWR, 0777); + if (fd < 0) { + fprintf(stderr, "shm_open: "); + exit(EXIT_FAILURE); + } + printf("Shared memory file descriptor: %d\n", fd); + + //----- Truncate memory to the buffer's size + + if (ftruncate(fd, sizeof(struct CircBuffer)) < 0) { + fprintf(stderr, "ftruncate: \n"); + exit(EXIT_FAILURE); + } + + //----- Initialize the buffer ----- + struct CircBuffer *buffer; + buffer = (struct CircBuffer *)mmap(NULL, sizeof(struct CircBuffer), PROT_WRITE, MAP_SHARED, fd, 0); + if (buffer == MAP_FAILED) { + fprintf(stderr, "mmap: "); + exit(EXIT_FAILURE); + } + buffer->info.size = sizeof(buffer->data)/sizeof(double); + buffer->info.free_idx = 0; + + producer(fd); + + return 0; +} \ No newline at end of file diff --git a/Task-8/task_8_2.c b/Task-8/task_8_2.c deleted file mode 100644 index 77b24fc..0000000 --- a/Task-8/task_8_2.c +++ /dev/null @@ -1,100 +0,0 @@ -// Producer: -// Retransfers sinusoidal signal sampled at a frequency of 2kHz -// Writes to the circular buffer: -// Write sample into the free buffer position -// Incremets the free position by one -// After idx = size go to the beginning - -// Consumers: -// - -#include -#include -#include -#include -#include -#include -#include -#include - -#define PI 3.14 - -// void generate_signal(double *signal, int n_samples) { -// static double signal[n_samples]; -// double step = 2.*PI/(double)n_samples; -// for (int i = 0; i < n_samples; ++i) { -// signal[i] = sin(i*step); -// } -// } - -struct CircBuffer { - union { - struct { - int size; - int rd_idx; - int wr_idx; - } info; - char padding[1024]; - }; - int data[1024]; -}; - -void producer(const char * memory_name, int fd) { - printf("The producer has been called\n"); - double signal[] = {0, 0.7, 1, 0.7, 0}; - - struct CircBuffer *buffer; - - - buffer = mmap(NULL, 64, PROT_WRITE, MAP_SHARED, fd, 0); - if (buffer == MAP_FAILED) { - fprintf(stderr, "mmap: "); - exit(EXIT_FAILURE); - } - - - - -} - -int main(int argc, char *argv[]) { - int buffer_size = 64; - const char *memory_name = "/dsp"; - int fd = shm_open(memory_name, O_CREAT | O_RDWR, 0777); - if (fd < 0) { - fprintf(stderr, "shm_open: "); - exit(EXIT_FAILURE); - } - printf("Shred memory file descriptor: %d\n", fd); - - - // double *signal; - // generate_signal(signal, 100); - - struct CircBuffer *buffer; - - if (ftruncate(fd, sizeof(struct CircBuffer)) < 0) { - fprintf(stderr, "ftruncate: \n"); - exit(EXIT_FAILURE); - } - - pid_t pid; - pid = fork(); - if (pid == -1) { - perror("fork: "); - exit(EXIT_FAILURE); - } - if (pid == 0) { - buffer = (struct CircBuffer *)mmap(NULL, sizeof(buffer), PROT_READ, MAP_SHARED, fd, 0); - if (buffer == MAP_FAILED) { - fprintf(stderr, "mmap: "); - exit(EXIT_FAILURE); - } - exit(EXIT_SUCCESS); - } else { - producer(memory_name, fd); - } - - - return 0; -} \ No newline at end of file