ksangeelee
Posts: 192
Joined: Sun Dec 25, 2011 5:25 pm
Location: Edinburgh, UK
Contact: Website

Re: GPIO Programming and Interrupts

Thu Jul 19, 2012 10:18 pm

gordon@drogon.net wrote: I will benchmark the response time in my interrupt handler system above - once I've worked out just how - it might invovle a 2nd Pi toggling a GPIO pin...
Does the pin need to be triggered by an external device? I'd have thought an output pin could raise/lower an input pin with interrupt-on-change, and have the service routine reflect the state on a 3rd (output) pin. A logic analyser on the two output pins would give an accurate measure of the latency.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Thu Jul 19, 2012 10:27 pm

ksangeelee wrote:
gordon@drogon.net wrote: I will benchmark the response time in my interrupt handler system above - once I've worked out just how - it might invovle a 2nd Pi toggling a GPIO pin...
Does the pin need to be triggered by an external device? I'd have thought an output pin could raise/lower an input pin with interrupt-on-change, and have the service routine reflect the state on a 3rd (output) pin. A logic analyser on the two output pins would give an accurate measure of the latency.
Yes, I could connect one gpio output to an input, but that will add cpu overhead generating the clock! (and I don't have a logic analyser) I'm looking for the absolute max. possible, so i'll generate a clock on a 2nd Pi and run the timing on the first. I could easilly send it (eg) a million pulses and have it count, then start to increase the frequency until it misses...


-Gordon
--
Gordons projects: https://projects.drogon.net/

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: GPIO Programming and Interrupts

Thu Jul 19, 2012 10:58 pm

There are a huge number of programs (processes) running all the time on a Linux system. (197 at the moment on this desktop. "ps axg |wc -l" to count them)

Not all of them are eligible to run at any given moment; almost all of them are waiting for input. At the moment there are between 1 and 4 on this machine that are in running state at the same time as this command which counts them: "ps axg -o stat | grep R | wc -l". (There will always be at least one of course, because by definition that command is running when it counts them.)

However the whole point of a multi-tasking OS like Linux or Windows or just about any other, is that it can do more than one thing at once. Each process is given a small slice of time (a timeslice) in which to do some work. At the end of the timeslice it is suspended and another process is given the chance to run. That happens several times a second so you don't notice it happening. Since there are generally few processes that are eligible to run at any one moment, each process effectively has a significant fraction of the power of the CPU to itself -- somewhere of the order of between 25% and 100%.

It's slightly more complex than that, because processes can have multiple threads and it is those that get the timeslices. A simple program has one thread whereas in the suggestion above the program (process) would have three threads. The difference between threads and processes is that threads can see each other's variables, whereas processes are all separate from each other and can only communicate through the OS.

So threads get timeslices and the OS decides when each thread gets a timeslice. It decides that using some horribly hairy algorithms; vast amounts of books and learned papers have been written on the subject. One input it uses is the priority of the thread, but a thread that uses too much time can see its effective priority drop to prevent the system from becoming unresponsive. So your GPIO polling loop can get pushed aside by the user listing a directory or playing solitaire. But a thread that has real-time priority does not get demoted even if it runs all the time, and it runs in preference to anything else. It wont get pushed aside for anything else, but if it doesn't give way occasionally nothing else will run, not even the terminal process that you are typing Ctrl-C to to terminate your run-away program; it's a good way to hang the machine, which is why you need administrator powers to set it up.

When you are writing normal every-day programs you can generally forget about multi-tasking and just imagine that you have the whole computer to yourself. Even if you are doing something like compiling or computing Fourier transforms, which take lots of CPU with only small amounts of input and output, the OS will still make sure that the other processes that need to run get enough time. The only effect is that the computer seems to slow down as the console or GUI process has to share the CPU. But when you are writing real-time code then you have to think about it and make sure that your high-priority threads only run for a fraction of a second before they sleep or wait on an event.

So the three threads in your robot would be part of one process, and the main thread would create the other two, set them to real-time priority, and then go and do the background thread work. In pseudo code it would look something like this:

Code: Select all

function main()

	initialise()

	thread1 = create_thread(foreground_function, priority=REAL_TIME)
	thread2 = create_thread(midground_function, priority=REAL_TIME)

	start(thread1)
	start(thread2)

	while(not terminating)
		handle very slow I/O
		handle user interface

	stop(thread2)
	stop(thread1)

	exit()

function foreground_function()
	forever
		event = poll(fast_io_stuff)
		switch(event)
			io1: handle io1
			io2: handle io2
			...

function midground_function()
	forever
		handle medium speed io
		sleep(100ms)

User avatar
jkCBWPnet
Posts: 3
Joined: Thu Jul 19, 2012 9:59 pm
Location: PA - USA
Contact: Website

Re: GPIO Programming and Interrupts

Thu Jul 19, 2012 11:05 pm

this balancing robot is sort of a hijack but just to make it easy, I would incorporate a dedicated processor just for the balance. atmega 328 picaxe whatever. I know some Arduino stuff. It could do other things as well, but even if it was just dedicated to the balance you are only looking at a few $ or quid etc ;)

pygmy_giant
Posts: 1562
Joined: Sun Mar 04, 2012 12:49 am

Re: GPIO Programming and Interrupts

Thu Jul 19, 2012 11:05 pm

ah - I see - thanks.
Ostendo ignarus addo scientia.

User avatar
DexOS
Posts: 876
Joined: Wed May 16, 2012 6:32 pm
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 12:34 pm

rurwin wrote: However the whole point of a multi-tasking OS like Linux or Windows or just about any other, is that it can do more than one thing at once. Each process is given a small slice of time (a timeslice) in which to do some work. At the end of the timeslice it is suspended and another process is given the chance to run. That happens several times a second so you don't notice it happening.
The main point (unless its multy core) is its not doing more that one thing at a time, as you said, its does one thing then stops, save state, and them moves on to the next task.

@pygmy_giant, I will be releasing bare bone basic soon, just finishing tuts, that may help or you maybe best just using a dedicated avr or pic.
Batteries not included, Some assembly required.

alexchamberlain
Posts: 121
Joined: Thu Jun 14, 2012 11:20 am
Location: Leamington Spa, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 12:39 pm

So, could it be possible to cluster Pis and run a single OS over them all?
Developer of piimg, a utility for working with RPi images.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 1:23 pm

alexchamberlain wrote:So, could it be possible to cluster Pis and run a single OS over them all?
Absolutely.
First task: Write an OS that will run over them all.

-Gordon
--
Gordons projects: https://projects.drogon.net/

alexchamberlain
Posts: 121
Joined: Thu Jun 14, 2012 11:20 am
Location: Leamington Spa, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 1:25 pm

gordon@drogon.net wrote:First task: Write an OS that will run over them all.
Very inciteful...

Pretty sure it wouldn't work without some sort of DMA lines, which I'm pretty sure we haven't got.
Developer of piimg, a utility for working with RPi images.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 1:31 pm

alexchamberlain wrote:
gordon@drogon.net wrote:First task: Write an OS that will run over them all.
Very inciteful...

Pretty sure it wouldn't work without some sort of DMA lines, which I'm pretty sure we haven't got.
Well - what you're creating would be a cluster - google beowolf cluster... that's not hard. We have Ethernet which is OK, but not brilliant to talk to each node. The hard part is making a program work over all the Pi's together in an easy to use fashion.

I have worked for companies in the past who've done just that. It's not easy - one of the most frequent things asked goes along the lines of; "I have this FORTRAN program I wrote 30 years ago - make it go faster"...

-Gordon
--
Gordons projects: https://projects.drogon.net/

alexchamberlain
Posts: 121
Joined: Thu Jun 14, 2012 11:20 am
Location: Leamington Spa, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 1:35 pm

I know the FORTRAN problem well - ended up there in a debugger by accident once.

The aim would be to maximise the amount one of the Pis could spend on an important task (like keeping a robot upright) by offloading other tasks to other Pis.
Developer of piimg, a utility for working with RPi images.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 1:40 pm

alexchamberlain wrote:I know the FORTRAN problem well - ended up there in a debugger by accident once.

The aim would be to maximise the amount one of the Pis could spend on an important task (like keeping a robot upright) by offloading other tasks to other Pis.
Yeech.

An 8-bit micro running at 16MHz with software floating point can keep a quadcopter aloft and stable and give it autonomous control. If you can't balance a robot with a 32-bit 700MHz ARM processor then there is something very wrong with your code and algorithms.

-Gordon
--
Gordons projects: https://projects.drogon.net/

User avatar
jkCBWPnet
Posts: 3
Joined: Thu Jul 19, 2012 9:59 pm
Location: PA - USA
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 6:01 pm

That's exactly the kind of reply I was hoping to see Gordon. Although I am not knowledgeable to make it ;)

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 7:10 pm

jkCBWPnet wrote:That's exactly the kind of reply I was hoping to see Gordon. Although I am not knowledgeable to make it ;)
Lookup the ArduPilot Mega project...

and I was contracted last year to design and build an autonomous quad/octo copter thing and I started with the ArduPilot hardware...

However for something closer to this project, there's this:

http://www.youtube.com/v/pC6yeyDunJg?

and this article to go with it:

http://www.arduino.cc/cgi-bin/yabb2/YaB ... 1284738418

And if you want to do it in Lego, then:

http://www.youtube.com/watch?v=V40ScvJeFxg

and several others - that was just the first hit on google. (Although the Lego NXT is an ARM7 processor however it only runs at 48MHz - it also has an ATmega running at 8MHz which handles most of the IO.

I'm not against this project and I would like to see a Pi doing a balancing robot though, but I fear the challenges to overcome might be a bit high - one being the power supply before we even get to the control aspect of it all - my thoughts being that the effort, rewarding as I'm sure it will be might not be worth the time, money, and hair-pulling required to make it work...

What I can see happening (and a lot is happening already), is using a Pi for simple control - lights, switches, motors - simple floor-crawling robots, things where absolute time critical actions is not needed, but then when it comes to timing critical things like CNC, Stepper motors, balancing, etc. then acting as a master controller to send commands like "forward 5 paces, left 45 degrees" to an autonomous device that's doing the hard work of the actual control - using something like a URF/XRF link to the remote device... (or hard wired)

I have been experimenting with more timing critical things recently though - e.g. my 7-segment LED display - and that mostly works. Would the techniques I used there work for a balancing robot? I'm not sure... If the program driving the LEDs stalls, then you just get a bit of flicker - if it misses a sensor reading/motor speed update, then it falls over ... But who knows!


-Gordon
--
Gordons projects: https://projects.drogon.net/

alexchamberlain
Posts: 121
Joined: Thu Jun 14, 2012 11:20 am
Location: Leamington Spa, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 7:13 pm

You got any code Gordon?
Developer of piimg, a utility for working with RPi images.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 7:23 pm

alexchamberlain wrote:You got any code Gordon?
Er, lots.

Not sure what you're after though!

the 7-segment LED stuff is here:

https://projects.drogon.net/7-segment-l ... pberry-pi/

Complete with wholly innapropriate cheesy video...

my latest wiringPi library has some simplified code for starting concurrent threads and setting a process priority - that's here:

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

-Gordon
--
Gordons projects: https://projects.drogon.net/

alexchamberlain
Posts: 121
Joined: Thu Jun 14, 2012 11:20 am
Location: Leamington Spa, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 7:38 pm

Cool stuff. The Pi would be fine if you buffered the output and drove a whole digit at a time.
Developer of piimg, a utility for working with RPi images.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 7:48 pm

alexchamberlain wrote:Cool stuff. The Pi would be fine if you buffered the output and drove a whole digit at a time.
Sure - as I said in the article: ...doing more in software than in hardware to keep the hardware design simple...

So to do it on a per-digit basis it would require 4 more resistors and a transistor (and additional resistor) per digit to sink the current (as a single GPIO pin would be overloaded if all 8 segments were lit at the same time).

But I leave that as an excercise to the user ;-)

-Gordon
--
Gordons projects: https://projects.drogon.net/

pygmy_giant
Posts: 1562
Joined: Sun Mar 04, 2012 12:49 am

Re: GPIO Programming and Interrupts

Fri Jul 20, 2012 10:29 pm

sorry to 'interrupt' but when I think of 'GPIO' + 'interrupt' in the same sentace I think of pages 25 -30 and 79 most of all 109 onwards in the Boardcom BCM2835 ARM Peripherals datasheet - is that what was intended by the OP?

I'm more interested by the way that interrupts work on a hardware level than in pieces of software elbowing each other out of the way.

Am I missing the point? how can software exploit these hardware interrupts?

I'm sorry I have no understanding of my own to contribute - I intend on scrutinising these parts of the datasheet at a later date....
Ostendo ignarus addo scientia.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Sat Jul 21, 2012 6:48 am

pygmy_giant wrote:sorry to 'interrupt' but when I think of 'GPIO' + 'interrupt' in the same sentace I think of pages 25 -30 and 79 most of all 109 onwards in the Boardcom BCM2835 ARM Peripherals datasheet - is that what was intended by the OP?

I'm more interested by the way that interrupts work on a hardware level than in pieces of software elbowing each other out of the way.

Am I missing the point? how can software exploit these hardware interrupts?

I'm sorry I have no understanding of my own to contribute - I intend on scrutinising these parts of the datasheet at a later date....
Myself and others have posted demonstrations of how software can work with these hardware level interrupts.

The issues (as I see it) is making them work in a Linux-friendly manner.

So while you can get down to the bare metal and have some code executed the instant the interrupt happens, once you put Linux on-top it all changes and there are 2 mechanisms that I'm aware of.

One is the way it's done at present - the GPIO driver is capable of detecting interrupts and working with the standard Linux file event mechanism, so that when a program listens for an interrupt, that program is stalled, the CPU is free to do other things and when the interrupt comes in, the program is resumed. If that program is a thread in a bigger program, then the bigger program keeps on running, the thread is stalled, and wakes up when the interrupt happens. There is no busy-loop polling, and other than the overhead of creating the thread and waiting on the file event, it works in the same way you'd expect a program to take an interrupt.

Fetch my wiringPi library and look in the examples directory for a file wfi.c - that program creates a thread and the thread then waits for an interrupt. It's not a busy wait, it's consuming zero cpu resources while it's waiting, but as soon as the interrupt happens, the process is resumed from where it stopped and can handle the interrupt.

The other way is to have a signal delivered asynchronously to your program. This is being worked on as a kernel module right now - to do it this way, you need to write a signal handler in your program (which is a function), register that function with the Linux signal mechanism, then get on with what you need to ge on with doing. When the interrupt happens, your program will be signalled and the signalg handler code will be executed. This is closer to a more traditional approach to handling interrupts but it's not mainline yet.

Both ways handle interrupts from the hardware directly to the user program. The first way involves creating a thread that runs in parallel with the main program, the 2nd is a more traditional approach.

Both ways are utilising real interrupts - there is no busy-loop polling for an event.

If you want to start to program the interrupt registers your self and have the ARM vector directly into your code, then you need to write it as a kernel extension/module and run it as part of the kernel.

-Gordon
--
Gordons projects: https://projects.drogon.net/

pygmy_giant
Posts: 1562
Joined: Sun Mar 04, 2012 12:49 am

Re: GPIO Programming and Interrupts

Sat Jul 21, 2012 5:00 pm

looking at how that would work with dexos (kernel compiled via fasarm) - not sure I need linux... but would like I2C and am not sure how to write my own driver so maybe I do - but then again maybe writing an I2C driver using fbasic would not be that hard?
Ostendo ignarus addo scientia.

Daverj
Posts: 28
Joined: Tue Mar 06, 2012 2:23 am
Contact: Website

Re: GPIO Programming and Interrupts

Wed Jul 25, 2012 8:49 pm

I am also interested in using GPIO and interrupts. But my application would require true asynchronous interrupt handlers, and not requiring the program to stop and wait for an interrupt.

I'd like to interface an optical rotary encoder to 3 of the GPIO pins (A, B, and Index). Then have three very small interrupt handlers that intrerrupt on either edge change and maintain the value of a variable based on which interrupts happen and in what order. The main program would then occasionally call a function that returns the value of that variable.

The program would run continuously (well, as continuously as any multi-tasking program runs) and occasionally read the value of the variable that the interrupts maintain. There might be no interrupts between reading the value, or there might be hundreds. It depends on how often the program calls the variable read function vs how fast the encoder is turning.

Is there a way yet to do this? Or is this something for the future?

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Wed Jul 25, 2012 9:16 pm

Daverj wrote:I am also interested in using GPIO and interrupts. But my application would require true asynchronous interrupt handlers, and not requiring the program to stop and wait for an interrupt.
Yes, you can do that now. Just have a look at my code.
You do need to take a slightly different approach under Linux to that on an embedded microcontroller, but a true asynchronous interrupt handler is what you get.

Think of it this way: You split your program into 2 threads. These 2 threads then run in parallel. One of these 2 waits for the interrupt (it waits in the kernel, it's not busy polling using CPU) When the interrupt happens, the other thread is stopped and the program that's waiting for the interrupt starts. When it's done that program goes back to sleep, waiting on the next interrupt, and the main program carries on as in nothing has happened. It shouldn't miss the interrupt, but may be delayed if there's a higher priority thread/program active at the time.

Daverj wrote:I'd like to interface an optical rotary encoder to 3 of the GPIO pins (A, B, and Index). Then have three very small interrupt handlers that intrerrupt on either edge change and maintain the value of a variable based on which interrupts happen and in what order. The main program would then occasionally call a function that returns the value of that variable.

The program would run continuously (well, as continuously as any multi-tasking program runs) and occasionally read the value of the variable that the interrupts maintain. There might be no interrupts between reading the value, or there might be hundreds. It depends on how often the program calls the variable read function vs how fast the encoder is turning.

Is there a way yet to do this? Or is this something for the future?
It's perfectly do-able today with a kernel that supports GPIO interrupts and software to handle them - use my wiringPi code as an example if you like, (its LGPL, free, etc.) but other examples have been posted.

The "trick" is to run the interrupt handlers at a high and real-time priority - higher than your main program. To pass information between the interrupts handlers and the main program, you use a mechanism known as a mutex - I've added a very simple version into wiringPi, but it's all bog-standard pozix threads stuff here - I'm just putting some simple wrappers round what's already there.

Example program: http://unicorn.drogon.net/wfi.c


-Gordon
--
Gordons projects: https://projects.drogon.net/

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: GPIO Programming and Interrupts

Wed Jul 25, 2012 9:36 pm

Daverj wrote: not requiring the program to stop and wait for an interrupt.
That would be either a contradiction in terms or how every computer handles interrupts.

Whether you could do this on Linux with the raw hardware depends on how many counts per revolution the encoders have and how fast they are turning. I could easily turn a knob with a 1024-line encoder fast enough to generate a 10kHz output, and there is little likelihood that Linux could keep up with that. If you can keep the frequency down to 100Hz then Linux is very likely to be able to cope.

The encoders I have experience of only have two outputs: A and B, and they only require one interrupt. When you get an edge on A you examine the state of B. Depending on the edge and the state of B you either increment or decrement a counter. That is so simple it is easy to build the functionality in hardware, or of course you could use a microcontroller.

User avatar
gordon@drogon.net
Posts: 2020
Joined: Tue Feb 07, 2012 2:14 pm
Location: Devon, UK
Contact: Website

Re: GPIO Programming and Interrupts

Wed Jul 25, 2012 9:46 pm

rurwin wrote:
Daverj wrote: not requiring the program to stop and wait for an interrupt.
That would be either a contradiction in terms or how every computer handles interrupts.

Whether you could do this on Linux with the raw hardware depends on how many counts per revolution the encoders have and how fast they are turning. I could easily turn a knob with a 1024-line encoder fast enough to generate a 10kHz output, and there is little likelihood that Linux could keep up with that. If you can keep the frequency down to 100Hz then Linux is very likely to be able to cope.

The encoders I have experience of only have two outputs: A and B, and they only require one interrupt. When you get an edge on A you examine the state of B. Depending on the edge and the state of B you either increment or decrement a counter. That is so simple it is easy to build the functionality in hardware, or of course you could use a microcontroller.
This:

https://projects.drogon.net/raspberry-p ... omment-235

Suggests that 5000/sec is achievable and more if required...

-Gordon
--
Gordons projects: https://projects.drogon.net/

Return to “C/C++”