restarting work on this since im using it in penguinator
parent
519c761f7a
commit
125e6f2b5e
@ -0,0 +1,178 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: Microsoft
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveMacros: None
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignConsecutiveBitFields: None
|
||||||
|
AlignConsecutiveDeclarations: None
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: None
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: MultiLine
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: true
|
||||||
|
AfterControlStatement: Always
|
||||||
|
AfterEnum: true
|
||||||
|
AfterFunction: true
|
||||||
|
AfterNamespace: true
|
||||||
|
AfterObjCDeclaration: true
|
||||||
|
AfterStruct: true
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: true
|
||||||
|
BeforeCatch: true
|
||||||
|
BeforeElse: true
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeConceptDeclarations: true
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 120
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentRequires: false
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PointerAlignment: Right
|
||||||
|
PPIndentWidth: -1
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: true
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SortIncludes: CaseSensitive
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Always
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- STRINGIZE
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
...
|
||||||
|
|
@ -1,29 +1,29 @@
|
|||||||
{
|
{
|
||||||
// Use IntelliSense to learn about possible attributes.
|
// Use IntelliSense to learn about possible attributes.
|
||||||
// Hover to view descriptions of existing attributes.
|
// Hover to view descriptions of existing attributes.
|
||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "gcc.exe build and debug active file",
|
"name": "gcc.exe build and debug active file",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
|
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
|
||||||
"args": [],
|
"args": [],
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"environment": [],
|
"environment": [],
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
"miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe",
|
"miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe",
|
||||||
"setupCommands": [
|
"setupCommands": [
|
||||||
{
|
{
|
||||||
"description": "Enable pretty-printing for gdb",
|
"description": "Enable pretty-printing for gdb",
|
||||||
"text": "-enable-pretty-printing",
|
"text": "-enable-pretty-printing",
|
||||||
"ignoreFailures": true
|
"ignoreFailures": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"preLaunchTask": "gcc.exe build active file"
|
"preLaunchTask": "gcc.exe build active file"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -1,42 +1,42 @@
|
|||||||
/*
|
/*
|
||||||
(WORK IN PROGRESS)
|
(WORK IN PROGRESS)
|
||||||
Penguin's Circular Buffer Example -- Turning a noisy bell curve into a less noisy bell curve
|
Penguin's Circular Buffer Example -- Turning a noisy bell curve into a less noisy bell curve
|
||||||
|
|
||||||
Here's an example of using the circular buffer library for sensor data:
|
Here's an example of using the circular buffer library for sensor data:
|
||||||
|
|
||||||
Let's say I have a sensor that gives me temperature at 1khz (using ideals so it is exactly 1khz)
|
Let's say I have a sensor that gives me temperature at 1khz (using ideals so it is exactly 1khz)
|
||||||
If this sensor was only giving me raw analog data, I might want to do some processing on these values
|
If this sensor was only giving me raw analog data, I might want to do some processing on these values
|
||||||
so that I can make sure the values are as clean as possible. The more samples we have, the closer we are to the actual value.
|
so that I can make sure the values are as clean as possible. The more samples we have, the closer we are to the actual value.
|
||||||
The faster we gather samples, the closer we get to representing our data in realtime.
|
The faster we gather samples, the closer we get to representing our data in realtime.
|
||||||
|
|
||||||
Using the sample rate, I can decide on a sampling window (in seconds) and an OSR (Oversampling Rate). The larger the buffer size, the more memory I need, so
|
Using the sample rate, I can decide on a sampling window (in seconds) and an OSR (Oversampling Rate). The larger the buffer size, the more memory I need, so
|
||||||
it is useful to find a happy medium between a large buffer and clean values.
|
it is useful to find a happy medium between a large buffer and clean values.
|
||||||
|
|
||||||
A sampling window is the window of time in which we can accept values for an average value. Depending on your application,
|
A sampling window is the window of time in which we can accept values for an average value. Depending on your application,
|
||||||
a sampling window may need to be extremely small or maybe not so small. A rocket going extremely fast using
|
a sampling window may need to be extremely small or maybe not so small. A rocket going extremely fast using
|
||||||
some sensor for real time controls will want an extremely small sampling window as well as a lot of measurements for
|
some sensor for real time controls will want an extremely small sampling window as well as a lot of measurements for
|
||||||
both clean, near noiseless data and as close to realtime data as possible.
|
both clean, near noiseless data and as close to realtime data as possible.
|
||||||
|
|
||||||
The sampling windows is usually an engineering requirement given that can match the sampling rate of the sensor with the following:
|
The sampling windows is usually an engineering requirement given that can match the sampling rate of the sensor with the following:
|
||||||
sampling window (in seconds) = 1 / frequency
|
sampling window (in seconds) = 1 / frequency
|
||||||
Here, the OSR is simply 1.
|
Here, the OSR is simply 1.
|
||||||
|
|
||||||
So at 1khz sample rate, let's say I decide I only need a 0.125 second sample window and I want to clean up some noisy data.
|
So at 1khz sample rate, let's say I decide I only need a 0.125 second sample window and I want to clean up some noisy data.
|
||||||
We can now use this equation:
|
We can now use this equation:
|
||||||
OSR = frequency * sample window (in seconds)
|
OSR = frequency * sample window (in seconds)
|
||||||
|
|
||||||
All of these have ignored real world slowdowns like the time it takes to do math on lower end hardware, interrupts slightly delaying the math, etc
|
All of these have ignored real world slowdowns like the time it takes to do math on lower end hardware, interrupts slightly delaying the math, etc
|
||||||
Without wanting to do some hard analysis on whatever hardware we're using, I usually take my frequency and half it to ensure timing requirements are met, like so:
|
Without wanting to do some hard analysis on whatever hardware we're using, I usually take my frequency and half it to ensure timing requirements are met, like so:
|
||||||
|
|
||||||
OSR = frequency / 2 * sample window
|
OSR = frequency / 2 * sample window
|
||||||
|
|
||||||
Please note: In applications that require real real-time data, this is not a good way of doing things.
|
Please note: In applications that require real real-time data, this is not a good way of doing things.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -1,203 +1,198 @@
|
|||||||
// Resource/Inspiration: https://embedjournal.com/implementing-circular-buffer-embedded-c/
|
// Resource/Inspiration: https://embedjournal.com/implementing-circular-buffer-embedded-c/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Penguin's Circular Buffer -- a simple floating queue designed for low memory usage (mainly for embedded)
|
Penguin's Circular Buffer -- a simple floating queue designed for low memory usage (mainly for embedded)
|
||||||
|
|
||||||
This is a ring buffer with limited capabilities. It is meant as a container for moving data.
|
This is a ring buffer with limited capabilities. It is meant as a container for moving data.
|
||||||
Normally included features such as checks to see if the buffer is full or empty have been omitted
|
Normally included features such as checks to see if the buffer is full or empty have been omitted
|
||||||
because this type of buffer is being implemented mainly for sensor data usage. Data is almost never read individually,
|
because this type of buffer is being implemented mainly for sensor data usage. Data is almost never read
|
||||||
and even if it is, it isn't meant to be cleared on read. It is a simple moving buffer that automatically
|
individually, and even if it is, it isn't meant to be cleared on read. It is a simple moving buffer that
|
||||||
writes over old data for the purpose of keeping track of the most up to date data.
|
automatically writes over old data for the purpose of keeping track of the most up to date data.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
- Initialization is mandatory using p_cb_<type>_init.
|
- Initialization is mandatory using p_cb_<type>_init.
|
||||||
- If a circular buffer is not initialized, you will run into a LOT of hard-to-debug problems. Just initialize it.
|
- If a circular buffer is not initialized, you will run into a LOT of hard-to-debug problems. Just initialize it.
|
||||||
- By default, all cb types should be defined as disabled. This is to save on size. Enable the ones you want to use.
|
- By default, all cb types should be defined as disabled. This is to save on size. Enable the ones you want to use.
|
||||||
|
|
||||||
Behavior:
|
Behavior:
|
||||||
- Oldest data is overwritten
|
- Oldest data is overwritten
|
||||||
- popping of data isn't implemented. If this feature is required, use a ring buffer.
|
- popping of data isn't implemented. If this feature is required, use a ring buffer.
|
||||||
|
|
||||||
Acronyms:
|
Acronyms:
|
||||||
- p: penguin
|
- p: penguin
|
||||||
- pb: penguin buffer
|
- pb: penguin buffer
|
||||||
- cb: circular buffer
|
- cb: circular buffer
|
||||||
- uX, where X is bit size: unsigned X bit integer
|
- uX, where X is bit size: unsigned X bit integer
|
||||||
- iX, where X is bit size: signed X bit integer
|
- iX, where X is bit size: signed X bit integer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _PCIRCULARBUFFER_H_
|
#ifndef _PCIRCULARBUFFER_H_
|
||||||
#define _PCIRCULARBUFFER_H_
|
#define _PCIRCULARBUFFER_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdbool.h>
|
||||||
#include <stdbool.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// comment this out for release builds
|
// comment this out for release builds
|
||||||
//#define PB_CB_DEBUG
|
//#define PB_CB_DEBUG
|
||||||
|
|
||||||
// Making these PB_EN/DIS rather than just ENABLE/DISABLE because
|
// Making these PB_EN/DIS rather than just ENABLE/DISABLE because
|
||||||
// some enable/disable definition might already exist that is
|
// some enable/disable definition might already exist that is
|
||||||
// inversely active (enabled = 0, disable = 1)
|
// inversely active (enabled = 0, disable = 1)
|
||||||
// this way our en/dis definitions are explicit
|
// this way our en/dis definitions are explicit
|
||||||
#ifndef PB_ENABLE
|
#ifndef PB_ENABLE
|
||||||
#define PB_ENABLE (1)
|
#define PB_ENABLE (1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PB_DISABLE
|
#ifndef PB_DISABLE
|
||||||
#define PB_DISABLE (0)
|
#define PB_DISABLE (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Max size is 65535 (2^16 - 1) so variables can be safely set 16 bits (unsigned)
|
// Max size is 65535 (2^16 - 1) so variables can be safely set 16 bits (unsigned)
|
||||||
// If you want to change this, you'll need to change the sizes of all heads and max lengths
|
// If you want to change this, you'll need to change the sizes of all heads and max lengths
|
||||||
#define PB_CB_MAX_BUFFER_SIZE (65535)
|
#define PB_CB_MAX_BUFFER_SIZE (65535)
|
||||||
|
|
||||||
// Config
|
// Config
|
||||||
// Disable or Enable types needed here
|
// Disable or Enable types needed here
|
||||||
// We can save code size this way
|
// We can save code size this way
|
||||||
// While there are better ways to do this, this is the most accessible for anyone imo
|
// While there are better ways to do this, this is the most accessible for anyone imo
|
||||||
#define PB_CB_FLOAT PB_DISABLE
|
#define PB_CB_FLOAT PB_DISABLE
|
||||||
#define PB_CB_DOUBLE PB_ENABLE
|
#define PB_CB_DOUBLE PB_ENABLE
|
||||||
#define PB_CB_U8 PB_DISABLE
|
#define PB_CB_U8 PB_DISABLE
|
||||||
#define PB_CB_U16 PB_DISABLE
|
#define PB_CB_U16 PB_DISABLE
|
||||||
#define PB_CB_U32 PB_DISABLE
|
#define PB_CB_U32 PB_DISABLE
|
||||||
#define PB_CB_U64 PB_DISABLE
|
#define PB_CB_U64 PB_DISABLE
|
||||||
#define PB_CB_I8 PB_DISABLE
|
#define PB_CB_I8 PB_DISABLE
|
||||||
#define PB_CB_I16 PB_DISABLE
|
#define PB_CB_I16 PB_DISABLE
|
||||||
#define PB_CB_I32 PB_DISABLE
|
#define PB_CB_I32 PB_DISABLE
|
||||||
#define PB_CB_I64 PB_DISABLE
|
#define PB_CB_I64 PB_DISABLE
|
||||||
|
|
||||||
typedef enum PB_CB_STATUS
|
typedef enum PB_CB_STATUS
|
||||||
{
|
{
|
||||||
PB_CB_GOOD = 0,
|
PB_CB_GOOD = 0,
|
||||||
PB_CB_BAD = 1,
|
PB_CB_BAD = 1,
|
||||||
PB_CB_BAD_BUFFER_SIZE = 2,
|
PB_CB_BAD_BUFFER_SIZE = 2,
|
||||||
PB_CB_NULL_BUFFER = 3,
|
PB_CB_NULL_BUFFER = 3,
|
||||||
PB_CB_NULL_CBUFFER = 4
|
PB_CB_NULL_CBUFFER = 4
|
||||||
}PB_CB_STATUS;
|
} PB_CB_STATUS;
|
||||||
|
|
||||||
|
#if PB_CB_U8
|
||||||
#if PB_CB_U8
|
typedef struct p_cb_u8
|
||||||
typedef struct p_cb_u8
|
{
|
||||||
{
|
uint8_t *buffer;
|
||||||
uint8_t* buffer;
|
uint16_t head;
|
||||||
uint16_t head;
|
uint16_t max_len;
|
||||||
uint16_t max_len;
|
// Signifies the buffer being filled at least once.
|
||||||
// Signifies the buffer being filled at least once.
|
// Useful for initializing sensor data
|
||||||
// Useful for initializing sensor data
|
bool b_filled;
|
||||||
bool b_filled;
|
// Signifies the buffer being empty
|
||||||
// Signifies the buffer being empty
|
// Useful for knowing if data is being received
|
||||||
// Useful for knowing if data is being received
|
bool b_empty;
|
||||||
bool b_empty;
|
|
||||||
|
PB_CB_STATUS (*push)(struct p_cb_u8 *cbuffer, uint8_t value);
|
||||||
PB_CB_STATUS (*push)(struct p_cb_u8* cbuffer, uint8_t value);
|
PB_CB_STATUS (*empty)(struct p_cb_u8 *cbuffer);
|
||||||
PB_CB_STATUS (*empty)(struct p_cb_u8* cbuffer);
|
} p_cb_u8;
|
||||||
}p_cb_u8;
|
|
||||||
|
PB_CB_STATUS p_cb_u8_init(p_cb_u8 *circ_buffer, uint8_t *buff, uint32_t max_length);
|
||||||
PB_CB_STATUS p_cb_u8_init(p_cb_u8* circ_buffer, uint8_t* buff, uint32_t max_length);
|
#endif
|
||||||
#endif
|
|
||||||
|
#if PB_CB_U16
|
||||||
#if PB_CB_U16
|
typedef struct p_cb_u16
|
||||||
typedef struct p_cb_u16
|
{
|
||||||
{
|
uint16_t *buffer;
|
||||||
uint16_t* buffer;
|
uint16_t head;
|
||||||
uint16_t head;
|
uint16_t max_len;
|
||||||
uint16_t max_len;
|
// Signifies the buffer being filled at least once.
|
||||||
// Signifies the buffer being filled at least once.
|
// Useful for initializing sensor data
|
||||||
// Useful for initializing sensor data
|
bool b_filled;
|
||||||
bool b_filled;
|
// Signifies the buffer being empty
|
||||||
// Signifies the buffer being empty
|
// Useful for knowing if data is being received
|
||||||
// Useful for knowing if data is being received
|
bool b_empty;
|
||||||
bool b_empty;
|
|
||||||
|
PB_CB_STATUS (*push)(struct p_cb_u16 *cbuffer, uint16_t value);
|
||||||
PB_CB_STATUS (*push)(struct p_cb_u16* cbuffer, uint16_t value);
|
PB_CB_STATUS (*empty)(struct p_cb_u16 *cbuffer);
|
||||||
PB_CB_STATUS (*empty)(struct p_cb_u16* cbuffer);
|
} p_cb_u16;
|
||||||
}p_cb_u16;
|
|
||||||
|
PB_CB_STATUS p_cb_u16_init(p_cb_u16 *circ_buffer, uint16_t *buff, uint32_t max_length);
|
||||||
PB_CB_STATUS p_cb_u16_init(p_cb_u16* circ_buffer, uint16_t* buff, uint32_t max_length);
|
#endif
|
||||||
#endif
|
|
||||||
|
#if PB_CB_U32
|
||||||
#if PB_CB_U32
|
typedef struct p_cb_u32
|
||||||
typedef struct p_cb_u32
|
{
|
||||||
{
|
uint32_t *buffer;
|
||||||
uint32_t* buffer;
|
uint16_t head;
|
||||||
uint16_t head;
|
uint16_t max_len;
|
||||||
uint16_t max_len;
|
// Signifies the buffer being filled at least once.
|
||||||
// Signifies the buffer being filled at least once.
|
// Useful for initializing sensor data
|
||||||
// Useful for initializing sensor data
|
bool b_filled;
|
||||||
bool b_filled;
|
// Signifies the buffer being empty
|
||||||
// Signifies the buffer being empty
|
// Useful for knowing if data is being received
|
||||||
// Useful for knowing if data is being received
|
bool b_empty;
|
||||||
bool b_empty;
|
|
||||||
|
PB_CB_STATUS (*push)(struct p_cb_u32 *cbuffer, uint32_t value);
|
||||||
PB_CB_STATUS (*push)(struct p_cb_u32* cbuffer, uint32_t value);
|
PB_CB_STATUS (*empty)(struct p_cb_u32 *cbuffer);
|
||||||
PB_CB_STATUS (*empty)(struct p_cb_u32* cbuffer);
|
} p_cb_u32;
|
||||||
}p_cb_u32;
|
|
||||||
|
PB_CB_STATUS p_cb_u32_init(p_cb_u32 *circ_buffer, uint32_t *buff, uint32_t max_length);
|
||||||
PB_CB_STATUS p_cb_u32_init(p_cb_u32* circ_buffer, uint32_t* buff, uint32_t max_length);
|
#endif
|
||||||
#endif
|
|
||||||
|
#if PB_CB_U64
|
||||||
|
typedef struct p_cb_u64
|
||||||
#if PB_CB_U64
|
{
|
||||||
typedef struct p_cb_u64
|
uint64_t *buffer;
|
||||||
{
|
uint16_t head;
|
||||||
uint64_t* buffer;
|
uint16_t max_len;
|
||||||
uint16_t head;
|
// Signifies the buffer being filled at least once.
|
||||||
uint16_t max_len;
|
// Useful for initializing sensor data
|
||||||
// Signifies the buffer being filled at least once.
|
bool b_filled;
|
||||||
// Useful for initializing sensor data
|
// Signifies the buffer being empty
|
||||||
bool b_filled;
|
// Useful for knowing if data is being received
|
||||||
// Signifies the buffer being empty
|
bool b_empty;
|
||||||
// Useful for knowing if data is being received
|
|
||||||
bool b_empty;
|
PB_CB_STATUS (*push)(struct p_cb_u64 *cbuffer, uint64_t value);
|
||||||
|
PB_CB_STATUS (*empty)(struct p_cb_u64 *cbuffer);
|
||||||
PB_CB_STATUS (*push)(struct p_cb_u64* cbuffer, uint64_t value);
|
} p_cb_u64;
|
||||||
PB_CB_STATUS (*empty)(struct p_cb_u64* cbuffer);
|
|
||||||
}p_cb_u64;
|
PB_CB_STATUS p_cb_u64_init(p_cb_u64 *circ_buffer, uint64_t *buff, uint32_t max_length);
|
||||||
|
#endif
|
||||||
PB_CB_STATUS p_cb_u64_init(p_cb_u64* circ_buffer, uint64_t* buff, uint32_t max_length);
|
|
||||||
#endif
|
#if PB_CB_FLOAT
|
||||||
|
typedef struct p_cb_float
|
||||||
#if PB_CB_FLOAT
|
{
|
||||||
typedef struct p_cb_float
|
float *buffer;
|
||||||
{
|
uint16_t head;
|
||||||
float* buffer;
|
uint16_t max_len;
|
||||||
uint16_t head;
|
// Signifies the buffer being filled at least once.
|
||||||
uint16_t max_len;
|
// Useful for initializing sensor data
|
||||||
// Signifies the buffer being filled at least once.
|
bool b_filled;
|
||||||
// Useful for initializing sensor data
|
// Signifies the buffer being empty
|
||||||
bool b_filled;
|
// Useful for knowing if data is being received
|
||||||
// Signifies the buffer being empty
|
bool b_empty;
|
||||||
// Useful for knowing if data is being received
|
|
||||||
bool b_empty;
|
PB_CB_STATUS (*push)(struct p_cb_float *cbuffer, float value);
|
||||||
|
PB_CB_STATUS (*empty)(struct p_cb_float *cbuffer);
|
||||||
PB_CB_STATUS (*push)(struct p_cb_float* cbuffer, float value);
|
} p_cb_float;
|
||||||
PB_CB_STATUS (*empty)(struct p_cb_float* cbuffer);
|
|
||||||
}p_cb_float;
|
PB_CB_STATUS p_cb_float_init(p_cb_float *circ_buffer, float *buff, uint32_t max_length);
|
||||||
|
#endif
|
||||||
PB_CB_STATUS p_cb_float_init(p_cb_float* circ_buffer, float* buff, uint32_t max_length);
|
|
||||||
#endif
|
#if PB_CB_DOUBLE
|
||||||
|
typedef struct p_cb_double
|
||||||
#if PB_CB_DOUBLE
|
{
|
||||||
typedef struct p_cb_double
|
double *buffer;
|
||||||
{
|
uint16_t head;
|
||||||
double* buffer;
|
uint16_t max_len;
|
||||||
uint16_t head;
|
// Signifies the buffer being filled at least once.
|
||||||
uint16_t max_len;
|
// Useful for initializing sensor data
|
||||||
// Signifies the buffer being filled at least once.
|
bool b_filled;
|
||||||
// Useful for initializing sensor data
|
// Signifies the buffer being empty
|
||||||
bool b_filled;
|
// Useful for knowing if data is being received
|
||||||
// Signifies the buffer being empty
|
bool b_empty;
|
||||||
// Useful for knowing if data is being received
|
|
||||||
bool b_empty;
|
PB_CB_STATUS (*push)(struct p_cb_double *cbuffer, double value);
|
||||||
|
PB_CB_STATUS (*empty)(struct p_cb_double *cbuffer);
|
||||||
PB_CB_STATUS (*push)(struct p_cb_double* cbuffer, double value);
|
} p_cb_double;
|
||||||
PB_CB_STATUS (*empty)(struct p_cb_double* cbuffer);
|
|
||||||
}p_cb_double;
|
PB_CB_STATUS p_cb_double_init(p_cb_double *circ_buffer, double *buff, uint32_t max_length);
|
||||||
|
#endif
|
||||||
PB_CB_STATUS p_cb_double_init(p_cb_double* circ_buffer, double* buff, uint32_t max_length);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <PCircularBuffer.h>
|
#include <PCircularBuffer.h>
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
const uint16_t maxlength = 16;
|
const uint16_t maxlength = 16;
|
||||||
double my_buffer[maxlength];
|
double my_buffer[maxlength];
|
||||||
p_cb_double data;
|
p_cb_double data;
|
||||||
p_cb_double_init(&data, my_buffer, 16);
|
p_cb_double_init(&data, my_buffer, 16);
|
||||||
|
|
||||||
for(int x = 0; x < 32; x++)
|
for(int x = 0; x < 32; x++)
|
||||||
{
|
{
|
||||||
if( x < 16)
|
if( x < 16)
|
||||||
{
|
{
|
||||||
printf("[%02d] Before: %02lf\t", x, data.buffer[x]);
|
printf("[%02d] Before: %02lf\t", x, data.buffer[x]);
|
||||||
data.push(&data, (double)x);
|
data.push(&data, (double)x);
|
||||||
printf("[%02d] After: %02lf\r\n", x, data.buffer[x]);
|
printf("[%02d] After: %02lf\r\n", x, data.buffer[x]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("[%02d] Before: %02lf\t", x - 16, data.buffer[x - 16]);
|
printf("[%02d] Before: %02lf\t", x - 16, data.buffer[x - 16]);
|
||||||
data.push(&data, (double)x);
|
data.push(&data, (double)x);
|
||||||
printf("[%02d] After: %02lf\r\n", x - 16, data.buffer[x - 16]);
|
printf("[%02d] After: %02lf\r\n", x - 16, data.buffer[x - 16]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue