分类【嵌入式Linux】


9
Sep 11

编写Linux网卡设备驱动(下)

本文介绍基于Realtek 8139芯片PCI接口的网卡驱动程序。我选择了Realtek芯片有两个原因:首先,Realtek提供免费的芯片技术手册; 第二,芯片相当便宜。

本文介绍的驱动程序是最基本的,它只有发送和接收数据包功能,和做一些简单的统计。对于一个全面和专业级的驱动程序,请参阅Linux源码。

本文(下)的主要内容是在前一文(上)实现的驱动模板的基础上进一步实现网卡驱动的分组收发功能。除了实现发包接口和收包接口,原模板上的初始化接口、打开接口和私有数据都要改动。另外,网卡的硬件收发原理在《RTL8139的收发原理》(下述简称《收发原理》)已经阐述得很清楚,本文是对《收发原理》中的理念用代码具体实现。 Continue reading →


6
Sep 11

RTL8139收发原理

RTL8139的硬件接口由256个字节寄存器组成,这些寄存器按可读性分为只读和可读写两类;按实现收发功能分为发送相关的和接收相关的;按实现收发原理的角色分为,配置寄存器、命令寄存器(或者叫控制寄存器)和状态寄存器;没有数据寄存器,因为RTL8139是PCI设备,使用了一片DMAble的缓冲区作“数据寄存器”。

本文简要地介绍一下RTL8139收发原理,和实现原理的基本寄存器,其它特色功能寄存器请查阅手册。本文先按实现收包原理、发包原理和全局原理,三类精要地介绍相关实现的寄存器。最后简述收包发包过程。 Continue reading →


2
Sep 11

编写Linux网络设备驱动(上)

本文介绍基于Realtek 8139芯片PCI接口的网卡驱动程序。我选择了Realtek芯片有两个原因:首先,Realtek提供免费的芯片技术手册; 第二,芯片相当便宜。

本文介绍的驱动程序是最基本的,它只有发送和接收数据包功能,和做一些简单的统计。对于一个全面和专业级的驱动程序,请参阅Linux源码。

本文代码是基于Linux2.4.18上测试的,建议编译一个内核,此内核没有任何形式RealTek8139驱动程序,以避免有莫名的BUG。最后,你将网卡插入PCI插槽,我们可以开始了。 Continue reading →


28
Aug 11

IP网络层与网络设备之间分组收发原理

1.引子

当我们为字符设备或块设备编写驱动程序时,我们实现逻辑设备的接口是文件读写接口——file_operations,这个接口基本上直接面向用户空间程序的。而我们要为网络设备编写驱动则不然了,用户空间程序是通过标准套接口(sockets)系统调用来使用网络功能的,用户空间程序与网络设备之间夹着一层TCP/IP协议栈程序。也就是说,当我们为网络设备编写驱动程序时,实现的设备接口是给TCP/IP协议栈“用”的。

事实上,现代操作系统的实现里,TCP/IP协议栈还不是直接“用”网络设备发送接收数据包的,因为为了实现更好网络性能、控制网络流量等,协议栈的第三层——IP网络层和第二层——网络设备层之间发生很多代码活动(activity)。如果不深入理解这两层之间的代码活动(数据流和控制流),那是很难理解和编写网络设备驱动的。 Continue reading →


19
Jul 11

设备、驱动和开发者

自接触Linux设备驱动程序以来,一直在思考设备、设备驱动和设备驱动开发者三者之间的关系,也曾经写下一些粗略的思考碎片(看这里);随着对硬件和内核的认识的增加,三者的关系也便更清晰。

设备

设备是系统的一种,有接口、用户、设计者和维护者等系统属性。特别注意的是设备可以是物理的,也可以是逻辑的;因而,设备的实现形式不同,其接口、用户、设计者和维护者的实现形式也各有不同。例如在设备接口上,[显示终端设备]的接口显示器(上的字符)和键盘,串口设备的接口是12个寄存器,一支软件虚拟的TTY设备的接口是某种C函数等。

一些直观概念扰乱了我们认清设备、驱动和开发者三者的关系,例如,“驱动程序是为某设备编写的一集C函数”和“设备就是主板上芯片、扩展板和通过USB线链接的移动盘”。下文开始讲解设备、驱动和开发者三者的关系,可能有点费解,解理的关键是何为“逻辑设备”。
Continue reading →


16
Jul 11

TTY设备驱动结构

本文为你展示基于“串口通信设备”的TTY设备驱动程序内部结构,并讲述这些驱动是如何实现链路层通信协议(包括ppp和slip)的应用。本文的代码基于2.4内核,大部分适用于2.2和2.0[注]。

注:本文的代码虽然基于2.4内核,但是结构原理在现在内核版本仍然存在。

串口驱动误解

当我们说【串口驱动】的时候,我们第一个想到的东西是/dev/ttyS0,因为它是大家所熟知的串口通信的设备文件(至少在PC系统上如此)。由于/dev/ttyS0是一个字符型的设备文件,大家都以为串口驱动是字符设备驱动,这种推断不能叫错,只是不够准确。 Continue reading →


14
Jul 11

udev——设备文件管理的用户空间实现

Abstract

自2.5版内核起,用户空间的进程可以通过sysfs文件系统访问按层次组织的所有系统的外部设备(包括物理设备和虚拟设备)的元信息。另外,“/sbin/hotplug” 会在系统设备热插拔时向用户空间发出提示。具备了这两项功能后,在用户空间内动态管理设备文件(/dev目录)成为现实,一直需求的更灵活的设备名分配策略成为现实。

本报告文分析udev,一支代替devfs——只是实现动态管理/dev目录条目的方案——的用户空间程序,解决由devfs不能单独解决的一些问题:

  • 第一,无论设备何时何处插入都使用同一个设备名;
  • 第二,发现并用户空间提示系统设备发生变动;
  • 第三,灵活的设备命名方案;
  • 第四,允许内核使用动态的主设备号和次设备号;
  • 第五,将命名策略移出内核空间

本文将解释为什么在用户空间实现的udev会优于在内核实现的devfs,并且详述在实现udev上的一些设计考虑。另外,这里也讲解udve的工作原理和怎样给udev制作插件(如命名方案naming scheme),还有一些udev使用上需要考虑的事情。 Continue reading →


2
Jul 11

关于I²C和SPI总线协议

I²C vs SPI

现今,在低端数字通信应用领域,我们随处可见I²C (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种通信协议非常适合近距离低速芯片间通信。Philips(for I²C)和Motorola(for SPI) 出于不同背景和市场需求制定了这两种标准通信协议。

I²C 开发于1982年,当时是为了给电视机内的CPU和外围芯片提供更简易的互联方式。电视机是最早的嵌入式系统之一,而最初的嵌入系统是使用内存映射(memory-mapped I/O)的方式来互联微控制器和外围设备的。要实现内存映射,设备必须并联入微控制器的数据线和地址线,这种方式在连接多个外设时需大量线路和额外地址解码芯片,很不方便并且成本高。

为了节省微控制器的引脚和和额外的逻辑芯片,使印刷电路板更简单,成本更低,位于荷兰的Philips实验室开发了 ‘Inter-Integrated Circuit’,IIC 或 I²C ,一种只使用二根线接连所有外围芯片的总线协议。最初的标准定义总线速度为100kbps。经历几次修订,主要是1995年的400kbps,1998的3.4Mbps。 Continue reading →


29
Jun 11

8051异步串口的收发原理

异步串口通信的基本原理是,点对点异步,没有时钟线没有地址,以低电平为开始位,高电平闲置,通信双方约定相同的数据帧大小,还有在相同的波特率下,收发顺利进行。异步串行通信可双线同时收发,为全双工通信。数据帧内容包括一个开始位、5到9个数据位、一个可选的检验位和一到两位的停止位。

以上是异步串口通信的通用原理,但具体的通信过程是怎样的呢?这就得拿一个具体的实现——8051的built-in UART来分析一下了。 Continue reading →


8
May 11

深度把握In-system programming

在嵌入式开发领域,[在-系统式]编程(In-System Programming,下称ISP)是指一些可编程逻辑器件(programmable logic devices),如微控制器(的EEPROM),可以不必从[应用系统]中卸下,直接在应用系统上进行“再编程”。逻辑器件是组成数字电路(用于电计算的组合电路和时序电路)的必备元件,而 “可编程”是指这些元件的计算逻辑可重组,也叫重配置(reconfigure)。要深入理解ISP,应用ISP,必须先厘清何为“在-系统式”,何为“编程”。

Continue reading →