Alternative C++ Code for GPIO Access (now with Interrupts and EXPLED)
-
@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.
-
@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:
- a dynamic library based on the amalgamated code
- fast-gpio program (with the edge detection updates)
- 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:
- 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. - I have tried to incorporate a relatively light weight but consistent approach to error detection and handling throughout
- 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
- My code completely handles interrupts on multiple pins in an object oriented way using a threading approach - this was totally lacking from fast-gpio
- 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 JNIAs 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
- 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.
-
@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/valueget 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!
-
@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.bz2In 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
-
Code now on GitHub
I have now setup a GitHub repository for all my new-gpio code.
The repository can be found at https://github.com/KitBishop/new-gpio
It currently contains the version 1.3.1 code as has been supplied in new-gpio-1.3.1.tar.bz2
In future, when I make any updates to the code, it will be found in the referenced repository
-
@Kit-Bishop Sorry for the radio silence. I just realized tonight that my preferences were set up to NOT email me when mentioned or watching a post (fixed now). I had actually created a Git repo that I was going to transfer over to you but I see that you created one under your account. Awesome work! And sorry again for going silent on this thread.
-
FYI: Code on https://github.com/KitBishop/new-gpio has now been updated to version 1.3.2
No functional changes, just:- Some reorganisation of source code
- Improvements to Makefiles
See the new-gpio.pdf file for details
-
FYI: Code on https://github.com/KitBishop/new-gpio has now been updated to version 1.3.3
Changes are:- Added rgb <r> <g> <b> parameters to new-gpio expled and new-expled to provide the expansion led settings as 3 decimal values in the range 0..100