C GPIO library


26 posts   Page 1 of 2   1, 2
by LandyManLuke » Fri Jun 29, 2012 12:04 pm
Hi all,

Has anyone written a straight forward C library for GPIO access?

I'm not interested in Arduino style libraries, as I have not used Arduinos at all.

Regards,

Luke
Posts: 14
Joined: Tue Jun 05, 2012 9:45 pm
by TonyD » Fri Jun 29, 2012 1:10 pm
Tony
User avatar
Posts: 342
Joined: Thu Sep 08, 2011 10:58 am
Location: Newcastle, UK
by panik » Fri Jun 29, 2012 1:18 pm
And if you're looking for I2C or SPI, have a look here: http://www.bootc.net/projects/raspberry-pi-kernel/
User avatar
Posts: 273
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by LandyManLuke » Fri Jun 29, 2012 1:26 pm


Mike McCauley's library looks like exactly what I am after, I think I'll try that.

The second link is to the Arduino style library, which I'm sure makes sense to those who've used Arduino, but I haven't, and would rather not complicate things.

Luke
Posts: 14
Joined: Tue Jun 05, 2012 9:45 pm
by fridgefreezer » Fri Jun 29, 2012 2:23 pm
Hi Luke - fancy bumping into you here! :mrgreen:
Posts: 12
Joined: Thu Jun 21, 2012 8:50 am
by panik » Fri Jun 29, 2012 3:28 pm
LandyManLuke wrote:Mike McCauley's library looks like exactly what I am after, I think I'll try that.

There's a topic about it here: viewtopic.php?f=44&t=9230
User avatar
Posts: 273
Joined: Fri Sep 23, 2011 12:29 pm
Location: Netherlands
by pjc123 » Sat Jun 30, 2012 11:44 am
LandyManLuke wrote:Hi all,

Has anyone written a straight forward C library for GPIO access?

I'm not interested in Arduino style libraries, as I have not used Arduinos at all.

Regards,

Luke


All my electronic parts arrived yesterday to start playing around with the GPIO pins and I just need to pick a C library since that is the language that I am most familiar with. I am curious what you mean by "Arduino style library"? Are you just referring to the pin numbering? I have no plans on getting an Arduino, so I was wondering what the difference was.
Posts: 910
Joined: Thu Mar 29, 2012 3:37 pm
by gordon@drogon.net » Mon Jul 09, 2012 9:36 am
pjc123 wrote:
LandyManLuke wrote:Hi all,

Has anyone written a straight forward C library for GPIO access?

I'm not interested in Arduino style libraries, as I have not used Arduinos at all.

Regards,

Luke


All my electronic parts arrived yesterday to start playing around with the GPIO pins and I just need to pick a C library since that is the language that I am most familiar with. I am curious what you mean by "Arduino style library"? Are you just referring to the pin numbering? I have no plans on getting an Arduino, so I was wondering what the difference was.


FWIW: I originally designed wiringPi to look like Arduino style "wiring" interfacing. There you have a notion of a "pin" which has been abstracted away from the real hardware. So in Arduino-land, you have (e.g.) Pin 13 which in real terms means port B, pin 5 (on an Arduino with an ATmegaxx8 chip - on other Arduinos it could quite possibly be a different on-board port and pin, but the external pin you physically connect to would still be "Pin 13" - you just link with a library for the board your using...

So in wiringPi, I started my pins at 0 and went up from there. There is a 1:1 relation between wiringPi pins and the GPIO pins, and it's fairly easy to use.

However... After much criticism (not from Arduino programmers!) I've added in facilities to use native GPIO pin numbering too. It's not realy issue, use one set of numbers or the other. Pin 0 is GPIO 17, pin 1 is GPIO 18, pin7 is GPIO 4 and so on. See the table at

https://projects.drogon.net/raspberry-pi/wiringpi/pins/

for the details.

The functions I wrote, do reflect the arduino wiring functions, so:

digitalWrite (pin, value);
x = digitalRead (pin) ;

and so on. Pull-up and pull-down control is slightly different to that on an arduino though (arduino doesn't have pull-down for example).

Also, a recent addition to the gpio program (part of the wiringPi package) allows you to do (simple) GPIO programming via the command-line as a non-root user, and you can also use it to "export" GPIO pins which can then be accessed again from a non-root program... (Even a non wiringPi program - e.g. Python) as it changes the user-id of the 'value' file to that of the calling user, so write a little shell script to 'export' the GPIOs your using (and which direction), then you can run your C, Python, Ruby, PHP, Perl, etc. program which accesses the /sys/class/gpio interface without the need to be root, or use sudo.

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1541
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by pjc123 » Mon Jul 09, 2012 10:56 am
For no particular reason I am already using this library and everything works great:

http://www.open.com.au/mikem/bcm2835/

The whole pin number thing is a quite silly concern, since it can just be compensated for or taken into consideration when the user writes his/her code.
Posts: 910
Joined: Thu Mar 29, 2012 3:37 pm
by Grumpy Mike » Mon Jul 09, 2012 5:06 pm
pjc123 wrote:The whole pin number thing is a quite silly concern, since it can just be compensated for or taken into consideration when the user writes his/her code.

Only if you know what numbering sachem you are using and understand the implications.

Why the whole concept of a GPIO library itself is redundant according to this line of thinking, just use the ARM peripheral addresses to access the right register.
User avatar
Posts: 784
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
by brunialti » Wed Jul 25, 2012 3:58 pm
Nice to know there is a library using the wiring approach.
It is very simple to use.
Posts: 17
Joined: Sat Jun 09, 2012 9:11 am
by Ivan001 » Wed Aug 01, 2012 7:58 am
I have to give Gordon a +1 and thanks for the WiringPi library. I tried it out with my first project at the weekend and it was so easy to use and I had my temperature sensor working quite quickly.
I moved to using WiringPi after spending ages trying to get the i2c kernel driver working only to find that it didn't detect my device.

Now if only I knew how to get WiringPi projects to work without having to use sudo? anyone?
Ivan
Posts: 3
Joined: Wed Aug 01, 2012 7:51 am
by gordon@drogon.net » Wed Aug 01, 2012 8:30 am
Ivan001 wrote:I have to give Gordon a +1 and thanks for the WiringPi library. I tried it out with my first project at the weekend and it was so easy to use and I had my temperature sensor working quite quickly.
I moved to using WiringPi after spending ages trying to get the i2c kernel driver working only to find that it didn't detect my device.

Now if only I knew how to get WiringPi projects to work without having to use sudo? anyone?
Ivan


Get the latest wiringPi and then:

1. use the gpio command to export the pins you need.
2. initialise wiringPi in your code with:

x = wiringPiSetupSys () ;

and you don't need to use sudo to run your program.

You can even use the gpio command from inside your program:

Code: Select all
  system ("gpio unexportall") ;
  system ("gpio export 17 in") ;
  system ("gpio export 18 out") ;


etc.


bit crude but it does what you need.

See https://projects.drogon.net/raspberry-pi/wiringpi/the-gpio-utility/

It's somewhat slower than the native methods as it's going via the /sys/class/gpio interface, however it does mean that you can run your program without needing to be root at all.

(And you can use the gpio export mechanism to export the /sys/class/gpio pins for other programming languages - so no need for sudo for Python, perl, php, etc. programs - just comment out the usual setup/export instructions in your code, or replace them with the languages equivalent of the system() call)

What you can't do in this mode is set the direction, or the pull-up/down controls, so you need to do all this with the gpio program beforehand.

And I'm thinking that that's probably fine - so to do with your program might be a little shell-script that does the exports, etc. beforehand, then you run your program...

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1541
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by pygmy_giant » Wed Aug 01, 2012 10:11 am
grumpy mike said
... the whole concept of a GPIO library itself is redundant according to this line of thinking, just use the ARM peripheral addresses to access the right register.


according to http://infocenter.arm.com/help/index.js ... a3750.html you can do this:

#define PORTBASE 0x40000000
unsigned long int volatile * const port = (unsigned int *) PORTBASE;
*port = value; // write to port
value = *port; // read from port

although I have not tried it. My understanding is that addressing works differently from user space than it does from kernal space or on the bare metal due to linux employing a virtual memory map to control processes.

I don't really understand this yet but heres a diagram:

Image
Last edited by pygmy_giant on Wed Aug 01, 2012 10:37 am, edited 1 time in total.
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by gordon@drogon.net » Wed Aug 01, 2012 10:35 am
pygmy_giant wrote:grumpy mike said
... the whole concept of a GPIO library itself is redundant according to this line of thinking, just use the ARM peripheral addresses to access the right register.


according to http://infocenter.arm.com/help/index.js ... a3750.html you can do this:

#define PORTBASE 0x40000000
unsigned long int volatile * const port = (unsigned int *) PORTBASE;
*port = value; // write to port
value = *port; // read from port

although I have not tried it. My understanding is that addressing works differently from user space than it does from kernal space or on the bare metal due to linux employing a virtual memory map to control processes.

I don't really understand this yet but if anyone can shed light on it I would be grateful.


That's essentially what you do, (although the magic number is 0x20000000), but with the Pi, we have the situation where we have an operating system in the way of the hardware, and having a virtual memory mapping system is an integral part of the operating system which further complicates matters.

The truth is, Linux (and Unix in-general) really isn't designed for this sort of low-level access from user programs. Linux/Unix "owns" the hardware and provides standard mechamisms to allow user access.

Linux provides us with the /sys/class/gpio mechanism which hides the underlying hardware from us - however you need to be root to access the gpio via that mechanism (but you can subsequently access it from a user program if you set it up correctly). And again, traditionally in a Linux/Unix environment, running programs randomly as root is to be avoided due to the security implications...

But we all do it - we have to id we want any sort of GPIO access - and we have a generation of people used to microcontrollers like the ATmega (arduino) and PIC and older home computers and so on...

So if you want to do it that way, you need to bypass Linux and access the hardware directly. Fortunately for us the ARM hardware is memory mapped (rather than using special in/out type instructions), so we can use the special device /dev/mem which gives us access to the whole of the memory space in the ARM. And if your program crashes and scribbels all over RAM, well, so might the Pi. If your program has security issues, then so will the Pi - so don't keep your bank details on a Pi!

But it is possible and myself and others do it - just get our code and have a look, or get Dom/Gerts original code and check that too. That combined with the ARMperipherals manual should be more than enough to get you going. Once you've got the /dev/mem interface open and mapped the relevant pages into your program, then the Pi's your bivalve...

Or just use one of the gpio librarys/access mechanisms and make life easy :-)

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1541
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by pygmy_giant » Wed Aug 01, 2012 10:54 am
Thanks gordon - I'm in the process of trawling through other peoples code and data sheets.

I'm probobly re-inventing the wheel but I'm trying to write my own I2c software routines in C that take advantage of the BSC rather than bitbang.

My reason for this is that I want to create a program that I can develop under Linux in user space and then migrate onto the bare metal when it is complete, and so avoid Linux unexpectedly interrupting my control processes.

the example I am adapting at the moment requires

#include <fcntl.h>
#include <sys/mman.h>

I think I'm stuck using /sys/class/gpio or dev/mem filestreams which I believe utilise the kernel and so won't suit my purposes :(

confused

won't the pointer approach 'just work' without these?
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by gordon@drogon.net » Wed Aug 01, 2012 11:05 am
pygmy_giant wrote:Thanks gordon - I'm in the process of trawling through other peoples code and data sheets.

I'm probobly re-inventing the wheel but I'm trying to write my own I2c software routines in C that take advantage of the BSC rather than bitbang.

My reason for this is that I want to create a program that I can develop under Linux in user space and then migrate onto the bare metal when it is complete, and so avoid Linux unexpectedly interrupting my control processes.

the example I am adapting at the moment requires

#include <fcntl.h>
#include <sys/mman.h>

I think I'm stuck using /sys/class/gpio or dev/mem filestreams which I believe utilise the kernel and so won't suit my purposes :(


Are you aware that there is a functional I2C (and SPI) driver in the kernel now? I've not yet used the I2C interface, but the SPI one works a treat.

The /dev/mem interface is direct, "raw" access to the hardware. Using a C program it's possible to obtain about 20 million "pokes/sec" or more without much difficulty. A lot more if you want to code in assembler!

/sys/class/gpio is a lot slower and my benchmark program can only output a signal at about 300,000 "pokes/sec". However you'd not be using that interface in a kernel module, but be poking the hardware directly - via the kernel equivalent of the /dev/mem interface.

-Gordon
--
Gordons projects: https://projects.drogon.net/
User avatar
Posts: 1541
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
by pygmy_giant » Wed Aug 01, 2012 11:17 am
ahh - so maybe I am on the right track then....?

I've seen this approach work, but was not sure whether it was kernel independent....
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by alanb » Wed Aug 01, 2012 9:28 pm
pygmy_giant wrote:Thanks gordon - I'm in the process of trawling through other peoples code and data sheets.

I'm probobly re-inventing the wheel but I'm trying to write my own I2c software routines in C that take advantage of the BSC rather than bitbang.



I have some BSC / I2C code here https://github.com/alanbarr/RaspberryPi-GPIO which uses /dev/mem rather than an I2C enabled kernel. Its still somewhat experimental at the moment but I've tested it with a EEPROM and a bit expander I have and it works fine. Only thing which I am currently a but dubious about is the code which handles writing more than 16 bytes at once.
Posts: 4
Joined: Wed Aug 01, 2012 9:19 pm
by pygmy_giant » Wed Aug 01, 2012 9:51 pm
great - I'll give it a read.

I want to get it working with this: http://www.web4robot.com/files/I2C_FLEXEL.pdf

just got to solder some pins on the board - I hate soldering - always burn my fingures and make a mess - any tips?
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by Grumpy Mike » Tue Aug 07, 2012 8:20 pm
pygmy_giant wrote: I hate soldering - always burn my fingures and make a mess - any tips?

An iron has two ends, one end you hold and the other end you don't. Generally it is the hot end you avoid touching.
Make a mechanical joint before soldering it, that way you don't have to hold anything when soldering.
User avatar
Posts: 784
Joined: Sat Sep 10, 2011 7:49 pm
Location: Manchester (England England)
by pygmy_giant » Tue Aug 07, 2012 9:19 pm
Thanks mike - think i'll just balance the iron on the edge of the desk and hold the board instead - its safer.

Seriously though, a blob of blu-tack might come in handy.

While I've got your attention, is the diagram on this page kosher: http://www.robot-electronics.co.uk/htm/ ... amples.htm ?

I was thinking maybe the 5v might find its way back into the Pi and cause some damage, or am I misunderstanding how I2C works....?
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by idragoev » Wed Aug 08, 2012 1:46 pm
Hi all,
I'm trying to make a simple app using http://www.open.com.au/mikem/bcm2835/.
I build it directly on my Raspberry Pi and installed the library. I also created a simple C app the uses the GPIO, but when I run the app i get :"undefined symbol bcm2835_init".

I noticed then, that the libbcm is a static library (.a). how can I get .so?
Thanks!
Posts: 1
Joined: Wed Aug 08, 2012 1:41 pm
by pygmy_giant » Wed Aug 08, 2012 2:53 pm
You have to download and then install the library using

tar zxvf bcm2835-1.0.tar.gz cd bcm2835-1.0 ./configure make # as root: make check make install

I managed this successfully with Puppy and used it (after installing DevX) but also am having problems with Raspbarian.

I would also appreciate any help - or I'm going back to Puppy....!
Posts: 1569
Joined: Sun Mar 04, 2012 12:49 am
by DexOS » Wed Aug 08, 2012 4:09 pm
pygmy_giant wrote:just got to solder some pins on the board - I hate soldering - always burn my fingures and make a mess - any tips?

Are you using lead-free ?, if so buy some lead 60/40 Rosin Core Solder.
Lead-free is just rubbish.
Batteries not included, Some assembly required.
User avatar
Posts: 864
Joined: Wed May 16, 2012 6:32 pm