From 2d403d66f73086c1701acec561b37a422626e26d Mon Sep 17 00:00:00 2001 From: Andre Heber Date: Thu, 3 Mar 2016 22:00:09 +0100 Subject: [PATCH] Init --- Pipe.sln | 28 +++++++++ Pipe/Pipe.vcxproj | 122 ++++++++++++++++++++++++++++++++++++++ Pipe/Pipe.vcxproj.filters | 30 ++++++++++ Pipe/main.c | 110 ++++++++++++++++++++++++++++++++++ Pipe/pipe.h | 89 +++++++++++++++++++++++++++ Pipe/ringbuffer.h | 96 ++++++++++++++++++++++++++++++ 6 files changed, 475 insertions(+) create mode 100644 Pipe.sln create mode 100644 Pipe/Pipe.vcxproj create mode 100644 Pipe/Pipe.vcxproj.filters create mode 100644 Pipe/main.c create mode 100644 Pipe/pipe.h create mode 100644 Pipe/ringbuffer.h diff --git a/Pipe.sln b/Pipe.sln new file mode 100644 index 0000000..c91d63d --- /dev/null +++ b/Pipe.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Pipe", "Pipe\Pipe.vcxproj", "{FA5ADF78-687F-4538-B7DB-C62B46B697C7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x64.ActiveCfg = Debug|x64 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x64.Build.0 = Debug|x64 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x86.ActiveCfg = Debug|Win32 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Debug|x86.Build.0 = Debug|Win32 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x64.ActiveCfg = Release|x64 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x64.Build.0 = Release|x64 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x86.ActiveCfg = Release|Win32 + {FA5ADF78-687F-4538-B7DB-C62B46B697C7}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Pipe/Pipe.vcxproj b/Pipe/Pipe.vcxproj new file mode 100644 index 0000000..7116a6a --- /dev/null +++ b/Pipe/Pipe.vcxproj @@ -0,0 +1,122 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {FA5ADF78-687F-4538-B7DB-C62B46B697C7} + Pipe + 8.1 + + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + Application + true + v140 + MultiByte + + + Application + false + v140 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + + + + + Level3 + Disabled + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/Pipe/Pipe.vcxproj.filters b/Pipe/Pipe.vcxproj.filters new file mode 100644 index 0000000..763f921 --- /dev/null +++ b/Pipe/Pipe.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/Pipe/main.c b/Pipe/main.c new file mode 100644 index 0000000..9cdd3f5 --- /dev/null +++ b/Pipe/main.c @@ -0,0 +1,110 @@ +#include +#include +#include "ringbuffer.h" +#include "pipe.h" + +void increment(pipe_t * const p) +{ + while (Pipe_isFilled(p)) + { + uint32_t item = Pipe_Read(p); + item++; + Pipe_Write(p, item); + } +} + +void square(pipe_t * const p) +{ + while (Pipe_isFilled(p)) + { + uint32_t item = Pipe_Read(p); + item = item * item; + Pipe_Write(p, item); + } +} + +void integrate(pipe_t * const p) +{ + static uint32_t state = 0; + + while (Pipe_isFilled(p)) + { + uint32_t item = Pipe_Read(p); + state = state + item; + Pipe_Write(p, state); + } +} + +void sum(pipe_t * const p) +{ + uint32_t sum = 0; + + while (Pipe_isFilled(p)) + sum += Pipe_Read(p); + Pipe_Write(p, sum); +} + +void average(pipe_t * const p) +{ + uint32_t sum = 0; + uint32_t element_counter = 0; + uint32_t average = 0; + + while (Pipe_isFilled(p)) + { + sum += Pipe_Read(p); + element_counter++; + } + average = sum / element_counter; + Pipe_Write(p, average); +} + +int main(int argc, char * argv[]) +{ + /* Create pipes and connect them */ + Pipe_Create(increment_pipe, 4); + Pipe_Create(square_pipe, 4); + Pipe_Create(integrate_pipe, 8); + Pipe_Create(sum_pipe, 8); + Pipe_Create(average_pipe, 8); + + Pipe_Connect(&increment_pipe, &integrate_pipe); + Pipe_Connect(&square_pipe, &integrate_pipe); + Pipe_CreateOutput(integrate_pipe, integrate_output_rb, 8); + Pipe_Connect(&integrate_pipe, &sum_pipe); + Pipe_CreateOutput(sum_pipe, sum_output_rb, 4); + Pipe_Connect(&integrate_pipe, &average_pipe); + Pipe_CreateOutput(average_pipe, average_output_rb, 4); + + /* Generate input */ + Pipe_Insert(&increment_pipe, 1); + Pipe_Insert(&increment_pipe, 3); + Pipe_Insert(&increment_pipe, 5); + + Pipe_Insert(&square_pipe, 2); + Pipe_Insert(&square_pipe, 4); + Pipe_Insert(&square_pipe, 6); + + /* run the functions */ + increment(&increment_pipe); + square(&square_pipe); + integrate(&integrate_pipe); + sum(&sum_pipe); + average(&average_pipe); + + /* print the output */ + printf("Output:\n"); + printf("%d\n", RingBuffer_Read(&integrate_output_rb)); + printf("%d\n", RingBuffer_Read(&integrate_output_rb)); + printf("%d\n", RingBuffer_Read(&integrate_output_rb)); + printf("%d\n", RingBuffer_Read(&integrate_output_rb)); + printf("%d\n", RingBuffer_Read(&integrate_output_rb)); + printf("%d\n", RingBuffer_Read(&integrate_output_rb)); + printf("\n"); + printf("Summe: %d\n", RingBuffer_Read(&sum_output_rb)); + printf("Average: %d\n", RingBuffer_Read(&average_output_rb)); + + getchar(); + + return 0; +} diff --git a/Pipe/pipe.h b/Pipe/pipe.h new file mode 100644 index 0000000..74adbef --- /dev/null +++ b/Pipe/pipe.h @@ -0,0 +1,89 @@ +#ifndef PIPE_H_ +#define PIPE_H_ + +#include +#include "ringbuffer.h" + +/* microsoft specific */ +#define inline __inline + +/* number of counts */ +#define PIPE_OUTPUT_COUNT 4 + +typedef struct +{ + ringbuffer_t * input; + ringbuffer_t *output[PIPE_OUTPUT_COUNT]; + uint8_t output_count; +} pipe_t; + +/***********************************/ +/* Functions to contruct pipe mesh */ +/***********************************/ + +static inline void Pipe_Init(pipe_t * const p, ringbuffer_t * const arg_input) +{ + p->input = arg_input; + + for (uint8_t i = 0; i < PIPE_OUTPUT_COUNT; i++) + p->output[i] = NULL; + + p->output_count = 0; +} + +static inline void Pipe_Connect(pipe_t * const a, pipe_t * const b) +{ + a->output[a->output_count] = b->input; + a->output_count++; +} + +static inline void Pipe_AddOutput(pipe_t * const p, ringbuffer_t * const rb) +{ + p->output[p->output_count] = rb; + p->output_count++; +} + +#define Concat2(a, b) a ## b +#define Concat(a, b) Concat2(a, b) +#define SizeOfArray(arg) ( sizeof(arg) / sizeof(arg[0]) ) + +#define Pipe_Create(arg_name, arg_size) \ + static uint32_t Concat(buffer, __LINE__)[arg_size]; \ + ringbuffer_t arg_name ## _rb; \ + RingBuffer_InitFromArray(&arg_name ## _rb, Concat(buffer, __LINE__), SizeOfArray(Concat(buffer, __LINE__))); \ + pipe_t arg_name; \ + Pipe_Init(&arg_name, &arg_name ## _rb) + +#define Pipe_CreateOutput(arg_pipe, arg_name, arg_size) \ + static uint32_t Concat(buffer, __LINE__)[arg_size]; \ + ringbuffer_t arg_name; \ + RingBuffer_InitFromArray(&arg_name, Concat(buffer, __LINE__), SizeOfArray(Concat(buffer, __LINE__))); \ + Pipe_AddOutput(&arg_pipe, &arg_name); + + +/************************************/ +/* Functions to work with pipe mesh */ +/************************************/ + +static inline void Pipe_Insert(pipe_t * const p, uint32_t elem) +{ + RingBuffer_Write(p->input, elem); +} + +static inline uint32_t Pipe_Read(pipe_t * p) +{ + return RingBuffer_Read(p->input); +} + +static inline void Pipe_Write(pipe_t * p, uint32_t elem) +{ + for (uint8_t i = 0; i < p->output_count; i++) + RingBuffer_Write(p->output[i], elem); +} + +static inline uint8_t Pipe_isFilled(pipe_t * p) +{ + return RingBuffer_IsFilled(p->input); +} + +#endif diff --git a/Pipe/ringbuffer.h b/Pipe/ringbuffer.h new file mode 100644 index 0000000..f7e7799 --- /dev/null +++ b/Pipe/ringbuffer.h @@ -0,0 +1,96 @@ +#ifndef RINGBUFFER_H_ +#define RINGBUFFER_H_ + +#include + +#define inline __inline + +typedef struct { + uint32_t * reader; + uint32_t * writer; + uint32_t * start; + uint32_t * end; + uint8_t write_failed; + uint8_t read_failed; +} ringbuffer_t; + +/* Use Array as RingBuffer */ +static inline void RingBuffer_InitFromArray(ringbuffer_t * const rb, uint32_t * const array, const uint32_t size) +{ + rb->start = rb->reader = rb->writer = array; + rb->end = array + size - 1; + rb->write_failed = rb->read_failed = 0; +} + +static inline uint32_t * RingBuffer_GetNextWriterAddress(const ringbuffer_t * const rb) +{ + uint32_t * next_address = rb->writer; + + if (next_address == rb->end) + next_address = rb->start; + else + next_address++; + + return next_address; +} + +static inline uint8_t RingBuffer_IsFull(const ringbuffer_t * const rb) +{ + if (RingBuffer_GetNextWriterAddress(rb) == rb->reader) + return 1; + return 0; +} + +static inline uint8_t RingBuffer_IsEmpty(const ringbuffer_t * const rb) +{ + if (rb->writer == rb->reader) + return 1; + return 0; +} + +static inline uint8_t RingBuffer_IsFilled(const ringbuffer_t * const rb) +{ + return !RingBuffer_IsEmpty(rb); +} + +/* Write elem into RingBuffer. */ +static inline void RingBuffer_Write(ringbuffer_t * const rb, const uint32_t elem) +{ + if (!RingBuffer_IsFull(rb)) + { + *(rb->writer) = elem; + + if (rb->writer == rb->end) + rb->writer = rb->start; + else + rb->writer++; + } + else + { + rb->write_failed = 1; + } +} + +/* Read value from RingBuffer and returns it. */ +static inline uint32_t RingBuffer_Read(ringbuffer_t * const rb) +{ + uint32_t ret = 0; + + if (!RingBuffer_IsEmpty(rb)) + { + ret = *(rb->reader); + + if (rb->reader == rb->end) + rb->reader = rb->start; + else + rb->reader++; + } + else + { + rb->read_failed = 1; + } + + return ret; +} + +#endif