问题
I wrote a sample pwm function in C for beaglebone black. Whenever I make a function call in other modules or in main(), I end up in segmentation fault. Kindly help where I am making the mistake and how to deal with this issue. Below is the code.
int trigger_pwm_output(unsigned input_no )
{
FILE *pwm,*duty,*period,*run;``
uint16_t input=0;
uint8_t input_no=0,input_state=0;
unsigned int duty_cycle =500000;
pwm = fopen("/sys/devices/bone_capemgr.9/slots", "w");
fseek(pwm,0,SEEK_SET);
fprintf(pwm,"am33xx_pwm");
fflush(pwm);
switch(input_no)
{
case 0:
fprintf(pwm,"bone_pwm_P8_13");
fflush(pwm);
period = fopen("/sys/devices/ocp.3/pwm_test_P8_13.15/period", "w");
fseek(period,0,SEEK_SET);
fprintf(period,"%d",500000);
fflush(period);
duty = fopen("/sys/devices/ocp.3/pwm_test_P8_13.15/duty", "w");
fseek(duty,0,SEEK_SET);
run = fopen("/sys/devices/ocp.3/pwm_test_P8_13.15/run", "w");
fseek(run,0,SEEK_SET);
fprintf(run,"%d",0);
fflush(run);
fseek(run,0,SEEK_SET);
count++;
do
{
duty_cycle += 10;
fprintf(duty,"%d",duty_cycle);
}while(count > 0) || (count < 10));
fflush(duty);
fprintf(run,"%d",1);
fflush(run);
fclose(pwm);
fclose(duty);
fclose(period);
fclose(run);
break;
case 1:
fprintf(pwm,"bone_pwm_P8_19");
fflush(pwm);
period = fopen("/sys/devices/ocp.3/pwm_test_P8_19.16/period", "w");
fseek(period,0,SEEK_SET);
fprintf(period,"%d",500000);
fflush(period);
duty = fopen("/sys/devices/ocp.3/pwm_test_P8_19.16/duty", "w");
fseek(duty,0,SEEK_SET);
run = fopen("/sys/devices/ocp.3/pwm_test_P8_19.16/run", "w");
fseek(run,0,SEEK_SET);
fprintf(run,"%d",0);
fflush(run);
fseek(run,0,SEEK_SET);
--count;
do
{
duty_cycle += 10;
fprintf(duty,"%d",duty_cycle);
}while(count <10);
fflush(duty);
fprintf(run,"%d",1);
fflush(run);
fclose(pwm);
fclose(duty);
fclose(period);
fclose(run);
break;
}
return 0;
}
`
回答1:
I have just successfully enabled 4 PWM outputs on BeagleBone Black using C, so I can hopefully give you some legit advices.
Using files under /sys/devices/ocp.3/
directory (known as the Device Tree Overlay) for PWM is not a good idea for two reasons:
- The last two digits of PWM pin directory name are arbitrary, e.g.
pwm_test_P8_13.xx
, a potential cause for segmentation fault since you don't check for fopen status. However, fopen does not allow wildcard in the specified path. My workaround, which was not clean at all, was to callecho /sys/devices/ocp.3/pwm_test_P8_13.*/
with popen to retrieve the correct full path for the PWM pin directory. - There are only two PWM modules on BeagleBone Black, and the DTO prevents you from using more than one PWM pin per module. Consequently, if you try to modify the period of a pin from command line, a write error may return. If you then type
dmesg | tail
, you may see the following message:[ 1406.652632] ehrpwm 48304200.ehrpwm: Period value conflicts with channel 1
[ 1406.660047] pwm_test pwm_test_P8_19.11: pwm_config() failed
As such, I used the files under /sys/class/pwm/
instead. You still need to write am33xx_pwm
and the PWM pins you plan to use to the file /sys/devices/bone_capemgr.9/slots
. Then, you go to directory /sys/class/pwm/
, write digit (0-7) to the file export
, then modify the file under generated directory pwm?
, where ?
is the digit written to export
.
The following table shows each digit and their corresponding pin(s):

Here is the tutorial I referred to.
Hope this helps!
回答2:
There are several issues with this code - some of which are already described in the comments.
- There is a variable name collision.
input_no
is both passed into the function as well as defined within the function. - Both do-while loops are potentially infinite. Both loops have an end condition dependent on
count
which is not modified in the body of either loop. Additionally, the condition in the first of these loops is always true regardless of the value ofcount
. - The return value of all
fopen
calls is never checked. If any of these calls fail, then subsequent file operations are called with null file pointers. count
is not defined or initialized anywhere in this code. Is it defined globally?- One of your calls to
fopen
is made outside the body of the switch statement - it'd be best to move its corresponding close call outside as well.
来源:https://stackoverflow.com/questions/29369616/beaglebone-black-pwm-using-c