fl2440蜂鸣器测试程序和strcmp()及struct input_event 还有perror()浅析

来源:互联网 发布:电脑usb端口怎么设置 编辑:程序博客网 时间:2024/06/07 04:41


前面移植了内核自带的蜂鸣器驱动,现在有时间写一个最简单的测试程序,功能是打开蜂鸣器,或者关闭蜂鸣器。


  1 /*********************************************************************************  2  *      Copyright:  (C) 2017 fanmaolin<fanmaolinn@gmail.com>  3  *                  All rights reserved.  4  *  5  *       Filename:  test.c  6  *    Description:  This file   7  *                   8  *        Version:  1.0.0(04/23/2017)  9  *         Author:  fanmaolin <fanmaolinn@gmail.com> 10  *      ChangeLog:  1, Release initial version on "04/23/2017 09:36:39 AM" 11  *                  12  ********************************************************************************/ 13  14 #include<stdint.h> 15 #include<string.h> 16 #include<fcntl.h> 17 #include<unistd.h> 18 #include<stdio.h> 19 #include<linux/input.h> 20 #include<unistd.h> 21  22  23 int main(int argc, char *argv[]) 24 { 25     int fd; 26      27     struct input_event event; 28  29  30  31 if ((fd = open("/dev/event1", O_RDWR)) < 0) {//打开dev/event1,设置为读写模式 32  33     perror("beep test");//如果文件打开失败,打印出错信息 34  + testpwm.c                                                                                                                         35     return 1; 36  37 } 38  39  40  41     event.type = EV_SND;//事件类型设置为支持声音 42     event.code = SND_TONE;//设置事件代码为SND_TONE 43  44     if(!strcmp (argv[1],"1"))//strcmp()函数用来比较两个字符串 45     { 46         { 47             event.value = 2000;   //打开蜂鸣器   48             write(fd, &event, sizeof(struct input_event)); 49         } 50     } 51  52     else if(!strcmp (argv[1],"0")) 53     { 54  55             event.value = 0;//关闭蜂鸣器 56             write(fd, &event, sizeof(struct input_event)); 57     } 58  59    close(fd);//释放占用资源 60  61        return 0; 62  63 }


[fanmaolin@centos6 ~]$ /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc test.c

把生成的a.out文件传到开发板上进行测试




OK


下面展开分析函数和程序

我的蜂鸣器测试程序使用了struct input_even结构体,在写按键驱动时也用到了这个,这里展开仔细讲一下

[fanmaolin@Centeros linux-3.0]$ vim include/linux/input.h    

linux/input.h中有定义,这个文件还定义了标准按键的编码等struct input_event {struct timeval time; //按键时间__u16 type; //类型,在下面有定义__u16 code; //要模拟成什么按键__s32 value;//是按下还是释放};


事件类型中可以看到支持声音

/** Event types*/#define EV_SYN 0x00#define EV_KEY 0x01 //按键#define EV_REL 0x02 //相对坐标(轨迹球)#define EV_ABS 0x03 //绝对坐标#define EV_MSC 0x04 //其他#define EV_SW 0x05#define EV_LED 0x11 //LED#define EV_SND 0x12//声音#define EV_REP 0x14//repeat#define EV_FF 0x15 #define EV_PWR 0x16#define EV_FF_STATUS 0x17#define EV_MAX 0x1f#define EV_CNT (EV_MAX+1)



在头文件中追踪SND后发现event.code可以为两种模式

SND_BELL或SND_TONE



如果为SND_BELL,不管input_event.value为多少,最终的value只能为1000或0,即不能改变蜂鸣器的频率。1000表示蜂鸣器打开,0表示蜂鸣器关闭。
如果为SND_TONE,则可以通过改变input_event.value的值来调整蜂鸣器的频率,从而发出各种不同的音调。

至于为什么要使用struct input_even结构体有些时候我们要模拟按键来达到控制设备的目的,具体 方法就是操作/dev/input/eventx文件,向它写入个input_event结构体就可以模拟按键的输入了,查看/dev/input/eventX是什么类型的事件, cat /proc/bus/input/devices,比如我的测试程序中event.value=2000时蜂鸣器响,等于0时蜂鸣器关闭,就是相当于按键的event.value=1时按键按下,等于0时按键抬起,这就是一个模拟按键的典型例子,不同的是type,code,value不同。

http://blog.csdn.net/bingqingsuimeng/article/details/8178122(struct input_even结构体参考


strcmp()函数

int strcmp(const char *s1, const char *s2);

比较两个字符串

设这两个字符串为str1,str2,
若str1==str2,则返回零;
若str1<str2,则返回负数;
若str1>str2,则返回正数。
44     if(!strcmp (argv[1],"1"))
 52     else if(!strcmp (argv[1],"0"))
我们在这里,利用int main(int argc, char *argv[])

argc是命令行总的参数个数 , argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数命令行后面跟的用户输入的参数,char   *argv[]是一个字符数组,其大小是int   argc,主要用于命令行参数   argv[]   参数,数组里每个元素代表一个参数;   

 比如我们在执行这个程序时输入./a.out会导致段错误,因为没有给argv数组赋值,正确的是./a.out x ,这里的"x"会和“1”、“0”做比较,从而判断是否打开蜂鸣器。



perror()函数

  perror("beep test");

#include <stdio.h>void perror(const char *s);
perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 设备 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。


问题总结:

一、

./a.out: line 1: syntax error: unexpected "("

要交叉编译 /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc test1.c
生成的a.out才能在开发板上执行,这也是交叉编译器的作用。

二、
>: ./a.out
Segmentation fault

段错误,我没有给arg[]赋值,使他变成了野指针。在执行时应该./a.out 1 打开  或者 ./a.out 0 关闭,给它赋值“1”或“0”。上面也有分析。
详细解释:http://blog.chinaunix.net/uid-23069658-id-3959636.html

三、
我执行了./a.out 1 但是蜂鸣器并没有响,加了printf后,发现文件已经打开,但为什么蜂鸣器不能正常工作。

我们在启动开发板进入内核时,会有哔的一声,说明蜂鸣器驱动没有问题,后来发现是我们的测试程序打开错误的文件,之前看是event0但是后来移植了按键驱动后按键驱动变成了event0,蜂鸣器变为event1,所以应该open(event1...),用cat proc/bus/input/devices查看
这是之前的:

移植按键驱动后:


蜂鸣器的测试程序是模拟按键的,所以这里有kbd event1,但是我们要知道蜂鸣器是event1就可以了,所以应该是open("/dev/event1",O_RDWR),以后要特别注意这个问题。

参考:

strcmp():http://baike.baidu.com/link?url=1PJKyqgobTbIYt8fbVku1Loxdz4GEyqYjGAyAMpzNTJ61xT6Rvi_6DvGRVlD53tjnMfyZjvKFN-a9t3uHBT61_

perror():http://blog.csdn.net/ypist/article/details/7886209

struct input event :http://blog.sina.com.cn/s/blog_602f87700101dno6.html

     http://blog.csdn.net/bingqingsuimeng/article/details/8178122

0 0
原创粉丝点击