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


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


  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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值