用C语言实现Beaglebone黑PWM
我用C语言为beaglebone black编写了一个示例pwm函数。每当我在其他模块或main()中进行函数调用时,我都会出现分段错误。请帮助我在哪里犯了错误以及如何处理这个问题。 下面是代码用C语言实现Beaglebone黑PWM,c,embedded-linux,beagleboneblack,C,Embedded Linux,Beagleboneblack,我用C语言为beaglebone black编写了一个示例pwm函数。每当我在其他模块或main()中进行函数调用时,我都会出现分段错误。请帮助我在哪里犯了错误以及如何处理这个问题。 下面是代码 int trigger_pwm_output(unsigned input_no ) { FILE *pwm,*duty,*period,*run;`` uint16_t input=0; uint8_t input_no=0,input_state=0; unsigne
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;
}
int触发器\u pwm\u输出(无符号输入\u否)
{
文件*pwm、*占空比、*周期、*运行``
uint16_t输入=0;
uint8\u t输入号=0,输入状态=0;
无符号整数占空比=500000;
pwm=fopen(“/sys/devices/bone_capemgr.9/slots”,“w”);
fseek(脉宽调制,0,寻道设置);
fprintf(脉宽调制,“am33xx_脉宽调制”);
脉冲宽度调制;
开关(输入号)
{
案例0:
fprintf(pwm,bone_pwm_P8_13);
脉冲宽度调制;
周期=fopen(“/sys/devices/ocp.3/pwm_test_P8_13.15/周期”,“w”);
fseek(周期,0,搜索集);
fprintf(期间,“%d”,500000);
弗卢什(时期);
占空比=fopen(“/sys/devices/ocp.3/pwm_test_P8_13.15/占空比”,“w”);
fseek(占空比,0,寻道设置);
run=fopen(“/sys/devices/ocp.3/pwm_test_P8_13.15/run”,“w”);
fseek(run,0,SEEK_SET);
fprintf(运行,“%d”,0);
fflush(运行);
fseek(run,0,SEEK_SET);
计数++;
做
{
占空比+=10;
fprintf(占空比,“%d”,占空比);
}而(计数>0)| |(计数<10));
(职责);
fprintf(运行,“%d”,1);
fflush(运行);
fclose(pwm);
fclose(关税);
fclose(期间);
fclose(run);
打破
案例1:
fprintf(pwm,bone_pwm_P8_19);
脉冲宽度调制;
周期=fopen(“/sys/devices/ocp.3/pwm_test_P8_19.16/周期”,“w”);
fseek(周期,0,搜索集);
fprintf(期间,“%d”,500000);
弗卢什(时期);
占空比=fopen(“/sys/devices/ocp.3/pwm_test_P8_19.16/占空比”,“w”);
fseek(占空比,0,寻道设置);
run=fopen(“/sys/devices/ocp.3/pwm_test_P8_19.16/run”,“w”);
fseek(run,0,SEEK_SET);
fprintf(运行,“%d”,0);
fflush(运行);
fseek(run,0,SEEK_SET);
--计数;
做
{
占空比+=10;
fprintf(占空比,“%d”,占空比);
}虽然(count此代码存在一些问题,其中一些问题已在注释中描述
- 存在变量名冲突。
输入\u no
既传递到函数中,也在函数中定义
- 两个do while循环都可能是无限的。两个循环都有一个依赖于
count
的结束条件,该条件在两个循环的主体中都没有修改。此外,无论count
的值是多少,这些循环中的第一个条件始终为真
- 从不检查所有
fopen
调用的返回值。如果这些调用中的任何一个失败,则使用空文件指针调用后续的文件操作
count
未在此代码中的任何位置定义或初始化。它是全局定义的吗
- 您对
fopen
的一个调用是在switch语句的主体之外进行的-最好也将其相应的close调用移到外部
我刚刚使用C在BeagleBone Black上成功启用了4个PWM输出,所以我希望能给您一些合法的建议
将/sys/devices/ocp.3/
目录下的文件(称为设备树覆盖)用于PWM不是一个好主意,原因有二:
- PWM引脚目录名称的最后两位数字是任意的,例如
PWM\u test\u P8\u 13.xx
,这是分段故障的潜在原因,因为您没有检查fopen状态。但是,fopen不允许在指定路径中使用通配符。我的解决方法根本不干净,就是调用echo/sys/devices/ocp.3/pwm_test_P8_13.*/
with可检索PWM引脚目录的正确完整路径
- BeagleBone Black上只有两个PWM模块,DTO阻止每个模块使用多个PWM引脚。因此,如果您试图从命令行修改引脚的周期,可能会返回写入错误。如果您随后键入
dmesg | tail
,您可能会看到以下消息:
[1406.652632]ehrpwm 48304200.ehrpwm:周期值与通道1冲突
[1406.660047]pwm_测试pwm_测试P8_19.11:pwm_配置()失败
因此,我使用了/sys/class/pwm/
下的文件。您仍然需要将am33xx_pwm
和计划使用的pwm引脚写入文件/sys/devices/bone_capemgr.9/slots
。然后,转到目录/sys/class/pwm/
,写入数字(0-7)到文件导出
,然后修改生成目录下的文件pwm?
,其中?
是写入导出
的数字。
下表显示了每个数字及其对应的pin:
这是我提到的教程
希望这有帮助!这是如何编译的?函数参数input\u no
和相同名称(不同类型)的普通局部变量之间存在名称冲突。修复名称冲突后,您应该添加代码来检查几乎所有函数调用的结果。您假设所有函数调用都会成功。我首先猜测,为什么与您发布的类似的有效代码可能是一个或多个fopen()
调用失败,在这种情况下,它将返回一个空指针。当您随后试图通过这样一个指针执行I/O时,很可能(但决不能保证)会出现segfault。正如@JohnBollinger所写的,通过键入file*fp=fopen(“bla.txt”,“w”);如果(fp==null){printf(“无法打开文件”\n检查每个文件的打开是否成功);退出(1);}
。很可能是这样,