Alternative C++ Code for GPIO Access (now with Interrupts and EXPLED)



  • I have produce some alternative C++ code for accessing GPIO since I wanted some additional capabilities over those provided by fast-gpio.

    Rather than detailing what I have done in this post, I attach to this post an archive file (new-gpio.tar.bz2) that contains all the relevant files including documentation in the file PDF new-gpio.pdf included in the archive.

    Note that this is an ongoing work and there will be updates in the future.

    I would be most interested in any comments, feedback etc. from others.
    Attached file: new-gpio.tar.bz2



  • For anyone who is interested, I have now updated my new-gpio code and documentation to include PWM access to the GPIO pins.

    The archive file (new-gpio.tar.bz2) with all the changes is attached.
    Attached file: new-gpio.tar.bz2



  • @Kit-Bishop
    HI Kit,

    Great work, a kickstart for me as a C++ programmer.

    Could you also provide the makefiles for the library and gpiotest, I am always interested in how other people do things and see how I can improve my own makefiles (not an expert in that)

    thx, Jo



  • @Johan-Simons Thank you for the kind words and glad my contribution is helpful.
    The code I posted was built using the NetBeans IDE. As a consequence, I don't have immediately on hand makefiles to do the building.
    However, I think I may be able to extract the makefiles - it may take me a little while to do so. I will post them here when I have done so.



  • I have now updated my new-gpio code and documentation to fully handle interrupts on the GPIO pins.

    You should read the documentation in the attached file first since there are a couple of pre-requisites that must be fulfilled.

    The archive file (new-gpio-1.2.tar.bz2) with all the changes is attached.
    Attached file:new-gpio-1.2.tar.bz2

    You may also be interested in: https://community.onion.io/topic/431/access-to-gpio-including-interrupts-using-new-gpio-test-program-and-library - which just supplies the library, test program and basic documentation on the just the usage of program.



  • @Kit-Bishop Hey Kit, this is awesome work. Could I help get this posted to Github so people could access it that way? If you're not interested in having it under your account (or if you don't have an account and don't want to create one) I'd be happy to put it in mine and give full attribution to you. Thanks again for creating this.

    Kevin



  • @Kevin-Sidwar Any assistance on that would be great šŸ™‚
    While I have only just recently created myself a Github account i haven't yet got to grips with using it šŸ˜ž I am much more familiar with SVN for code repository (I manage my code on a local SVN repository). I like the ideas in git but haven't really used it much.

    Some things I'd like to do with the code I posted but haven't done yet:

    1. Produce some basic makefiles to build it
      I use Netbeans 8.1 with access to the OpenWrt toolchain setup for all my building.
      But i appreciate that this is not for eveyrone and a more basic method would be of use
    2. Make the code buildable under the OpenWrt build environment (as in: https://wiki.onion.io/Tutorials/Cross-Compile) with the capability of producing .ipk package(s) installable via opkg
      I am still in the process of trying to figure out all the details for this

    So I would be grateful for anything you might be able to do (I could probably learn from it). I am Ok if you want to put it on your own repository (with attribution :-))
    Thanks


  • administrators

    @Kit-Bishop @Kevin-Sidwar
    Would you guys be interested in amalgamating new-gpio with Onion's fast-gpio package?

    That way we can push out any and all new features to the entire Omega userbase at once through the firmware. The fast-gpio repository can be found here: https://github.com/OnionIoT/fast-gpio

    Let me know what you think!



  • @Lazar-Demin In principle I have no problem at all with what you suggest.
    Other than for my own use, I like to be able to contribute anything I find useful to the community in case it is useful to others so whatever is best for this suits me. šŸ™‚

    I presume that as the result of the amalgamation, there would be 3 separate entities:

    1. fast-gpio program (and associated expled.sh script)
    2. My libnew-gpio.so dynamic library
    3. My new-gpiotest program

    I also think that it would be helpful to others if the documentation I have provided be included some where (though possibly modified as appropriate).

    If you want to rename either the library or the program, I am quite fine with that



  • @Lazar-Demin If it is of any use to you or the Omega community in general, I am currently working on Java wrappers and a Java test program for access to GPIO pins. It is largely working at present but I still have a bit of work to do to handle interrupts in Java.

    The code I have working at present runs find under Jamvm (but note that to install Jamvm you need to have more disk space by using (e.g.) the pivot-overlay method in https://wiki.onion.io/Tutorials/Using-USB-Storage-as-Rootfs)

    Implementation of the Java code directly parallels in Java everything in the new-gpio library and test program I have previously posted.

    The Java code consists of 3 components:

    1. libNew-GpioJava.so - a C/C++ dynamic link library that implments the JNI bridge between the Java code and the libnew_gpio.so library as previously referenced.
      This needs to be installed in /lib or LD_LIBRARY_PATH
    2. Java code of a test program that parallels in Java the in my C/C++ program new-gpiotest - this code is built in to a JavaNew-GPIOTest.jar file. It requires the above two files to be installed. It can be run as:
      • jamvm -jar JavaNew-GPIOTest.jar <parameters>
        This Java program uses the Java librar code as in JavaNew_Gpio.jar below
    3. Java code that parallels in Java the code for GPIOAccess and GPIOPin available in C/C++ - this produces a JavaNew_Gpio.jar file containing the Java classes
      This file needs to be in the directory ./lib relative to the location of JavaNew-GPIOTest.jar or any other Java program that uses it


  • @Lazar-Demin I'm happy to help in any way possible. I was just going to set up a Github repo for @Kit-Bishop 's stuff so changes could be pushed there for easy access but if you'd like I can put together a pull request that brings his code in. @Lazar-Demin if you want to comment on Kit's questions about what the amalgamation would look like and what you're thinking I can do the PR. Just let me know.


  • administrators

    @Kevin-Sidwar @Kit-Bishop
    I've only taken a cursory look at the new-gpio C++ code but it seems like it's based on fast-gpio with a few intermediate layers and a bunch of additions. So I was thinking that the fast-gpio code could be updated to include all of the new features/structure that are in new-gpio, specifically the edge detection interrupts.

    So the amalgamation would contain:

    1. a dynamic library based on the amalgamated code
    2. fast-gpio program (with the edge detection updates)
    3. a C++ based program to replace the expled script (I've been meaning to do this for a while)

    As for the gpio-test program, we have a package available on the Onion Package Repo based on this: https://github.com/OnionIoT/gpio-test
    I think it would be best if we kept that as a separate package since it might not be useful to everyone.

    If you guys are in agreement, you can go ahead and make a pull request to the fast-gpio repo



  • @Lazar-Demin I am happy with whatever you want to do with the code šŸ™‚

    You are correct that it is in part based on fast-gpio (as I stated in the documentation), however, from my perspective there are some important differences and improvements. The significant differences are:

    1. It separates out the hardware access in the class GPIOAccess that implements all the hardware access via static methods. The GPIOPin class represents individual pins and does NOT contain any hardware specific code. This all provides what I believe to be a better level of encapsulation.
      That said, if one so desires all access to the pins themselves can be done via GPIOAccess alone. Having the GPIOPin class gives a better object oriented view to the access.
    2. I have tried to incorporate a relatively light weight but consistent approach to error detection and handling throughout
    3. In my code, PWM is run in a thread and consequently can be stopped and started independently from within a single program for multiple pins. In the original fast-gpio, starting PWM on a pin puts the code in to a permanent loop and can only be used by the more heavy weight process of forking the program. This makes it much harder to incorporate the code in a single program that uses multiple PWM pins
    4. My code completely handles interrupts on multiple pins in an object oriented way using a threading approach - this was totally lacking from fast-gpio
    5. My code primarily consists of the libnew-gpio.so library usable from any other code. The new-gpiotest program is effectively just a (different) version of the code that is in the main.c code in fast-gpio and is intended for 2 purposes for those who may need it:
      • As a test bed for the libnew-gpio.so library
      • As a tool that could be run from the command line and/or scripts for those who want such access

    My primary motivations for writing the code were:
    a. I felt a better object oriented approach was needed
    b. I want to be able to write code in Java (to run under jamvm) and needed underlying code that can be accessed from Java using JNI

    As I have said, feel free to do whatever you want with my code (I feel no strong proprietary claim to it - its just my contribution to anyone who is interested). You can:

    • Use it as is
    • Pull code out of it for other uses
    • Ignore it

    Whatever you want šŸ™‚



  • @Kit Bishop

    Your new-gpio program does look awesome šŸ™‚
    Great work on that!

    As GPIOs are 'normally' handled by sysfs and files like
    /sys/class/gpio/gpioN/edge
    /sys/class/gpio/gpioN/direction
    /sys/class/gpio/gpioN/value

    get created, whereas /sys/class/gpio/gpioN/value can be used to poll the interrupt status (1 | 0) and /sys/class/gpio/gpioN/edge shows the interrupt' s state.

    I was wondering weather this is possible to achieve with your program.
    As sysfs handles /sys/class/gpio .... i suppose those files should be created elsewhere?
    Or do they already get created somewhere?

    BR
    Mar!


  • administrators

    @Kit-Bishop @Kevin-Sidwar
    Kit, yep, I like all of the features (code and functionality) you have in new-gpio. I was hoping that Kevin and yourself could spearhead the amalgamation process, and that I could just chime in when needed.
    Let me know if you guys are ok with that!



  • @Mark-Alexander Regarding the use of the various sys/class/gpio/gpioN/* files : these are created by writing the pin number to /sys/class/gpio/export (and removed by writing the pin number to /sys/class/gpio/unexport) - see: https://www.kernel.org/doc/Documentation/gpio/sysfs.txt

    I looked at using these but there seems to be some issue with the sysfs on the Omega that I couldn't figure out. No matter what I did, there was never any /sys/class/gpio/gpioN/edge file.

    So, most of the code for accessing the pins goes via direct access to the memory registers for the GPIO pins (as in the original fast-gpio) - dealing with interrupts makes use of writing to the /sys/kernel/debug/gpio-irq file which causes entries to be added/removed from the /sys/kernel/debug/gpio file to control the interrupt handling.



  • @Lazar-Demin All good. I will see what I can do. Though there are some aspects of dealing with git and setting up building of modules under the OpenWrt build environment that I am unfamiliar with and will need help from @Kevin-Sidwar or yourself.

    @Kevin-Sidwar and I have already been in brief e-mail communication on this. It might help (and remove pollution from this post if you sent us a brief e-mail describing what you would see as the aims and end product of the amalgamation including any specific features you would want to see.



  • @Kit-Bishop
    yeha, i know these files do get created by sysfs.

    As some programs might have the need for polling interrupt state:
    Is it possible for you to change your code, that files like
    /sys/class/gpio/gpioN/edge
    /sys/class/gpio/gpioN/value
    get created somewhere else?
    in order to get pollable files, which look just like them?
    e.g.
    1 | 0 in /pathsomewhere/gpioN/value
    rising | falling | both in /pathsomewhere/gpioN/edge
    in | out in /pathsomewhere/gpioN/direction

    [ Polling from /sys/kernel/debug/gpio does not seem to be the very best idea, as all GPIO interrupts are written right there.

    In order to be able to use polling correctly on those files, they need to support POLLPRI (methode?)
    stackoverflow.com/questions/15422919/difference-between-pollin-and-pollpri-in-poll-syscall ) ]

    That seems to be quite a handy feature, if there already is a program which needs to poll interrupt states of a given pin, one would not have the need of 'massive' code changes.



  • @Mark-Alexander Some points regarding the /sys/class/gpio/gpioN/* files etc:

    • Not sure why you would want to put these files elsewhere. They are already accessible from anywhere (once they have been created by writing to /sys/class/gpio/export)
    • These are NOT files that my code creates they are part of the standard sysfs for GPIO
    • If you really want to be able to access these files in a different directory, you could always set up symbolic links to them - they themselves are already accessed via symbolic links: e.g. /sys/class/gpio/gpioN is just a symbolic link to /sys/devices/virtual/gpio/gpioN
    • I contemplated implementing my C++ code by making access to these files, but decided on the direct access to the memory registers for GPIO pins as was already being done by the standard Omega fast-gpio since it is faster and more compact
    • As explained earlier, I spent quite a lot of time in looking at the possible usage of /sys/class/gpio/gpioN/edge along with the use of POLLPRI. However, I got nowhere with this since the Omega does not create the edge file for GPIO pins. Neither I nor the Omega people can figure out why it doesn't, hence my eventual use of the /sys/kernel/debug/gpio-irq to register interrupt handlers.

    Not sure what you mean by not have the need of 'massive' code changes.
    No matter what method is used to access the functionality, one is going to need write some code to access that functionality.
    The libnew-gpio.so library I provided is a C++ library that can easily be linked to and called from any C++ code you may write.
    E.G. some sample code snippets:

    • // Include necessary header
      #include "GPIOPin.h"
      //
      // Declare function to handle interrupt
      void handleInterrupt (int pin, GPIO_Irq_Type type)
      {
      // code to be executed on interrupt
      }
      // Some code snippets:
      // 1. Create a pin instance for pin 6
      GPIOPin * pin6 = new GPIOPin(6);
      // 2. Set it for output
      pin6->setDirection(GPIO_OUTPUT);
      // 3. Set output value
      pin6->set(1);
      // 4. Setup for and register interrupt to be trigger on rising edge
      pin6->setDirection(GPIO_INPUT);
      pin6->setIrq(GPIO_IRQ_RISING, handleInterrupt);


  • I have made various updates to my new-gpio code and documentation.

    The archive file (new-gpio-1.3.tar.bz2) with all the changes is attached.
    Attaches file:new-gpio-1.3.tar.bz2

    In particular, you should read the file new-gpio.pdf that is included in the archive file.

    In summary, the changes in this latest version are:

    • Some re-organisation of packaged components and component renaming
    • The new-gpiotest program is now just named new-gpio
    • Provided Makefile files for all components
    • Added both static and dynamic link versions of all components
    • Added new class, RGBLED, for control of RGB leds (e.g. as in expansion led)
    • Changed syntax of parameters to new-gpio program to be the same (where relevant) as is used for the existing fast-gpio program
    • Added additional operations to new-gpio program for control of expansion led
    • Added new program new-expled, that does the same as the existing expled script but written in C++ using libnew-gpio library


  • I have found a small bug in the Makefile for libnew-gpio in the archive file I posted yesterday.

    I have corrected this and the attached updated archive (new-gpio-1.3.1.tar.bz2) contains the corrected version.
    Attached file:new-gpio-1.3.1.tar.bz2



Looks like your connection to Community was lost, please wait while we try to reconnect.