手把手教你从零实现Linux misc设备驱动二(基于友善之臂4412开发板)

简介: 手把手教你从零实现Linux misc设备驱动二(基于友善之臂4412开发板)

上一节,我教大家实现了一个最简单的MISC设备驱动,那么这节,我们将用一个实例来驱动蜂鸣器,这里为了方便,我就不再写应用程序进行测试,直接在驱动里调用open函数,这个程序是在Android系统里跑起来,后面我会教大家如何在Android下写应用测试程序。

我们参考以前写的蜂鸣器驱动程序,将它移植到我们这个程序里,让它成为一个MISC设备。

参考以前写的文章:

http://blog.csdn.net/morixinguan/article/details/50628588

接下来,看看代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>
#include <asm/uaccess.h>  
#include <asm/irq.h>  
#include <asm/io.h>   
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
//定义配置蜂鸣器的IO地址
#define GPD0CON  0x114000A0
volatile unsigned long *bell_config = NULL ;   
volatile unsigned long *bell_dat = NULL ;   
//misc设备名称--->就是字符设备
#define DEVICE_NAME "misc_dev"
//实现open函数
int tiny4412_misc_dev_open(struct inode *inode , struct file *filp)
{
  printk("tiny4412 bell dev open!\n");
  //配置引脚为输出状态
  *bell_config &= ~(0xf);
  *bell_config |= (0x1);
  //开启蜂鸣器
  *bell_dat |= 0x1 ;
  return 0 ;
}
//实现close函数
int tiny4412_misc_dev_close(struct inode *inode, struct file *filp)
{
  printk("tiny4412 bell dev close!\n");
  //关闭蜂鸣器
  *bell_dat &= ~0x1 ;
  return 0 ;
}
//初始化文件操作结构体
struct file_operations tiny4412_file_ops = {
  .owner = THIS_MODULE ,
  .open = tiny4412_misc_dev_open,
  .release = tiny4412_misc_dev_close,
};
//初始化misc设备结构体
struct miscdevice tiny4412_misc_dev = {
  //由内核自动分配次设备号
  .minor = MISC_DYNAMIC_MINOR ,
  //初始化设备名称
  .name = DEVICE_NAME ,
  //初始化文件操作结构体
  .fops = &tiny4412_file_ops, 
};
static int __init tiny4412_misc_dev_init(void) 
{
  int ret_error ;
  //1、映射IO
  //映射控制配置引脚IO
  bell_config = (volatile unsigned long *)ioremap(GPD0CON , 16);  
    //加4个字节偏移到GP0DAT顺便映射该物理地址---引脚状态控制IO
    bell_dat = bell_config + 1 ;
  //2、注册misc设备
  int ret = misc_register(&tiny4412_misc_dev);
  if(ret != 0){
     ret_error = ret ;
     printk("misc register fair!\n");
     goto fair ;
  }
  printk("misc init success!\n"); 
  //在这里直接调用open函数,就方便,不用直接写应用程序打开设备访问
  tiny4412_misc_dev_open(NULL,NULL);
  return ret ;
  fair:
  return ret_error ;
}
static void __exit tiny4412_misc_dev_exit(void) 
{
  //注销misc设备
  misc_deregister(&tiny4412_misc_dev);
  //取消映射   
    iounmap(bell_config);  
}
module_init(tiny4412_misc_dev_init);
module_exit(tiny4412_misc_dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("YYX add misc driver");

运行结果:

640.png

在开机log中,我们看到open函数被正确调用,蜂鸣器发出了清脆的响声。

至此,我们完成了这个简单的基于蜂鸣器的misc设备驱动,当然,如果有兴趣,我们可以在Android上写一个C的应用程序,在开机的时候以服务的形式加载,一旦加载上,再在里面写一个按键输入的程序,当按下某个按键就调用bell open函数,当释放按键,就调用bell close函数。

以上的程序还可以进一步优化,做得更好。

目录
相关文章
|
1月前
|
安全 Linux 网络虚拟化
Linux网络名称空间和Veth虚拟设备的关系
在讨论Linux网络名称空间和veth(虚拟以太网对)之间的关系时,我们必须从Linux网络虚拟化的核心概念开始。Linux网络名称空间和veth是Linux网络虚拟化和容器化技术的重要组成部分,它们之间的关系密不可分,对于构建隔离、高效的网络环境至关重要。😊
|
1天前
|
Linux 芯片 Ubuntu
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
Linux驱动入门 —— 利用引脚号操作GPIO进行LED点灯
|
1天前
|
Ubuntu Linux
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-2
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-2
|
1天前
|
Linux 芯片
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-1
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯
Linux驱动入门 —— 利用寄存器操作GPIO进行LED点灯-1
|
1天前
|
Linux C语言 Ubuntu
Linux驱动入门——编写第一个驱动
Linux驱动入门——编写第一个驱动
Linux驱动入门——编写第一个驱动
|
4天前
|
网络协议 Shell Linux
LabVIEW 在NI Linux实时设备上访问Shell
LabVIEW 在NI Linux实时设备上访问Shell
|
7天前
|
Linux
linux驱动层输出dev_dbg打印信息
linux驱动层输出dev_dbg打印信息
12 0
|
16天前
|
存储 监控 Linux
【专栏】在 Linux 中,了解已安装驱动器是系统管理的关键
【4月更文挑战第28天】在 Linux 中,了解已安装驱动器是系统管理的关键。本文介绍了三种方法:1) 使用 `lsblk` 命令显示设备名、大小和类型;2) `fdisk -l` 命令提供详细分区信息;3) `gnome-disks` 等系统管理工具展示驱动器信息。此外,还讨论了驱动器类型识别、挂载点概念及其应用。通过这些方法,用户能有效地监控和管理 Linux 系统中的驱动器。
|
24天前
|
存储 Linux
如何查看Linux设备的硬盘信息?
【4月更文挑战第12天】在Linux系统中,查看硬盘信息的常用命令。
29 4
|
29天前
|
Linux Go
Linux命令Top 100驱动人生! 面试必备
探索Linux命令不再迷茫!本文分10部分详解20个基础命令,带你由浅入深掌握文件、目录管理和文本处理。 [1]: <https://cloud.tencent.com/developer/article/2396114> [2]: <https://pan.quark.cn/s/865a0bbd5720> [3]: <https://yv4kfv1n3j.feishu.cn/docx/MRyxdaqz8ow5RjxyL1ucrvOYnnH>
79 0