Beagleboard GPIO Input (driverless)

The following example C program configures the beagleboard expansion header pins as GPIO inputs. the pins are configured all pull up. It then reads from these pins and output “1” if pin 3 ONLY is shorted to ground.

The code bypasses the kernel completely by mapping the memory containing the GPIO configuration registers directly. It does this by mmaping /dev/mem, to access system memory. You need to use O_SYNC when you do this to tell mmap the memory is uncacheable. It’ll work /a bit/ without but you’ll get weird artifacts.

Once you have access to memory you need to configure the pins to be used as GPIO. Each pin on the OMAP3530 can have up to 6 functions, by default the expansion header pins are configured for use as MMC and I2C ports. The pinconf code reconfigures these as GPIO, an input bit also needs to be set here. Next there another GPIO configuration register, which also needs setting to 1 for input. After this you can read GPIO data from the GPIO input register for bank 5. You can’t configure all the pins on bank 5 as input on the beagleboard, a couple of them are used for the main MMC port.

Bypassing the kernel isn’t the best way to access GPIO from userland. It’s possibly useful though if you’re planning to migrate the code in to a driver.

#include
#include
#include
#include
#include
#include
#include
#include

int main() {

int fd = open(“/dev/mem”, O_RDWR | O_SYNC);

if (fd < 0) { printf("Could not open memory\n"); return 0; } // Pad configuration volatile ulong *pinconf; pinconf = (ulong*) mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x48000000); if (pinconf == MAP_FAILED) { printf("Pinconf Mapping failed\n"); close(fd); return 0; } // Configure Expansion header pins as input. pinconf[0x2158/4] = 0x011C011C; pinconf[0x215C/4] = 0x011C011C; pinconf[0x2160/4] = 0x011C011C; pinconf[0x2164/4] = 0x011C011C; pinconf[0x2168/4] = 0x011C011C; pinconf[0x216C/4] = 0x011C011C; pinconf[0x2170/4] = 0x011C011C; pinconf[0x2188/4] = 0x011C011C; close(fd); fd = open("/dev/mem", O_RDWR | O_SYNC); // GPIO Configuration: configure are input volatile ulong *gpio; gpio = (ulong*) mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0x49050000); if (gpio == MAP_FAILED) { printf("Gpio Mapping failed\n"); close(fd); return 0; } // Configure all GPIO pins on bank 5 as input. gpio[0x6034/4] = 0xFFFFFFFF; // Prints 1 when pin 3 of the Expansion header is Grounded. int c=0; for(;;) { if(gpio[0x6038/4] == 201390076) printf("1\n"); // printf("gpio5: %d \n",gpio[0x6038/4]); } } [/sourcecode]

Installing Ruby and running a program

I’ve written my first post on a first, simple Ruby program. But I’ve not included notes there on installing and running Ruby programs. That’s because Ruby runs on a lot of different systems. And Ruby programs can be run in different ways.

You can find advice on installing Ruby here.

If you’re using a Mac your in luck as Ruby is already installed on Snow Leopard and Lion! You’ll need a text editor though. Try TextWrangler. When you save files save them as myprogram.rb. To run them open up a terminal and type:

ruby myprogram.rb

You’ll need to make sure you’re in the same directory you saved your Ruby program to. By default TextWranger saves files to Documents so you’ll need to type:

cd Documents
ruby myprogram.rb

I hope that gets you started if you’re using a Mac. There are lots of instructions on getting up and running on other platforms around.

First steps in ruby. Printing a triangle of stars

I’m going to try and write some simple ruby programs. Here’s the first one. It prints a triangle of stars like this:

*
**
***
****
*****
******
*******
********
*********
**********
***********

And here is the code:

star_string = "*"

10.times do
    puts star_string
    star_string = star_string + "*"
end

I hope you can understand it. The program creates a string called “star_string”. Then it loops 10 times. Each time it loops it prints (puts) out star_string, and adds another * to the string. That way star_string gets longer and longer.

I’m also going to show you how this is done in C++. If you don’t want to learn C++ you don’t need to look at this. But C like languages are so common it’s worth at least gaining some familiarity with the syntax.

#include
#include

using namespace std;

int main() {

string star_string = “*”;

for(int n=0;n<10;n++) { cout << star_string << endl; star_string = star_string + "*"; } } [/sourcecode] Can you modify the program so it prints more than one triangle, like this? [sourcecode language="html"] * ** *** **** ***** ****** ******* ******** ********* ********** * ** *** **** ***** ****** ******* ******** ********* ********** [/sourcecode] Post your solution in the comments sections below. Everytime someone posts a solution, I'll try to post a new example and problem the next day. The part 2 is now HERE.

QR Code doodle

That is all.