linux c蜂鸣器驱动程序,嵌入式Linux设备驱动程序设计——蜂鸣器驱动程序
驱动描述:该驱动是一个完整的蜂鸣器驱动程序,考虑到了竟态的情况,实现了一个驱动只
能由一个应用程
序打开。该驱动面向应用层提供了强大的操作接口。应用程序操 作蜂鸣器只需要调用write函数写入相应的1或0即可,调用read可以查看当前蜂鸣器的电平状态。然后再驱动层的write和read就会进行相应的动作,当然在应用程序打开驱动时,将会调用open函数初始化gpio等资源,和实现竟态机制。
下面是源代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define ALLOW_OPEN_TIMES 2
//定义硬件相关的数据结构
struct button_resource {
char *name;
//名称
unsigned int gpio;
//GPIO编号
};
//定义驱动私有的数据结构
struct button_priv{
struct cdev btn_cdev;
//为了利用container_of
atomic_t av;
//整型原子变量
int open_times;
//记录设备打开的次数
spinlock_t lock;
//分配自旋锁
struct semaphore sema; //分配信号量
};
static struct button_priv *pbtn = NULL;
//主设备号
static int major;
//设备类
static struct class *cls;
static int buzzer_open(struct inode *inode, struct file *file)
{
unsigned long flags;
struct button_priv *pbtnp = container_of(inode->i_cdev,
struct button_priv, btn_cdev);
file->private_data = pbtnp;
gpio_request(S5PV210_GPD0(1), "buzzer");
gpio_direction_output(S5PV210_GPD0(1), 0);
#if 0
if (!atomic_dec_and_test(&pbtnp->av)) {
printk("button can be open only once!\n");
atomic_inc(&pbtnp->av);
return -EBUSY;
}
spin_lock_irqsave(&pbtnp->lock, flags); //加锁
if (pbtnp->open_times >= 2) {
printk("allow open %d times\n", ALLOW_OPEN_TIMES);
spin_unlock_irqrestore(&pbtnp->lock, flags);//释放锁
return -EBUSY;
}
pbtnp->open_times++;
spin_unlock_irqrestore(&pbtnp->lock, flags); //释放锁
#endif
#if 0
if(down_trylock(&pbtnp->sema)) {
printk("button can be open only once!\n");
return -EBUSY;
}
#endif
//down(&pbtnp->sema);
if (down_interruptible(&pbtnp->sema)) {
printk("Proccess is INT!\n");
return -EINTR;
}
printk("open button successfully!\n");
return 0;
}
static int buzzer_close(struct inode *inode,
struct file *file)
{
struct button_priv *pbtnp = file->private_data;
gpio_direction_output(S5PV210_GPD0(1), 0);
gpio_free(S5PV210_GPD0(1));
//atomic_inc(&pbtnp->av);
#if 0
unsigned long flags;
spin_lock_irqsave(&pbtnp->lock, flags);
pbtnp->open_times--;
spin_unlock_irqrestore(&pbtnp->lock, flags);
#endif
up(&pbtnp->sema);
return 0;
}
static int status;
static ssize_t buzzer_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
copy_to_user(buf, &status, 4);
return 0;
}
static ssize_t buzzer_write(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
int val;
copy_from_user(&val, buf, 4);
if (val == 1) {
gpio_set_value(S5PV210_GPD0(1), 1);
} else {
gpio_set_value(S5PV210_GPD0(1), 0);
}
status = val;
return 0;
}
//设备的操作集合
static struct file_operations btn_fops = {
.owner = THIS_MODULE,
.open = buzzer_open,
.release = buzzer_close,
.read = buzzer_read,
.write= buzzer_write
};
static int button_init(void)
{
dev_t dev_id;
if (major) {
dev_id = MKDEV(major, 0);
register_chrdev_region(dev_id, 1, "button");
} else {
alloc_chrdev_region(&dev_id, 0, 1, "button");
major = MAJOR(dev_id);
}
pbtn = kmalloc(sizeof(struct button_priv), GFP_KERNEL);
memset(pbtn, 0 ,sizeof(struct button_priv));
cdev_init(&pbtn->btn_cdev, &btn_fops);
atomic_inc(&pbtn->av);
spin_lock_init(&pbtn->lock);
sema_init(&pbtn->sema, 1); //互斥信号量
cdev_add(&pbtn->btn_cdev, dev_id, 1);
cls = class_create(THIS_MODULE, "button");
device_create(cls, NULL, dev_id, NULL, "button");
return 0;
}
static void button_exit(void)
{
dev_t dev_id = MKDEV(major, 0);
device_destroy(cls, dev_id);
class_destroy(cls);
cdev_del(&pbtn->btn_cdev);
unregister_chrdev_region(dev_id, 1);
kfree(pbtn);
pbtn = NULL;
}
module_init(button_init);
module_exit(button_exit);
MODULE_LICENSE("GPL v2");
linux c蜂鸣器驱动程序,嵌入式Linux设备驱动程序设计——蜂鸣器驱动程序相关推荐
- 嵌入式linux查看usb设备驱动程序,嵌入式Linux下USB驱动程序的设计
嵌入式Linux下USB驱动程序的设计 usb概念: USB(Universal Serial Bus)即通用串行总线,是一种全新的双向同步传输的支持热插拔的数据传输总线,其目的是为了提供一种兼容不 ...
- Linux设备驱动程序 三 字符设备驱动
Linux设备驱动程序 三 字符设备驱动 笔记 第三章 字符驱动设备 本章会编写一个完整的字符设备,字符设备简单,易于理解, 名字是scull:Simple Caracter Utility for ...
- linux内核培训广州,嵌入式Linux驱动开发高级培训班-华清远见嵌入式培训中心
课程目标 本课程以案例教学为主,系统地介绍Linux下有关FrameBuffer.MMC卡.USB设备的驱动程序开发.参加本课程学习的学员,因为具备了Linux设备驱动开发基础,所以本课程针对性较强, ...
- Linux USB设备驱动程序设计 和 USB下载线驱动设计
Linux USB设备驱动程序设计 和 USB下载线驱动设计 USB设备驱动模型 USB设备包括配置(configuration).接口(interface)和端点(endpoint),一个USB设备 ...
- Linux I2C核心、总线与设备驱动
Linux I2C核心.总线与设备驱动 I2C总线仅仅使用SCL. SDA这两根信号线就实现了设备之间的数据交互,极大地简化了对硬件资源和PCB板布线空间的占用.因此, I2C总线非常广泛地应用在EE ...
- linux 直流电机驱动设计,嵌入式Linux直流电机驱动.PPT
嵌入式Linux直流电机驱动.PPT 嵌入式Linux直流电机驱动实验 开发平台中直流电机驱动的实现 S3C2410芯片自带定时器,所以控制部分省去了三角波产生电路.脉冲调制电路和PWM信号延迟及信号 ...
- 嵌入式linux的发展历程,嵌入式Linux论文(历史发展分类及应用)
嵌入式Linux 一.嵌入式Linux简介 1.1 嵌入式Linux历史 随着社会的发展,信息化技术的成熟和数字化产品的普及,让以计算机技术.芯片技术和软件技术为核心的嵌入式系统再度成为当前研究和应用 ...
- 嵌入式linux 配置usb otg,嵌入式linux系统环境下USB设备的驱动实现
0 引言 嵌入式linux系统环境以其易于移植裁减.内核小.效率高.完整.原代码开放及性能优异等特点,在嵌入式领域得到了非常广泛的应用.Linux的USB设备端的源代码中主要有USB device的 ...
- Linux字符设备驱动程序开发(4)-LED驱动程序设计
这里编写一个LED内核驱动代码.流程大概如下: 1.实现一个内核模块. 2.添加字符设备驱动框架. 3.在字符设备驱动中实现open和ioctl函数. 4.编写应用程序. led.c #include ...
- 嵌入式linux矩阵键盘,基于嵌入式Linux的矩阵键盘驱动程序开发
O 引 言 随着以计算机技术.通信技术和软件技术为核心的信息技术的发展,嵌入式系统在各个行业中得到了广泛的应用.嵌入式系统已成为当今IT行业的焦点之一.而在嵌入式系统中,键盘是重要的人机交互设备之一. ...
最新文章
- 用Auto-TensorCore代码生成优化matmul
- AprilTag程序的获取
- 工作缺点和不足及措施_安全生产 | 查不足 定措施 抓落实 强管理 圣雄氯碱组织开展“事故回头看”工作...
- ABAP 数值四舍五入函数
- Nutanix的野心可不小!
- 【Luogu3926】SAC E#1 - 一道不可做题 Jelly
- 安全工具大全(持续补充中)
- JQuery超链接鼠标提示效果
- 使用UDP遇到的问题小结
- 微型计算机主机内部结构,微型计算机主机由什么组成
- html中划过鼠标滑过上方英文,CSS如何实现鼠标滑过文字出现效果?
- 完美配色排版海报模板|神奇的色彩搭配
- 斩波电路---视频课笔记
- Androidnbsp;学习论坛博客及网站推荐(…
- ai修复图片 python_百度AI攻略:拉伸图像恢复
- 卡梅隆对话刘慈欣:想看《三体》拍成电影
- Windows运行vbs在微信下自动发送烟花、庆祝
- 计算机学院毕业生祝福,暖心的毕业祝愿赠言
- 自学javase回顾(9/10)
- Bitwig Studio v2.4 x64 macOS+Ubuntu+WiN 音乐制作宿主软件下载
热门文章
- 【Linux内核分析与应用-陈莉君】进程的调度
- RobotStudio的基本布局方法,模型加载,工件坐标系的创建,手动操作机器人示教,以及模拟仿真机器人运动轨迹。
- 《企业大数据系统构建实战:技术、架构、实施与应用》——2.3 大数据制度和流程规范...
- 传智杯2021年第三届传智杯全国大学生IT技能大赛(决赛B组)python小白解题思路
- 安装selenium时报错,Unable to create process using ‘D:\ProgramData\python.exe D:\ProgramData\Scripts\pip-s
- gitter 卸载_最佳Gitter渠道:硬件,物联网和机器人技术
- oracle 用户权限设置,oracle用户权限管理使用详解
- android图标重力感应插件,重力感应,图片摆动旋转(自定义控件) android
- 刚刚用鸿蒙跑了个“helloworld”!我特么怀疑人生了
- JS 进阶 (六) 浏览器事件模型DOM操作