Linux下驱动开发

1.简介

  驱动,是指驱动计算机里软件的程序。驱动程序全称设备驱动程序,是添加到操作系统中的特殊程序,其中包含有关硬件设备的信息。驱动程序是操作系统与硬件连接的桥梁。
  设备驱动最通俗的解释就是“驱使硬件设备行动”。驱动与底层硬件直接打交道,按照硬件设备的具体工作方式,读写设备的寄存器,完成设备的轮询、中断处理、DMA通信,进行物理内存向虚拟内存的映射等,最终让通信设备能收发数据,让显示设备能显示文字和画面,让存储设备能记录文件和数据。

2.驱动分类

  • Linux驱动分类:
      字符设备、块设备、网络设备。
      网络设备: 有线网卡、无线网卡、其它与网络相关的设备。
      块设备: U盘、SD卡、硬盘、光盘等。
      字符设备: 除了块设备和网络设备,其它都归结于字符设备。
      字符设备中分类: 杂项设备、输入设备(键盘、鼠标、触摸屏)、帧缓冲(显示类设备)、RTC设备、串口设备等。

3.杂项设备


  驱动程序是应用层和硬件层的连接桥梁,应用层只管完成应用逻辑开发和界面设计,驱动层则处理硬件配置,实现应用层相关接口函数。
   杂项设备:字符设备类的一种,是除了上述输入设备、帧缓冲设备、RTC设备后的其它设备,例LED设备,由于不好归结于上述分类,则可将LED设备按杂项设备类进行注册。杂项设备主设备号为10。
   在生成的设备节点中,主设备号用来区分设备类。如字符设备中杂项设备主设备号为10,帧缓冲设备主设备号为29;次设备号用来区分这个类中的具体硬件。

4.驱动注册框架

4.1开发平台

开发平台:Ubuntu18.04
编译器:arm-linux-gcc
硬件平台:tiny4412基于Cortex-A9 4核1.5GHZ
开发板内核:Linux3.5

4.2 驱动模板

#include <linux/kernel.h>
#include <linux/module.h>
/*驱动初始化*/
static int __init wbyq_hello_module_init(void)
{printk("驱动入口,驱动注册成功\n");return 0;
}
/*驱动释放*/
static void __exit wbyq_hello_module_cleanup(void)
{printk("驱动出口,驱动注销成功\n");
}
module_init(wbyq_hello_module_init);//驱动入口函数
module_exit(wbyq_hello_module_cleanup);//驱动出口函数MODULE_LICENSE("GPL");//驱动注册协议
MODULE_AUTHOR("it_ashui");
MODULE_DESCRIPTION("Exynos4 hello Driver");

4.3 驱动编译

KER_ADD=/home/wbyq/src_pack/linux-3.5  #linux3.5内核的Makefile位置
all:make -C $(KER_ADD) M=`pwd` modules #通过调用linux3.5内核的Makefile文件进行编译cp ./*.ko /home/wbyq/src_pack/rootfs/code #将驱动文件拷贝到code目录下make -C $(KER_ADD) M=`pwd` modules clean  #清空文件
obj-m +=hello_drv.o #添加依赖文件

4.4 驱动安装

[root@wbyq code]# insmod hello_drv.ko  #安装驱动
[ 4684.795000] 驱动入口,驱动注册成功[root@wbyq code]# modinfo hello_drv.ko  #查看驱动详细信息
modinfo: can't open '/lib/modules/3.5.0-FriendlyARM/modules.dep': No such file or directory
[root@wbyq code]# mkdir /lib/modules/3.5.0-FriendlyARM/ -p
[root@wbyq code]# touch /lib/modules/3.5.0-FriendlyARM/modules.dep
[root@wbyq code]# lsmod #查看动态安装的驱动
hello_drv 612 0 - Live 0xbf000000 (O)
[root@wbyq code]# rmmod hello_drv.ko #注销驱动
[ 5610.635000] 驱动出口,驱动注销成功

5 编写蜂鸣器驱动

5.1 硬件接口


  蜂鸣接口:BP1 – GPD0_0 高电平驱动。

   GPD0_CON:0x1140 0000+0x00A0 --配置寄存器


   GPD0_DAT:0x1140 0000+0x00A4 --数据寄存器

5.2 蜂鸣器驱动层

   1.调用驱动注册和注销函数,在驱动入口函数中实现BEEP硬件接口配置。在驱动出口函数中完成硬件资源释放。
   2.通调用杂项设备驱动框架完成杂项设备注册,注册成功后在/dev生成beep的设备节点。完成应用层相关接口函数编写。

#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
/*驱动初始化*/
unsigned int *GPDO_CON;
unsigned int *GPDO_DAT;
int beep_open(struct inode *inode, struct file *file)/*对应应用层open函数*/
{printk("open函数调用成功\n");return 0;
}int beep_release(struct inode *inode, struct file *file) /*对应应用层close*/
{printk("releasse函数调用成功\n");*GPDO_DAT&=~(1<<0);return 0;
}
ssize_t beep_read(struct file *file, char __user * data, size_t size, loff_t *offset)/*对应应用层read*/
{int *p=(int *)data;*p=123;printk("read函数调用成功\n");return 4;
}
ssize_t beep_write(struct file *file, const char __user *data, size_t size, loff_t *offset)/*对应应用层write*/
{char buff[20];memcpy(buff,data,size);buff[size]='\0';printk("buff=%s\n",buff);if(strcmp(buff,"beep_on")==0)//开蜂鸣器{*GPDO_DAT|=1<<0;}else if(strcmp(buff,"beep_off")==0)//关蜂鸣器{*GPDO_DAT&=~(1<<0);}return size;//返回写入成功的字节数
}/*文件操作集合结构体*/
static struct file_operations beep_fops=
{.owner     = THIS_MODULE,/*当前模块*/.open        = beep_open,.release   = beep_release,.read       =beep_read,.write      =beep_write
};
/*杂项设备结构体*/
static struct miscdevice tiny4412_beep = {.minor           = MISC_DYNAMIC_MINOR,//次设备号,255表示由系统自动分配.name           = "beep", /*在/dev生成的设备节点名字*/.fops            = &beep_fops,
};
static int __init wbyq_beep_init(void)
{printk("驱动入口,驱动注册成功\n");/*蜂鸣器配置*/GPDO_CON=ioremap(0x114000A0, 4);//将GPDO_CON物理地址转换虚拟地址GPDO_DAT=ioremap(0x114000A4, 4);//将GPDO_DAT物理地址转换虚拟地址/*蜂鸣器*/*GPDO_CON&=0xfffffff0;//清除当前GPD0_0的配置*GPDO_CON|=0x00000001;//设置为输出模式/*注册杂项设备:在/dev下生成设备节点,实现应用层接口函数*/misc_register(&tiny4412_beep);return 0;
}
/*驱动释放*/
static void __exit wbyq_beep_cleanup(void)
{printk("驱动出口,驱动注销成功\n");/*注销杂项设备*/misc_deregister(&tiny4412_beep);iounmap(GPDO_CON);iounmap(GPDO_DAT);
}
module_init(wbyq_beep_init);//驱动入口函数
module_exit(wbyq_beep_cleanup);//驱动出口函数MODULE_LICENSE("GPL");//驱动注册协议
MODULE_AUTHOR("it_ashui");
MODULE_DESCRIPTION("Exynos4 beep Driver");

   杂项设备主设备为10,次设备可填值为0~254;当次设备号填255时表示有系统分配。

5.3 蜂鸣器应用层

   Linux下一切皆文件,操作设备就和操作文件一样。只需要open打开设备、读写设备、操作完成关闭设备即可。

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main()
{/*1.打开设备*/int fd=open("/dev/beep",2);if(fd<0){printf("/dev/beep 设备打开失败\n");return 0;}int data=0;int size;/*读写文件*/size=read(fd,&data,4);printf("size=%d,data=%d\n",size,data);while(1){write(fd,"beep_on",strlen("beep_on"));//开蜂鸣器sleep(1);write(fd,"beep_off",strlen("beep_off"));//关蜂鸣器sleep(1);}close(fd);//关闭文件
}

   在Linux内核中,设备节点的访问是通过主设备+次设备号的组合来完成的,占32位,主设备号是20 ~ 31位。次设备号是0 ~ 19位。

Linux下驱动开发相关推荐

  1. Linux下驱动开发_块设备驱动开发(硬件上采用SD卡+SPI协议)

    一.前言 块设备主要为存储设备设计的框架. 在前面章节Linux下驱动开发_块设备驱动开发(内存模拟存储) 里介绍了块设备驱动编写思路,并且利用内存模拟了硬件存储,完成了块设备驱动开发测试.这一篇文章 ...

  2. 《Linux设备驱动开发详解 A》一一2.3 接口与总线

    本节书摘来华章计算机出版社<Linux设备驱动开发详解 A>一书中的第2章,第2.3节,作者:宋宝华 更多章节内容可以访问云栖社区"华章计算机"公众号查看.1 2.3 ...

  3. Linux字符驱动开发学习总结

    linux驱动编写(虚拟字符设备编写) 昨天我们说了一些简单模块编写方法,但是终归没有涉及到设备的编写内容,今天我们就可以了解一下相关方面的内容,并且用一个实例来说明在linux上面设备是如何编写的. ...

  4. Linux设备驱动开发概述

    作者:宋宝华 email:author@linuxdriver.cn 在过去这些年,Linux已经成功应用于服务器和桌面系统,而近年来,随着嵌入式系统应用的持续升温,Linux也开始广泛应用于嵌入式领 ...

  5. Linux 设备驱动开发思想 —— 驱动分层与驱动分离

    前面我们学习I2C.USB.SD驱动时,有没有发现一个共性,就是在驱动开发时,每个驱动都分层三部分,由上到下分别是: 1.XXX 设备驱动 2.XXX 核心层 3.XXX 主机控制器驱动 而需要我们编 ...

  6. Linux 设备驱动开发 —— 设备树在platform设备驱动中的使用

    关与设备树的概念,我们在Exynos4412 内核移植(六)-- 设备树解析 里面已经学习过,下面看一下设备树在设备驱动开发中起到的作用 Device Tree是一种描述硬件的数据结构,设备树源(De ...

  7. linux cached释放_正点原子Linux第四十一章嵌入式Linux LED驱动开发实验

    1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第四十一章嵌入式Linux LED驱动开发实验 上一章我 ...

  8. Linux设备驱动开发详解 第3版 (即 Linux设备驱动开发详解 基于最新的Linux 4 0内核 )前言

    Linux从未停歇脚步.Linus Torvalds,世界上最伟大的程序员之一,Linux内核的创始人,Git的缔造者,仍然在没日没夜的合并补丁,升级内核.做技术,从来没有终南捷径,拼的就是坐冷板凳的 ...

  9. 【正点原子Linux连载】第四十一章 嵌入式Linux LED驱动开发实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

最新文章

  1. Android studio 导入jar 文件
  2. 你是如何自学 Python 的?
  3. matlab如求曲线插值点,两条曲线之间的插值(matlab)
  4. 浏览器同部署了https的服务器交互的过程
  5. 吐血整理《计算机网络五层协议之物理层(下)》
  6. linux---socket编程
  7. 77种互联网盈利创新模式(3)
  8. AnnotationTransactionAttributeSource is only available on Java 1.5 and higher
  9. [原创]CAN总线数据计算器V1.01
  10. 面试题10-二进制中1的个数
  11. 偏微分方程的数值解(一):定解问题 差分解法
  12. 计算机绘图AUTOcad2007证要考吗,计算机绘图和 与考证(AutoCAD2005).ppt
  13. 我的时间管理类培训PPT
  14. 合格的程序员精通c语言吗,只精通一门C语言的人算不算程序员?
  15. 键盘鼠标是计算机标准输入输出设备,输入输出设备.ppt
  16. Linux lolcat输出彩色格言
  17. “光庭杯”第五届华中北区程序设计邀请赛 暨 WHU第八届程序设计竞赛(部分解题报告)
  18. 一些经常送福利的技术公众号
  19. JavaScript框架比较:AngularJS vs ReactJS vs EmberJS
  20. 中国工程机器人大赛暨国际公开赛(RoboWork)

热门文章

  1. 创意美观的思维导图模板分享
  2. 调用微信的收货地址和我的地址功能页面。
  3. JavaWeb核心技术——RequestResponse用户登录注册案例
  4. 1082 射击比赛 (20分)
  5. php 计算函数 相加,比较,相除,相减,求余,相乘
  6. CPU怎么选择,单核cpu与多核cpu的区别
  7. 各主流编程语言适用领域——软件工程
  8. 11-DNS域名解析服务
  9. 阿里云官网购买云服务器完整版流程(图文教程)
  10. 冒险岛2虚拟机 显示服务器连接失败怎么办 显示TP解决方法