eTrice provides an implementation of the ROOM (Real-Time Object-Oriented Modeling) modeling language together with editors, code generators for Java, C++ and C code and exemplary target middleware.
The model is defined in textual form (Xtext) with graphical editors (Graphiti) for the structural and behavioral (i.e. state machine) parts.
http://www.eclipse.org/etrice/
Trace Compass is a Java tool for viewing and analyzing any type of logs or traces. Its goal is to provide views, graphs, metrics, etc. to help extract useful information from traces, in a way that is more user-friendly and informative than huge text dumps.
http://projects.eclipse.org/projects/tools.tracecompass
https://developers.google.com/web/fundamentals/
FlatBuffers is a serialization library for games and other memory constrained apps.
https://github.com/google/flatbuffers
Protocol Buffers - Google's data interchange format.
https://github.com/google/protobuf
The C++ Network Library Project -- header-only, cross-platform, standards compliant networking library.
https://github.com/google/cpp-netlib
A fast compressor/decompressor.
https://github.com/google/snappy
Brotli compression format.
https://github.com/google/brotli
Fruit is a dependency injection framework for C++.
https://github.com/google/fruit
RE2 is a fast, safe, thread-friendly alternative to backtracking regular expression engines like those used in PCRE, Perl, and Python. It is a C++ library.
https://github.com/google/re2
redgrep is a grep based on regular expression derivatives.
https://github.com/google/redgrep
Gumbo is an implementation of the HTML5 parsing algorithm implemented as a pure C99 library with no outside dependencies.
https://github.com/google/gumbo-parser
lmctfy is the open source version of Google’s container stack, which provides Linux application containers.
https://github.com/google/lmctfy
Lovefield is a relational query engine built on top of IndexedDB. It provides SQL-like syntax and works cross-browser (currently supporting Chrome 37+, Firefox 31+, and IE 10+).
https://github.com/google/lovefield
codefmt is a utility for syntax-aware code formatting. codefmt relies on codefmtlib for registration and management of formatting plugins.
https://github.com/google/vim-codefmt
Cppcheck is a static analysis tool for C/C++ code. Unlike C/C++ compilers and many other analysis tools it does not detect syntax errors in the code. Cppcheck primarily detects the types of bugs that the compilers normally do not detect. The goal is to detect only real errors in the code (i.e. have zero false positives).
http://cppcheck.sourceforge.net/
pugixml is a light-weight C++ XML processing library (it has XPath 1.0 implementation for complex data-driven tree queries).
http://pugixml.org/
Modern, powerful open source C++ class libraries for building network- and internet-based applications
http://pocoproject.org/
Multi-paradigm automated test framework for C++ and Objective-C (and, maybe, C). It is implemented entirely in a set of header files, but is packaged up as a single header for extra convenience.
https://github.com/philsquared/Catch
Some interesting C++ articles e.g. small size containers optimization using custom allocator
http://howardhinnant.github.io/
Gold linker
https://en.wikipedia.org/wiki/Gold_(linker)
Warp preprocessor
https://github.com/facebook/warp
LevelDB is a fast key-value storage library written at Google that provides an ordered mapping from string keys to string values.
https://github.com/google/leveldb
Kyoto Cabinet is a library of routines for managing a database.
http://fallabs.com/kyotocabinet/
UnQLite is a in-process software library which implements a self-contained, serverless, zero-configuration, transactional NoSQL database engine.
http://unqlite.org/
A Fast Key-Value Storage Engine Based on Hierarchical B+-Tree Trie
https://github.com/couchbase/forestdb
LMDB is an ultra-fast, ultra-compact, crash-proof key-value embedded data store
http://symas.com/mdb/
SQLite4 (with LSM - embedded database library for key-value data)
https://sqlite.org/src4/doc/trunk/www/index.wiki
FineDB.org - A high-performance noSQL database
http://www.finedb.org/
High performance JSON manipulation library
https://github.com/couchbase/subjson
Highly portable C system library
https://github.com/saprykin/plibsys
Memory optimal Small String Optimization implementation for C++
https://github.com/elliotgoodrich/SSO-23
c2xml is a tool that generates a XML representation of pre-processed ANSI C source code
http://c2xml.sourceforge.net/
Fake Function Framework (fff)
https://github.com/meekrosoft/fff
sobota, 31 stycznia 2015
niedziela, 18 stycznia 2015
Problem with Bluetooth in Dell Precision M4600
No connection neither from Linux nor Windows 7. The point is everything worked properly some time ago. Now Bluetooth seems to work and find devices, but after connection attempt it is broken instantly.
'hciconfig' shows device properly and from 'bluetoothctl', command 'paired-devices' shows devices properly.
Then using 'connect <dev>' everything worked again.
No connection neither from Linux nor Windows 7. The point is everything worked properly some time ago. Now Bluetooth seems to work and find devices, but after connection attempt it is broken instantly.
'hciconfig' shows device properly and from 'bluetoothctl', command 'paired-devices' shows devices properly.
Then using 'connect <dev>' everything worked again.
sobota, 1 listopada 2014
Fundamental types initialization
Consider something as complicated as:
the problem is value of member 'f'.
Structure A is of course POD therefore rules for member initialization can be really tricky.
Differences comes from three sources:
- way of initalization,
- C++ standard version,
- compiler vendor.
Possible ways of initialization are:
Note two things:
- it is impossible to use second case directly i.e.:
To use second initialization method, syntax can be:
Initialization of fundamental type variables and PODs is subject of constant changes and obscurity between C++ standards.
In C++98 initialization of non-POD object without constructor (e.g. struct with desctructor only or inherited) does not initialize fundamental type fields to 0 (but as it is visible below it is not truth for current compilers).
This was changed in C++03.
Also compilers can introduce surprising behaviours. VSC++ (before version 2013) was famous of not initializing PODs with A() syntax (still visible for some cases).
Below are test results of initialization results for different types and compilers.
Cases are
Compilers used
1. fundamental type
2. simplest POD struct
3. simplest non-POD struct (destructor added)
4. non-POD struct with field default initialization in constructor
5. non-POD struct without field initialization in constructor
6. non-POD struct with inheritance and no constructors
7. non-POD struct with inheritance and field default initialization in base class constructor
8. non-POD struct with inheritance and field default initialization in derived class constructor
Legend
And what lesson comes form data above - to be really sure field is initialized, you have to explicitly use initialization construct for the field (in constructor initialization list).
Test application available for downlowad here. Please note placement new used to avoid false 0-positive answers. For stack allocated items it is not that easy - there is try with recursive function (to pollute stack with non 0 values) but it is not always enough (false 0 answers can happen).
Note that in VSC++2013 "__cplusplus" is defined as 199711 (like for C++98 standard) but compiler allows for C++11 usage (perhaps not complete and therefore "__cplusplus" is not defined as 201103).
struct A
{
int f;
};
the problem is value of member 'f'.
Structure A is of course POD therefore rules for member initialization can be really tricky.
Differences comes from three sources:
- way of initalization,
- C++ standard version,
- compiler vendor.
Possible ways of initialization are:
A;
A();
A{};
which should be same to version with dynamic allocation:new A;
new A();
new A{};
Note two things:
- it is impossible to use second case directly i.e.:
A a();because in C++ this is function declaration (declaration can appear also inside function body).
To use second initialization method, syntax can be:
A a = A();- third way of initialization is from C++11 and allows for:
A a{};
Initialization of fundamental type variables and PODs is subject of constant changes and obscurity between C++ standards.
In C++98 initialization of non-POD object without constructor (e.g. struct with desctructor only or inherited) does not initialize fundamental type fields to 0 (but as it is visible below it is not truth for current compilers).
This was changed in C++03.
Also compilers can introduce surprising behaviours. VSC++ (before version 2013) was famous of not initializing PODs with A() syntax (still visible for some cases).
Below are test results of initialization results for different types and compilers.
Cases are
- fundamental type,
- simplest POD struct,
- simplest non-POD struct (destructor added),
- non-POD struct with field default initialization in constructor,
- non-POD struct without field initialization in constructor,
- non-POD struct with inheritance and no constructors,
- non-POD struct with inheritance and field default initialization in base class constructor,
- non-POD struct with inheritance and field default initialization in derived class constructor.
Compilers used
- gcc 4.8.2
- clang 3.3
- VisualStudio C++ 2013
1. fundamental type
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| int a; | - | - | - | - | - | - | - |
| int a = int(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| int a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| int *a = new int; | - | - | - | - | - | - | - |
| int *a = new int(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| int *a = new int{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
2. simplest POD struct
struct A
{
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | - | - | - | - | - | - | - |
| A a = A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| A *a = new A; | - | - | - | - | - | - | - |
| A *a = new A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A *a = new A{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
3. simplest non-POD struct (destructor added)
struct A
{
~A() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | - | - | - | - | - | - | - |
| A a = A(); | 0 | 0 | 0 | 0 | 0 | 0 | - |
| A a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| A *a = new A; | - | - | - | - | - | - | - |
| A *a = new A(); | 0 | 0 | 0 | 0 | 0 | 0 | - |
| A *a = new A{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
4. non-POD struct with field default initialization in constructor
struct A
{
A() : f() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A a = A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A a{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
| A *a = new A; | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A *a = new A(); | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| A *a = new A{}; | 0 | n.a. | n.a. | 0 | n.a. | n.a. | 0 |
5. non-POD struct without field initialization in constructor
struct A
{
A() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | - | - | - | - | - | - | - |
| A a = A(); | - | - | - | - | - | - | - |
| A a{}; | - | n.a. | n.a. | - | n.a. | n.a. | - |
| A *a = new A; | - | - | - | - | - | - | - |
| A *a = new A(); | - | - | - | - | - | - | - |
| A *a = new A{}; | - | n.a. | n.a. | - | n.a. | n.a. | - |
6. non-POD struct with inheritance and no constructors
struct P
{
int g;
};
struct A : public P
{
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- |
| A a = A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:-, g:- |
| A a{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:- |
| A *a = new A; | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- | f:-, g:- |
| A *a = new A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 |
| A *a = new A{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:- |
7. non-POD struct with inheritance and field default initialization in base class constructor
struct P
{
P() : g() {}
int g;
};
struct A : public P
{
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 |
| A a = A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:-, g:0 |
| A a{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:0 |
| A *a = new A; | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 | f:-, g:0 |
| A *a = new A(); | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:0, g:0 | f:-, g:0 |
| A *a = new A{}; | f:0, g:0 | n.a. | n.a. | f:0, g:0 | n.a. | n.a. | f:-, g:0 |
8. non-POD struct with inheritance and field default initialization in derived class constructor
struct P
{
int g;
};
struct A : public P
{
A() : f() {}
int f;
};
| init method | g++ std=c++11 | g++ std=c++03 | g++ std=c++98 | clang++ std=c++11 | clang++ std=c++03 | clang++ std=c++98 | VSC++2013 |
|---|---|---|---|---|---|---|---|
| A a; | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A a = A(); | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A a{}; | f:0, g:- | n.a. | n.a. | f:0, g:- | n.a. | n.a. | f:0, g:- |
| A *a = new A; | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A *a = new A(); | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- | f:0, g:- |
| A *a = new A{}; | f:0, g:- | n.a. | n.a. | f:0, g:- | n.a. | n.a. | f:0, g:- |
Legend
- "0" - initialized to 0
- "-" - not initialized
- "n.a." - available only in C++11
And what lesson comes form data above - to be really sure field is initialized, you have to explicitly use initialization construct for the field (in constructor initialization list).
Test application available for downlowad here. Please note placement new used to avoid false 0-positive answers. For stack allocated items it is not that easy - there is try with recursive function (to pollute stack with non 0 values) but it is not always enough (false 0 answers can happen).
Note that in VSC++2013 "__cplusplus" is defined as 199711 (like for C++98 standard) but compiler allows for C++11 usage (perhaps not complete and therefore "__cplusplus" is not defined as 201103).
wtorek, 19 sierpnia 2014
Acoustics absorption calculation (impedance tube)
Here is bunch of equations to calculate acoustic absorption coefficient according to transfer function method (ISO 10534-2:1998).
Absorption coefficient as function of frequency can be calculated from pressure reflection factor with:
Reflection factor is calculated from calculation (corrected) transfer function:
where 's' is microphones' spacing, 'x1' is distance form specimen to closer microphone and 'k0' is wave number.
Calculation (corrected) transfer function comes from:
Correction transfer function is obtained from:
and calculated as:
Please note that absorption coefficient calculation does not really need 'x1' distance to be known.
This is visible when following substitution is used in equation for reflection factor:
Then square of absolute value is given as (which is free from 'x1'):
Taking above into account ready to use equation can be derived:
taking following into account:
can be simplified to:
where:
Note that calculations are a bit simpler using polar representation for complex numbers.
Absorption coefficient as function of frequency can be calculated from pressure reflection factor with:
Reflection factor is calculated from calculation (corrected) transfer function:
where 's' is microphones' spacing, 'x1' is distance form specimen to closer microphone and 'k0' is wave number.
Calculation (corrected) transfer function comes from:
Correction transfer function is obtained from:
and calculated as:
Please note that absorption coefficient calculation does not really need 'x1' distance to be known.
This is visible when following substitution is used in equation for reflection factor:
Then square of absolute value is given as (which is free from 'x1'):
Taking above into account ready to use equation can be derived:
taking following into account:
can be simplified to:
where:
Note that calculations are a bit simpler using polar representation for complex numbers.
niedziela, 3 sierpnia 2014
Real time (stream) acquisition with ADS1278 and MMB0 (ADS1278EVM-PDK)
MMB0 with ADS1278 board is perfect tool to start adventure with DSP programming, especially in A/D conversion context.
Solution presented below is development of first Linux approach presented here.
ADS1278EVM-PDK is delivered with ready to use Windows software called ADCPro which is post processing tool for data gathered. The tool is build using LabVIEW environment and allows for basic estimation of A/D converter features and performance.
Main weakness of ADCPro (which is of course out of its original purpose) is lack of data streaming handling. Data acquisition is realized within MMB0 using its 16MB SDRAM memory. After acquisition is finished, data is transferred to PC for further analysis and presentation. This of course limits length of data that can be acquired in single measurement.
It is tempting idea to create alternative software to provide data streaming from MMB0 functionality. Obvious limitation here is USB 1.1 used in TMS320VC5509A which drives MMB0 (Rev.D in my case).
For USB 1.1 bandwidth is practically limited to about 1MB/s, which does not allow for all 8 channels utilisation with high sample rate. But this limitation makes the problem even more attractive - try to get all possible performance from MMB0 and check limits of USB 1.1.
Prepared solution contains two parts: firmware for MMB0 prepared with free Linux version of CCS and simple PC (Linux) app for control and data acquisition.
In order to limit usage of precious bandwidth data samples transferred to PC are 24-bit length (1/4 less than original 32-bit samples). As 24-bit is native resolution of ADS1278 therefore this has no impact on measurement precision (no real downsampling).
Also transfers are performed using maximal possible buffer size for BULK transfers (close to TMS320VC5509A's limit 64kB) which gives maximal performance.
As MMB0 has 16MB of SDRAM memory it gives additional advantage when handling short time gathering even for sampling rates out of USB 1.1 transfer possibilities.
SDRAM used as cyclic buffer stores data before transfer and in case of overflow acquisition is stopped, but gathered data can be transferred to PC. Please also note that due to transfer being parallel to acquisition real acquisition length is more than SDRAM size (some data is transferred and additional acquisitions can be stored before overflow takes place).
As SDRAM buffer usage is critical parameter for application performance, MMB0's led segment is used to present digit which represents decimals of buffer usage (and letter 'o' in case of overflow).
To gather data transferred using USB interface, simple app was developed. The app handles start and stop commands and stores gathered data to a file.
Application parameters allows for easy setup i.e. to specify cpu clock (via APLL divider and multiplier), 5509 output clock divider, also settings for external PLL (for ADS1278 clock) shall be specified (multiplier and dividers). The settings allows for arbitrary sample rate selection.
Beside clocks ADS operating settings shall be specified i.e. CLKDIV 1 or 0 and mode (highspeed, highresolution, lowpower or lowspeed).
Here are results obtained for maximal transfer rates for each mode (acquisition time before overflow occurs)
Generally maximal sampling which can be performed without overflow (or with overflow after long time) is about 45kSPS (for 8 channels).
Please note that other devices connected to USB host may influence bandwidth for transfer. Also I have noticed with my computer that USB 2.0 host has better max throughput for USB 1.1 connection than USB 3.0 host.
TODO list:
Solution presented below is development of first Linux approach presented here.
ADS1278EVM-PDK is delivered with ready to use Windows software called ADCPro which is post processing tool for data gathered. The tool is build using LabVIEW environment and allows for basic estimation of A/D converter features and performance.
Main weakness of ADCPro (which is of course out of its original purpose) is lack of data streaming handling. Data acquisition is realized within MMB0 using its 16MB SDRAM memory. After acquisition is finished, data is transferred to PC for further analysis and presentation. This of course limits length of data that can be acquired in single measurement.
It is tempting idea to create alternative software to provide data streaming from MMB0 functionality. Obvious limitation here is USB 1.1 used in TMS320VC5509A which drives MMB0 (Rev.D in my case).
For USB 1.1 bandwidth is practically limited to about 1MB/s, which does not allow for all 8 channels utilisation with high sample rate. But this limitation makes the problem even more attractive - try to get all possible performance from MMB0 and check limits of USB 1.1.
Prepared solution contains two parts: firmware for MMB0 prepared with free Linux version of CCS and simple PC (Linux) app for control and data acquisition.
In order to limit usage of precious bandwidth data samples transferred to PC are 24-bit length (1/4 less than original 32-bit samples). As 24-bit is native resolution of ADS1278 therefore this has no impact on measurement precision (no real downsampling).
Also transfers are performed using maximal possible buffer size for BULK transfers (close to TMS320VC5509A's limit 64kB) which gives maximal performance.
As MMB0 has 16MB of SDRAM memory it gives additional advantage when handling short time gathering even for sampling rates out of USB 1.1 transfer possibilities.
SDRAM used as cyclic buffer stores data before transfer and in case of overflow acquisition is stopped, but gathered data can be transferred to PC. Please also note that due to transfer being parallel to acquisition real acquisition length is more than SDRAM size (some data is transferred and additional acquisitions can be stored before overflow takes place).
As SDRAM buffer usage is critical parameter for application performance, MMB0's led segment is used to present digit which represents decimals of buffer usage (and letter 'o' in case of overflow).
To gather data transferred using USB interface, simple app was developed. The app handles start and stop commands and stores gathered data to a file.
Application parameters allows for easy setup i.e. to specify cpu clock (via APLL divider and multiplier), 5509 output clock divider, also settings for external PLL (for ADS1278 clock) shall be specified (multiplier and dividers). The settings allows for arbitrary sample rate selection.
Beside clocks ADS operating settings shall be specified i.e. CLKDIV 1 or 0 and mode (highspeed, highresolution, lowpower or lowspeed).
Here are results obtained for maximal transfer rates for each mode (acquisition time before overflow occurs)
- High-speed mode, 8ch, 144500 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 2), ADS f_clk=36.992 MHz (p: 289, q: 75, post: 10)
max acquisition time ~6.5 sec, acquired 22866480 bytes (in 21.8 sec)
- High-resolution mode, 8ch, 52725 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=26.9952 MHz (p: 703, q: 125, post: 10)
max acquisition time ~70 sec, acquired 89107200 bytes (in 85.7 sec)
- Low-power mode (CLKDIV = 1), 8ch, 52725 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=26.9952 MHz (p: 703, q: 125, post: 10)
max acquisition time ~63 sec, acquired79541280 bytes (in 78.6 sec)
- Low-power mode (CLKDIV = 0), 8ch, 52725 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=13.4976 MHz (p: 703, q: 100, post: 25)
max acquisition time ~63 sec, acquired 79541280 bytes (in 78.5 sec)
- Low-speed mode (CLKDIV = 1), 8ch, 10545 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=26.9952 MHz (p: 703, q: 125, post: 10)
no overflow occurred, continuous streaming possible, average transfer rate ~250kB/s
- Low-speed mode (CLKDIV = 0), 8ch, 10545 SPS, cpu_freq: 192 MHz (m: 16, d: 1, div: 4), ADS f_clk=5.39904 MHz (p: 703, q: 125, post: 50)
no overflow occurred, continuous streaming possible, average transfer rate ~250kB/s
Generally maximal sampling which can be performed without overflow (or with overflow after long time) is about 45kSPS (for 8 channels).
Please note that other devices connected to USB host may influence bandwidth for transfer. Also I have noticed with my computer that USB 2.0 host has better max throughput for USB 1.1 connection than USB 3.0 host.
TODO list:
- Add downsampling to 16-bit option for further bandwidth save and higher sampling rates handling.
- Add possibility to limit number of (or select) channels transferred to have even more bandwidth saving.
- Implement as Linux (and Windows) driver.
Etykiety:
ADS1278,
ADS1278EVM-PDK,
MMB0,
real-time streaming
poniedziałek, 6 stycznia 2014
gcc link-time optimization
Link optimization can give impressive results (at least regarding executable size as presented below).
Here is output from simple program build. The program consists of 3 modules and 2 header files (6 functions in total).
Please note that compilation time and output code speed was not taken into account in simple example consideration above.
Also for sure example is far too simple to treat it as meaningful case, please treat it just as remark of LTO possibilities.
Here is output from simple program build. The program consists of 3 modules and 2 header files (6 functions in total).
- Normal compilation (and linking), no optimization 'gcc mod1.c mod2.c mod3.c -o test'
stripped executable size - 14480. - Normal compilation (and linking), optimized for size 'gcc mod1.c mod2.c mod3.c -o test -Os'
stripped executable size - 10384. - LTO compilation (and linking), no optimization 'gcc mod1.c mod2.c mod3.c -o test -flto'
stripped executable size - 10384. - LTO compilation (and linking), optimized for size 'gcc mod1.c mod2.c mod3.c -o test -flto -Os'
stripped executable size - 6288.
Please note that compilation time and output code speed was not taken into account in simple example consideration above.
Also for sure example is far too simple to treat it as meaningful case, please treat it just as remark of LTO possibilities.
References
poniedziałek, 11 listopada 2013
How to skip every n-th byte in binary file from Linux command
Here is solution to do it from shell using 'xxd' and 'sed'.
E.g. to copy every 4th byte from binary in_file to out_file:
E.g. to copy every 4th byte from binary in_file to out_file:
xxd -p -c4 in_file | sed 's/\(.\{6\}\)\(..\)/\2/g' | xxd -p -r >out_file
Subskrybuj:
Posty (Atom)












