Software PWM generation using gpio in Beaglebone

829 views
Skip to first unread message

swaroop

unread,
Feb 17, 2012, 1:04:43 PM2/17/12
to Beagle Board, pranja...@gmail.com
Hi!

We are trying to run a servo using software PWM (No kernel modules /
hardware used, Beaglebone-Minimal Angstrom image Kernel ver. 3.1.0+).
The development is being done on the target itself(No cross compilers
being used). The code is as follows:

*********************************************************************************************
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <string.h>

void gpio_control(int,int);
struct timespec off;
struct timespec on;
void gpio_init(int);
void gpio_cleanup(int);

void gpio_cleanup(int pinout)
{
FILE *p;
char *temp;
p = NULL;
p = fopen("/sys/class/gpio/unexport","w");
fprintf(p,"%d",pinout);
fclose(p);
}
void gpio_init(int pinout)
{
FILE *p;
char temp1[50];
char pin1[2];
p = NULL;
printf("ps");
p = fopen("/sys/class/gpio/export","w");
printf("sp");
fprintf(p,"%d",pinout);
fclose(p);
sprintf(pin1,"%d",pinout);
strcat(temp1,"/sys/class/gpio/gpio");
strcat(temp1,pin1);
strcat(temp1,"/direction");
p = fopen(temp1,"w");
fprintf(p,"out");
fclose(p);
}

void gpio_control(int pinout,int val)
{
FILE *p = NULL;
char temp[50];
char pin[3];
sprintf(pin,"%d",pinout);
strcat(temp,"/sys/class/gpio/gpio");
strcat(temp,pin);
strcat(temp,"/value");
p= fopen(temp,"wb");
fprintf(p,"%d",val);
fclose(p);
}

int main(void)
{

on.tv_nsec=1500000;
off.tv_nsec=18500000;
gpio_init(38);
while(1)
{
gpio_control(38,0);
nanosleep(&on,NULL);
gpio_control(38,1);
nanosleep(&off,NULL);
}
gpio_cleanup(38);
}
*********************************************************************************************

We checked with GDB and we get the following output:
___________________________________________________________________
root@beaglebone:~# gdb servo.out
GNU gdb (GDB) 7.3.1
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/
gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
and "show warranty" for details.
This GDB was configured as "arm-angstrom-linux-gnueabi".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/root/servo.out...done.
(gdb) run
Starting program: /home/root/servo.out

Program received signal SIGSEGV, Segmentation fault.
0x400f0114 in fwrite () from /lib/libc.so.6
(gdb) where
#0 0x400f0114 in fwrite () from /lib/libc.so.6
#1 0x000086d0 in gpio_init ()
#2 0x00008820 in main ()
(gdb)
_______________________________________________________________________________

Any help will be highly appreciated.

Regards,

pea lo

unread,
Feb 17, 2012, 11:34:24 PM2/17/12
to Beagle Board
Yehh , even i'm facing exactly the same problem, ...please let me know
if you find any solution...:)

Andrey Nechypurenko

unread,
Feb 18, 2012, 5:47:48 AM2/18/12
to beagl...@googlegroups.com
>> #0  0x400f0114 in fwrite () from /lib/libc.so.6
>> #1  0x000086d0 in gpio_init ()
>> #2  0x00008820 in main ()

Most probably one of your fprintf() fails. The reason for it could be
wrong arguments you are passing to it. Most probably the FILE* pointer
is null. Why it could be? Because file is not opened properly. How it
could happens? For example because the path you are passing to fopen()
is wrong. How that could happen? Either file does not exists or you do
not have enough permissions or your constructed path string is wrong.
How it could be wrong? Look for example how you are using
*uninitialized* temp1 variable with strcat(). Here you are calling for
problems.

So what I would suggest to do are:

- clean up your code so that you are not manipulating uninitialized strings

- it is absolutely necessary to add error checking and handling for
fopen() function. It will tell you what is wrong.

- there is absolutely no need to open/close the file every time you
want to write to it. It is *very* inefficient. Consider adding FILE*
parameter to your gpio_control function, open the file at the
beginning of your program and close it at the end.

zetoff

unread,
Feb 18, 2012, 11:01:07 AM2/18/12
to beagl...@googlegroups.com, pranja...@gmail.com
when you call an  fopen("/sys/class/gpio/export","w"); check alway return value : if null an error occured and
each operation after will fail
In your case perhaps wrong rights permission

Michael Lewis

unread,
Feb 26, 2012, 8:09:08 PM2/26/12
to Beagle Board
This is pretty interesting. I just got a servo working using the built-
in hardware PWM and it works pretty well, but after reading some more
discussions and the SRM it sounds like the BeagleBone can only support
up to 6 servos via this method (I'm looking to control more).

I'm hoping that there's a way to make use of software PWM by default
and then offload some of that to hardware PWM if the CPU load becomes
to intense.

- Mike

Andrey Nechypurenko

unread,
Feb 27, 2012, 4:24:18 AM2/27/12
to beagl...@googlegroups.com
> I'm hoping that there's a way to make use of software PWM by default
> and then offload some of that to hardware PWM if the CPU load becomes
> to intense.

Speaking about software PWM generation - you might be interested to
take a look at the following article:
http://veter-project.blogspot.com/2011/09/real-time-enough-about-pwms-and-shaky.html

In addition, the following article provides great overview about what
is possible on BeagleBoard:
https://www.osadl.org/fileadmin/dam/rtlws/12/Brown.pdf

--
Andrey.

Chris Dew

unread,
Feb 29, 2012, 11:17:16 AM2/29/12
to Beagle Board
Hi Mike,

Could you point me at any docs you used to get the hardware pwm
working? (I only need to control 4 servos.)

Thanks,

Chris.

cmsdew at gmail.com

Crunchy

unread,
Feb 29, 2012, 11:30:54 AM2/29/12
to beagl...@googlegroups.com
Chris, sure. You can follow this thread: http://groups.google.com/group/beagleboard/browse_thread/thread/6a529febb7703072/70dbad13db19f8be?lnk=gst&q=pwm#70dbad13db19f8be

The last couple pages are the most relevant.

- Mike

--
To join: http://beagleboard.org/discuss
To unsubscribe from this group, send email to:
beagleboard...@googlegroups.com
Frequently asked questions: http://beagleboard.org/faq

Chris Dew

unread,
Feb 29, 2012, 11:42:25 AM2/29/12
to Beagle Board
Thanks,

Chris.

On Feb 29, 4:30 pm, Crunchy <crunchythe...@gmail.com> wrote:
> Chris, sure. You can follow this thread:http://groups.google.com/group/beagleboard/browse_thread/thread/6a529...

tallakt

unread,
Feb 29, 2012, 4:13:15 PM2/29/12
to Beagle Board
You might want to look at my project http://github.com/tallakt/servodrive

Michael Lewis

unread,
Feb 29, 2012, 9:30:51 PM2/29/12
to Beagle Board
tallakt, your servodrive project would be the ideal solution. Would
you have any idea how to adapt it to the beaglebone? The pinmuxing
would be the main difference, I think.

tallakt

unread,
Mar 1, 2012, 2:09:49 AM3/1/12
to Beagle Board
Hi. Sorry, I only have an Beagleboard, no XM or 'bone, so I don't want
to comment on compatibility. I would also like to mention that one
user got problems with the beagleboard running servis directly off the
1.8V, but the root cause was never found (ie could be something else).

tallakt

unread,
Mar 1, 2012, 2:31:51 AM3/1/12
to Beagle Board

> you have any idea how to adapt it to the beaglebone? The pinmuxing
> would be the main difference, I think.

Actually, I never did any pin muxing. All the IO pins I used worked as
gpio right out of the box. You might want to select other pins on the
beaglebone that are preconfigured to work as gpio, and you might test
this with the generic gpio stuff (echo 1 > /dev/...)

Tallak

Reply all
Reply to author
Forward
0 new messages