libpruio (fast and easy D/A - I/O)

Thanks for the feedback. I know that I’m far from a good c programmer, but I’m not that bad.

From reading the book “The C++ Programming Language” by Bjarne Stourstrup (the maker of c++) I know a thing or two about the compiler.
First of, all sizeof(…) are replace at compile time. Secondly, all operators that can be calculated at compile time will be calculated at compile time. This makes the last two optimizations you suggest just working with the code harder.

I don’t know if you’ve runned this code your self already, but if you would have noticed that the limiting part is the PRU coprocessor and not actually the ARM processor itself.

With that in mind option 1 is just the flavor of code you choose.

About point 3: If you want to concatenate a integer to a string/char[] there are two options. First you can convert the into to a char[] with itoa() and then use strcat(), or you use the minimal slower spintf which is more readable

And lastly about point 2, if you want to write it to multiple files, you’ll have to close the old one and open the new one every time you go on to the next file.

This programs was for me to test the performance, and as you see from the one seconds sleeps I’ve build into it, it runs fine and a lot faster than it needs to be. Also from any of the examples included to libpruio you can expect the reader not to just copy the code 1:1 and live happily ever after. Everyone will edit it to their liking and performance needs. For me this runs fine and error handling with the file io is something you can implement your self, if you need it. This is example code and not production code…

And on a last note, you’ve made me aware of a little error in my code though, the line:

fwrite(io->Adc->Value, sizeof(uint16), 16000, oFile);

should be

fwrite(io->Adc->Value, sizeof(uint16), bsSize, oFile);

If you want to provide better sample code you’re free to go, but please don’t be that smart-ass stating facts that are only half or not at all true.

Greetings,
Nils Kohrs

If you want to provide better sample code you’re free to go, but please don’t be that smart-ass stating facts that are only half or not at all true.

So, since we’re being rude now. I should mention the code you pasted is C and not C++. I figured you should know this since you think you know everything.

I will tell you what. You keep on trucking on, and nesting while loops 100 deep if you like, and I’ll refrain from reading your posts any further to keep my eyes from bleeding.

Hey TJF,

I wanted to give you a heads up on my samplecode. The performance test was right in that is was that exact performance, but I shouldn’t write a program in c when I’m sleepy.
The program had some functional problems which should be fixed now. However, I’ll first test it with a function generator to make sure that the code is indeed working as expected. If everything is working fine I’ll post it here and you should be able to use it as c samplecode.

Greetings,
Nils Kohrs

Hello Nils,

I just had a closer look at your first example. Sorry, I’ve new concerns. It seems that the code requires to customize the size of the external memory, which is a downside for beginners. And it doesn’t show the ring buffer capabilities (, you could have used MM mode as well).

So for the FreeBASIC folder I created a new example called rb_file.bas

`
/’* \file rb_file.bas
\brief Example: fetch ADC samples in a ring buffer and save to file.

This file contains an example on how to use the ring buffer mode of
libpruio. A fixed step mask of AIN-0, AIN-4 and AIN-7 get sampled and
saved as raw data to some files.

Licence: GPLv3

Copyright 2014 by Thomas{ dOt ]Freiherr[ At ]gmx[ DoT }net

Compile by: fbc -w all rb_file.bas

\since 0.2
'/

’ include libpruio
#INCLUDE ONCE “…/pruio/pruio.bi”

CONST tSamp = 123401 _ '< The number of samples in the files (per step).
, tmr = 5000 _ '
< The sampling rate in ns (5000 → 200 kHz).
, NoStep = 3 _ '< The number of active steps (must match setStep calls and mask).
, NoFile = 2 _ '
< The number of files to write.
, NamFil = “output.” '*< The output file names.

VAR io = NEW PruIo() '*< Create a PruIo structure, wakeup subsystems.

WITH *io
DO
IF .Errr THEN ?"NEW failed: " & *.Errr : EXIT DO

IF .Adc->setStep( 9, 0, 0, 0, 0) THEN _
?"step 9 configuration failed: " & *.Errr : EXIT DO
IF .Adc->setStep(10, 1, 0, 0, 0) THEN _
?"step 10 configuration failed: " & *.Errr : EXIT DO
IF .Adc->setStep(11, 2, 0, 0, 0) THEN _
?"step 11 configuration failed: " & *.Errr : EXIT DO

VAR mask = &b111 SHL 9 _ '< The active steps (9 to 11).
, tInd = tSamp * NoStep _ '
< The maximum total index.
, half = ((.ESize SHR 2) \ NoStep) * NoStep '*< The maximum index of the half ring buffer.

IF half > tInd THEN half = tInd ’ adapt size for small files
VAR samp = (half SHL 1) \ NoStep '*< The number of samples (per step).

IF .config(samp, mask, tmr, 0) THEN _ ’ configure driver
?"config failed: " & *.Errr : EXIT DO

IF .rb_start() THEN _ ’ start ring buffer mode
?"rb_start failed: " & *.Errr : EXIT DO

VAR p0 = .Adc->Value _ '< A pointer to the start of the ring buffer.
, p1 = p0 + half '
< A pointer to the middle of the ring buffer.
FOR n AS INTEGER = 0 TO NoFile - 1
VAR fnam = NamFil & n, fnr = FREEFILE
IF OPEN(fnam FOR OUTPUT AS fnr) THEN
?"Cannot open " & fnam
ELSE
?“Creating file " & fnam
VAR i = 0 '*< Start index.
WHILE i < tInd
i += half
IF i > tInd THEN ’ fetch the rest (no complete chunk)
VAR rest = tInd + half - i _
, iEnd = IIF(p1 >= p0, rest, rest + half)
WHILE .DRam[0] < iEnd : SLEEP 1 : WEND
?” writing samples " & (tInd - rest) & “-” & (tInd - 1)
PUT #fnr, , *p0, rest
SWAP p0, p1 : EXIT DO
END IF

IF p1 > p0 THEN WHILE .DRam[0] < half : SLEEP 1 : WEND _
ELSE WHILE .DRam[0] > half : SLEEP 1 : WEND
?" writing samples " & (i - half) & “-” & (i - 1)
PUT #fnr, , *p0, half
SWAP p0, p1
WEND
?"Finished file " & fnam
CLOSE #fnr
END IF
NEXT
LOOP UNTIL 1
IF .Errr THEN SLEEP
END WITH

DELETE(io)

‘’ help Doxygen to dokument the main code
'&/** The main function. */
'&int main() {PruIo::PruIo(); AdcUddt::setStep(); PruIo::config(); PruIo::~PruIo();}

`

Do you like to translate that code to C to include it in the libpruio package? If so, please add a file header with your copyright notes.

BR

Oups, found a buck right when I posted:

line 70

`
SWAP p0, p1 : EXIT DO

`

should be

`
SWAP p0, p1 : EXIT WHILE

`

Soory!

TJF,

I’d be willing at some point to help you port some code for your project, Do you have a quick setup guide for your library ? I did read some of your documents a couple months ago, but then i got busy with many other things . . . such is life.

Other problem is that I am not exactly a hardware person so much as a software developer, and I am semi new to embedded Linux. The new to embeded Linux part shouldnt be too much of a problem, just means I need to read up on the libc functions available to me. Not being an EE however slows me down greatly however, since I do not want to fry my boards . . .

As an aside, I must have really really become accustomed to C over the last several years, BASIC syntax hurts my eyes, lol but it was the very first language I picked up 17+ years ago . . .

TJF,

I’d be willing at some point to help you port some code for your project,

Hello William, welcome at the libpruio project.

I know about many tasks to improve the libpruio package. Some of them might be fun for you.

Do you have a quick setup guide for your library ?

Find the installation guide in the documentation at page Preparation.

Could you check the documentation text? It seems that you’re a native speaker with good language skills. You should be able to improve the text a lot. (I could mail a pdf version, where you could add your comments.)

Other problem is that I am not exactly a hardware person so much as a software developer, and I am semi new to embedded Linux. The new to embeded Linux part shouldnt be too much of a problem, just means I need to read up on the libc functions available to me. Not being an EE however slows me down greatly however, since I do not want to fry my boards . . .

I’m neither an electronics engineer, nor a programmer, nor an expert on embedded systems, nor a native speaker. I think I realy know what you’re talking about.

I’m looking at the project from the user point of view, evaluating how things should work and then do my best to make this happen. And, knowing there’s no perfect solution, I try to learn from my failures.

As an aside, I must have really really become accustomed to C over the last several years, BASIC syntax hurts my eyes, lol but it was the very first language I picked up 17+ years ago . . .

Basic isn’t the first programming language I used, but for me it’s the most productive. I’m not speaking about the m$ dialects, which I dislike as well, and which I don’t use since the middle 80’s. (AFAIR QB 4.5 was the last one I tested and droped.) But there’re other dialects, which are in some points more powerful than C, and easier to read for my old eyes.

The libpruio package contains some examples, as you can see at this documentation page. I think all code in folder src/c_examples could have a review. But most important, there’re some examples with grafics output

  • pwm_adc.bas,

  • osci.bas,

  • rb_oszi.bas, and

  • triggers.bas

which I didn’t translate to C code jet. My idea was to use cairo grafics library, but there might be a more common way to create short and easy C code?

Note: libpruio examples should be easy to understand for beginners and should have less than 200 lines of code.

Feel free to send further colaboration ideas and discuss details (here or PM). Or just make your choice and start.

BR

Back in the early to mid 80’s I was living in Kitzingen,Germany, and I was young. If you catch my meaning.

But anyway, I am still a bit busy, but perhaps in my spare time I can read your documentation a bit at a time to be used to it. It is something I’ve been wanting to do for a while now . . .

Back in the early to mid 80’s I was living in Kitzingen,Germany, and I was young. If you catch my meaning.

A “Franke”, I see. Most of my mess mates were coming from the Würzburg and Aschaffenburg area.

Your surname sounds German. I’m not living in Germany any more. I moved to the “Schluchtenscheißers”.

But anyway, I am still a bit busy, but perhaps in my spare time I can read your documentation a bit at a time to be used to it. It is something I’ve been wanting to do for a while now . . .

May I send (private mail) a pdf version of the documentation? You could add notes to that document to improve the text.

Sure. However I am afraid my German reading skills ( translation ) are terrible now days. I will do what I can.

Hey,

I’m trying to match the below modification in my version of libpruio, but while compiling I run into the following

`

ld: pruio.o: relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol’ can not be used when making a shared object; recompile with -fPIC

`

and I’m not sure how to get past it. I -think- that I have the freebasic compiler running correctly. Any advice would be welcome.

Thanks,
Michael Todd

Hi Michael,

Hello TJF,

thanks for librpuio and the effort you spent for this.

I followed the instructions on the side above, but still can not compile the FB examples:

  • I run a BBB with a very new Debian Linux image.
  • I installed everything according the documentation on the above link.
  • fbc is working:

fbc -version
FreeBASIC Compiler - Version 1.01.0 (10-14-2014), built for linux-arm (32bit) Copyright © 2004-2014 The FreeBASIC development team.

However, compiling an FB example yields:

libpruio-0.2/src/examples# fbc -w all analyse.bas
/usr/local/include/freebasic/BBB/prussdrv.bi(56) error 23: File not found, “crt/sys/types.bi” in '#INCLUDE ONCE “crt/sys/types.bi” ‘HEADERS: sys/types.h’

  • I have searched my system manually for “types.bi”, but there is none.

Do you have any suggestions what might be missing to compile the libpruio FB examples?
Btw. The C-examples can be compiled without errors.

Thanks.

Hallo Herr Vogelfrei,

ich hoffe, dass eine deutschsprachige Antwort in Ihrem Sinne ist und
bedanke mich für das Interesse an libpruio.

However, compiling an FB example yields: libpruio-0.2/src/examples#
fbc -w all analyse.bas
/usr/local/include/freebasic/BBB/prussdrv.bi(56) error 23: File not
found, "crt/sys/types.bi" in '#INCLUDE ONCE "crt/sys/types.bi"
'__HEADERS__: sys/types.h'

- I have searched my system manually for "types.bi", but there is
none.

Do you have any suggestions what might be missing to compile the
libpruio FB examples?

Bitte beachten Sie folgenden Satz auf der deutschen Downlaodseite:

Diese fbc Version ist nicht vollständig. Fehlende Dateien, z. B.
Header oder Beispiele, können aus dem GIT Repository bezogen und
nachinstalliert werden.

Mittlerweile habe ich auch ein Debian Paket erstellt, welches die
Installation vereinfachen soll. Dieses ist hier zu finden:

Da ich bisher keine Zeit hatte das Paket zu testen, würde ich mich
über Ihre Rückmeldung sehr freuen. (Bitte beachten: das Paket
installiert in /usr, nicht in /usr/local. Ggf. vorhandene Dateien und
Ordner in /usr/local vor der Installation löschen.)

MfG

[SOLVED]

Hello TJF,

I will answer in English to give other users the possibility to use this information as well.

Thank you for your answer. With this information I was able to compile the supplied libpruio FreeBASIC examples.

Steps to take (on the BeagleBone, as root, otherwise use ‘sudo’):

1.) wget http://www.freebasic-portal.de/dlfiles/625/freebasic_1.01.0debian7_armhf.deb
2.) dpkg --install freebasic_1.01.0debian7_armhf.deb
(Note: On http://www.freebasic-portal.de/downloads/fb-on-arm/debian-package-fbc-1-01-357.html
you type: freebasic_1.01.0~debian7_armhf.deb which make copy and paste from the website resulting in an error)
3.) apt-get -f install
4.) rm /usr/local/bin/fbc
5.) reboot
6.) cp -R /usr/local/include/freebasic/BBB /usr/include/freebasic/

After this, compiling fbc -w all analyse.bas works.

Thank you.

Thanks for feedback!

BR

Hi TJF,

I am trying to use the example you provided here to sample an analog signal.
With the default setting of tmr=5000, I am getting configuration error:

config failed: sample rate too big

It works with tmr=20000 and dumps the data into 2 files. Though the data looks to be in binary format.

Could there be something in my setup that may need tweaking to run this at 200KHz?
I am using libpruio v0.2 and installed it following the steps mentioned here.

Thanks,
Akshay

Hi Akshay!

I am trying to use the example you provided here to sample an analog signal.

I guess you’re refering to the example rb_file, which is sampling three analog signals?

With the default setting of tmr=5000, I am getting configuration error:

config failed: sample rate too big

It works with tmr=20000 and dumps the data into 2 files. Though the data looks to be in binary format.

Could there be something in my setup that may need tweaking to run this at 200KHz?
I am using libpruio v0.2 and installed it following the steps mentioned here.

This example is pre-published (from next version). In libpruio-0.2 the limit checking for the timer value is too rigid. See this post on how to fix this.

BR

Hi TJF,
I’m trying to solve the bug as you described to niro some posts ahead.
After I’ve followed the instruction on the library site, I’ve:

`
cd pruio/
vim pruio_adc.bas (modify buggy lines)
./make.sh
./build.sh

`

After that a file named libpruio.so appear in the current directory
The problem is that I can’t build anything with that lib. When I try to compile the c_example shipped with the library
I run into the annoying error

sos.c:(.text+0x128): undefined reference to `pruio_new’ ecc

I’m doing something wrong? Why the libpruio library that I build doesn’t export the pruio_* functions?

Thanks,
Andrea

Hi Andrea!

It compiles OK, but the linker doesn't find the symbols (= doesn't find the binary libpruio.so).

Where did you place the new binary? It should work when you override the original binary (ie. in /usr/local/lib). Otherwise you have to update the linker cache first:

sudo ldconfig

Or you can instruct the linker to search for libraries in a custom path, like (for the current directory)

LD_LIBRARY_PATH="." & ANY_COMPILE_COMMAND

See your linker manual for details (this issue is not related to libpruio).

BR