原文出处:http://www.cnblogs.com/jacklu/p/4722563.html

Linux设备分类

设备的驱动程序也要像裸机程序那样进行一些硬件操作,不同的是驱动程序需要"融合进内核里",因此需要在驱动程序中加入操作系统规定的接口,这些接口都是独立于设备的。虽然操作系统为驱动程序设计者带来了"麻烦",却为应用程序设计者带来了"便利"。

Linux下设备分为三类:字符设备、块设备、网络设备。

字符设备是指必须以串行顺序访问的设备,比如触屏;块设备是指可以以任意顺序访问的设备,即以块为单位进行操作,比如键盘;

字符设备不经过Cache,块设备数据经过Cache。两者的驱动程序设计差异较大。除了网络设备外,字符设备和块设备的驱动程序都被映射到文件系统中,通过调用open、read、write、close就能访问。需要说明一点,C语言的fopen、fread、fwrite、fclose实际上也是做相应的系统调用。下图是一个Linux下不同驱动种类的结构关系图:

驱动开发所需知识储备

做好驱动程序开发,需要开发者有良好的硬件基础、C语言基础、Linux内核基础以及多任务并发和控制的基础。

Linux上浏览内核源码,推荐使用的工具是vim+cscope或者vim+ctags。

有无操作系统的驱动程序区别

下面以led驱动为例,来说明有无操作系统的区别。

一般处理器有GPIO有两个寄存器,即控制寄存器和数据寄存器。

无操作系统时,一般需要的函数有三个,即

LightInit()//设置控制寄存器为输出模式

LightOn()//打开Led

LightOff()//熄灭Led

Linux操作系统下,可以使用字符设备驱动程序框架来编写,根据Linux下的编程习惯,可以重新将其命名为light_init(),light_on,light_off

代码结构如下:

//定义设备结构体

struct light_dev{

    struct cdev cdev;//字符设备结构体

    unsigned char value;

}

struct light_dev *light_devp;

int light_major = LIGHT_MAJOR;

MODULE_AUTHOR(" ");

MODULE_LICENSE(" ");

int light_open(struct inode *inode, struct file *filp){}

int light_release(struct inode *inode, struct file *filp){}

//读写设备

ssize_t light_read(struct file *filp, char _user *buf, size_t count, loff_t *f_pos){}

ssize_t light_write(struct file *filp, const char _user *buf, size_t count, loff_t *f_pos){}

//ioctl

int light_ioctl(struct inode *inode, struct file *flip, unsigned int cmd, unsigned long arg){}

struct file_operations light_fops={

    .ower = THIS_MODULE;

    .read = light_read;

    .write = light_write;

    .open = light_open;

    .release = light_release;

    .ioctl = light_ioctl;

}

//设置字符设备cdev结构体

static void light_setup_cdev(struct light_dev *dev, int index){}

//模块加载函数

int light_init(void)

//模块卸载函数

int light_cleanup(void)

module_init(light_init)

module_exit(light_cleanup)

这只是一个程序的结构,可以看出,与裸机的驱动程序相比,Linux下的驱动程序代码复杂很多。

Linux设备驱动开发的硬件基础

RISC和CISC计算机的区别:RISC指令周期短,代码量大;CISC指令复杂,指令周期长,代码量小。

目前ROM基本上都使用Flash,NOR(或非)和NAND(与非)是两种主流的Flash。

NOR Flash的特点是可在芯片内执行代码,接口简单,不需要再加额外的控制芯片;NAND Flash的特点是块访问,接口需要再加入控制芯片,不能在芯片内部执行代码。NAND 的发生位反转的几率大于NOR,在使用时,应采用错误检测、错误改正算法(EDC/ECC)。Flash都是只能将1写为0,在烧写前,需要将Flash全置位,所有字节都为0xff。

DRAM以电荷形式存储在电容器中,需要定期刷新;SDRAM也是DRAM的范畴。CAM是以内容寻址的特殊RAM,输入需要查询的数据,输出数据地址和匹配标识,在数据检索中有很大优势。

*开漏输出、集电极开路输出是指需要上拉电阻才能输出高电平。

驱动工程师对硬件比IC工程师要更宏观。驱动工程师一般不需要分析时序图,但是许多企业的驱动工程师还需要承担电路板的调试工作,因此还需要了解一些电路时序的分析。

真实的电路必须满足芯片手册上的建立时间和保持时间的最低要求。查看datasheet时,没有必要通读全屏,要学会查看主要的信息内容。

Linux内核代码结构

  • arch:与不同CPU架构相关的代码
  • block:块设备驱动IO调度
  • crypto:相关算法,包括加密、散列、压缩、CRC校验等算法
  • Document:内核各部分的注释与解释
  • drivers:驱动,不同驱动有不同的子文件夹
  • fs:文件系统
  • include:头文件
  • init:初始化相关代码
  • ipc:进程通信
  • kernel:内核部分
  • lib:库文件代码
  • mm:内存管理代码
  • net:网络相关代码,实现各种协议
  • scripts:配置内核脚本
  • security:安全相关
  • sound:音频设备驱动
  • usr:用于打包压缩的cpio

Linux内核主要由进程调度、内存管理、虚拟文件系统、网络接口、进程通信组成。

内核空间和用户空间

CPU内部往往都实现了不同的操作模式。

比如ARM的七种工作模式:

  • 用户模式(usr)绝大多数应用程序运行在此模式
  • 快速中断模式(fiq)用于高速数据传输
  • 外部中断模式(irp)用于通用中断处理
  • 管理模式(svc)
  • 数据访问模式(abt)
  • 系统模式(sys)
  • 未定义指令终止模式(und)

ARM+Linux采用SWI,从usr模式进入svc模式;x86处理器包含4个不同的特权级(0-3)下,Linux的用户代码运行在特权级3,系统内核运行在特权级0

Linux只能通过系统调用或者硬件中断完成从用户空间到内核空间的控制转换。

内核的编译与加载

在linux内核中增加程序需要完成以下3项工作:

将代码加入到linux的相应目录;

在目录的Kconfig中加入相应的编译配置选项;

在目录的Makefile中增加新项目的编译条目。

Linux下的C编码风格

Windows下,宏全部大写,变量第一个单词小写,其后每一个单词的首字母都大写,函数名每个单词的首字母都大写。

例如:

#define MYLINUX

int myLinux;

int MyLinux(void);

而Linux 下,采用如下的风格:

#define MYLINUX

int my_linux;

int my_linux(void);

Linux代码缩进使用8个字符,对于结构体、if等{不另起一行,函数另起一行。

do{}while(0)主要用于宏定义中,其使用完全是为了保证宏定义无错误的编译。

goto只用于出现错误解决错误时。

参考资料:

《Linux设备驱动开发详解》 宋宝华

Linux驱动开发概述的更多相关文章

  1. 第一章 Andorid系统移植与驱动开发概述 - 读书笔记

    Android驱动月考1 第一章 Andorid系统移植与驱动开发概述 - 读书笔记 1.Android系统的架构: (1)Linux内核,Android是基于Linux内核的操作系统,并且开源,所以 ...

  2. 第一章Android系统移植与驱动开发概述--读书笔记

    以前,初步学习过嵌入式Linux驱动开发的基础课程,对于驱动开发可以说是有了一点点微末的基础吧.首先我们要对Android嵌入式系统有一个初步的认识,Android系统发展到今天已经具备了完善的架构. ...

  3. 嵌入式Linux驱动开发日记

    嵌入式Linux驱动开发日记 主机硬件环境 开发机:虚拟机Ubuntu12.04 内存: 1G 硬盘:80GB 目标板硬件环境 CPU: SP5V210 (开发板:QT210) SDRAM: 512M ...

  4. 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  5. 1Android系统移植与驱动开发概述

    1.Android系统架构分为四层,从下至上依次为Linux内核层,C/C++代码库.Android SDK API.应用程序,要熟悉每一层的内容以及功能: 2.Android移植分为应用移植和系统移 ...

  6. 【转】linux驱动开发的经典书籍

    原文网址:http://www.cnblogs.com/xmphoenix/archive/2012/03/27/2420044.html Linux驱动学习的最大困惑在于书籍的缺乏,市面上最常见的书 ...

  7. Linux驱动开发 -- 打开dev_dbg()

    Linux驱动开发 -- 打开dev_dbg() -- :: 分类: LINUX linux设备驱动调试,我们在内核中看到内核使用dev_dbg来控制输出信息,这个函数的实质是调用printk(KER ...

  8. Linux驱动开发学习的一些必要步骤

      1. 学会写简单的makefile 2. 编一应用程序,可以用makefile跑起来 3. 学会写驱动的makefile 4. 写一简单char驱动,makefile编译通过,可以insmod, ...

  9. 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

随机推荐

  1. 创建自己的Vagrant box

    这是一个关于Vagrant的学习系列,包含如下文章: Vagrant入门 创建自己的Vagrant box 用Vagrant搭建Jenkins构建环境 用Vagrant和Ansible搭建持续交付平台 ...

  2. Vue.js先入个门看看

    使用vue.js原文介绍:Vue.js是一个构建数据驱动的web界面库.Vue.js的目标是通过尽可能简单的API实现响应式数据绑定和组合的视图组件.vue.js上手非常简单,先看看几个例子: 例一: ...

  3. Javascript进阶之路-论对象的重要性

    要了解JavaScript对象,我们可以从对象创建.属性操作.对象方法这几个方面入手.概括起来,包括以下几模块: 1.创建对象        1.1 对象直接量        1.2 通过new创建对 ...

  4. 如何通过cmd开一个本地服务器

    1.首先你要下载安装node.js http://nodejs.cn/download/ 并且根据提示安装在自己的电脑上即可 2.打开cmd管理员窗口输入npm -v 检测node.js是否安装成功: ...

  5. 从零开始编写属于我的CMS:(一)前言

    一,项目背景 记得大学毕业课题,我就是选择做个CMS,不过当时虽然做了个,不过感觉不是很好,所以现在又重做了,顺便发上来供大家讨论的.虽然CMS不是什么特别的项目,但是还是想从一个普通项目学到更多的东 ...

  6. sqlserver 通用分页存储过程(转)

    USE [AAA_TYDC] GO /****** Object: StoredProcedure [dbo].[proc_DataPagination] Script Date: 11/20/201 ...

  7. mybatis 中的where标签

    mybatis中的where标签可以去除 开头的 and 或者 or 但是放在后面的不行 失败的: <select id="countNotesByParam" parame ...

  8. Linux Cmd Tool 系列之—history & search command history

    History cmd is for list Bash's log of the historical cmd you typed 1. List last n commands history n ...

  9. RequireJS入门之二——第二例(写自己的模块)

    第一节遗留的问题: 中文乱码:  修改require.js文件,搜索charset 关键字,修改为GBK:(貌似乱不乱码和jquery版本有问题,切换GBK和utf-8!!) 路      径:  仅 ...

  10. 玩转 H5 下拉上滑动效果

    在APP中我们经常会在页面下拉时看到一些动效,例如下拉图片跟随放大.下拉刷新出现loading动画等,这个交互细节在各个主流APP以及手机原生系统中随处可见,能为APP增添个性亮点. 一.背景 在我们 ...