DRV亮,在驱动学习时,如何解释

            串口驅动程序学习

  本文主要实现对串口驱动程序初始化的分析

一、串口驱动中的数据结构

  尽管一个特定的UART设备驱动完全可以按照tty驱动嘚设计方法来设计即定义tty_driver并实现tty_operations其中的成员函数,但是Linux已经在文件serial_core.c中实现了UART设备的通用tty驱动层称为串口核心层,这样UART驱动的主要任務变成了实现serial_core.c中定义的一组uart_xxx接口而非tty_xxx接口。

1.1下图描述了串行系统间的层次结构关系,可以概括为:

1.2下图是串口核心层在整个tty源文件关系及数據流向中的位置:

二、串口驱动中的数据结构

1.4使用到的数据结构

1.4.1其中一个串口驱动对应一个struct uart_driver当然一个驱动是可以对应多个设备的:

其中的uart_state昰设备状态结构结构体:

   就可以获取设备私有信息结构体

1.4.2uart_port用于描述一个UART端口(直接对应于一个串口)的I/O端口或者IO内存地址等信息--->即┅个uart_port对应一个端口

  因为把uart驱动注册为platform驱动,当平台驱动与平台设备进行匹配的时候会调用平台总线的match函数匹配成功后就会调用平台驅动的xxx_probe()函数来进行一系列的初始化工作。

完成应用程序通过驱动控制硬件嘚实现实验建立在之前的框架上,我们先实现用户层与内核层之间的数据交互驱动程序拿到用户传来的指令后,就可以执行点灯的动莋了

应用程序与驱动数据交互

copy_to_user是将数据从内核空间拷贝到用户空间

copy_from_user将数据从用户空间拷贝到内核空间

控制外设,其实就是控制寄存器地址由于MMU(内存管理单元),内核层的驱动不能直接操作硬件上的地址通过虚拟地址来实现。

在之前的框架的基础上一方面对下实现叻硬件的操作,加载模块时将控制LED灯的引脚(GPX2_7)地址的映射并设置引脚控制寄存器为输出模式;另一方面,实现对应用层接口的封装當用户程序向驱动写数据时,chr_drv_write函数接收并且判断该数值如果是正数则点亮LED灯,否者灭灯

//将物理地址映射成为虚拟地址,用指针指向这個地址

在应用层的角度一切皆是文件。程序把驱动当成一个文件(设备结点)来操作打开文件后,间隔一段时间写入0或1最终实现led灯嘚闪烁。


编译并移动文件到nfs根目录

开发板加载模块执行应用程序

观察开发板上led是闪烁状态。

回顾一下之前的字符设备驱动编程:

在我们为多个设备编写驱动时会发现大部分流程是相同的,如上其实内核中已经实现大部分通用的功能,例如1~4,6~7我们只需要实现硬件的部分与差异化代码即可。通用的部分就是Linux内核中的驱动框架其实在linux中我们要做的工作很少,但是想要知道怎么搞却要学习很多嘚知识。

linux程序框架的概念

  1内核引入程序框架思想:代码可重用,可维护,可伸缩
  2,通用功能 写一次 可重用性好
  3差异功能 平台不哃 可移植性好
  4,内核框架采用分层
  5建立设备模型,它外在表现 平台设备驱动(总线,设备,驱动来实现的)
  6,面向对象编程方式

  B繼承于AB是A的子类

//2 初始化(底层硬件初始化)

初级驱动和高级驱动的不同特点

  2.代码量大,复杂 不从零开始写代码(参考内核提供代码,厂商提供玳码),分析代码,看代码实现原理,移植代码
  3.从宏观角度把握框架原理 如何实现,分层,要做什么?
  4.软硬结合紧密,采用现成模板来实现

  1,熟悉各种设备驱动子系统特点(软件,硬件)
  2熟悉各种设备驱动的工作流程(框架实现原理)
  3,采用模板学习如何移植各种设备驱动

学习方法源码分析+接口驱动代码编程
  1控制器工作原理
  3,研究samsung的驱动,看别人代码(提高代码阅读能力,分析能力)
  4移植驱动/写驱动

我要回帖

 

随机推荐