什么是设备
设备(device): 是提供输入或输出功能的一种载体,其包括物理设备(对实际存在的物理硬件的抽象)例如,键盘是一种输入设备,硬盘是输入和输出设备。也包括虚拟设备(不依赖于特定的物理硬件,仅是内核自身提供的模拟/虚拟功能). 例如:虚拟控制台是输入和输出设备。每个设备都对应一个文件(设备文件),这些设备文件统一放在一个公共位置/dev下,通过设备文件(或称设备节点)来使用驱动程序操作设备。
设备按照存取方式的不同,分为两类:
字符设备: 字符设备按字符处理。最明显的例子是键盘,其中每个键在设备上生成一个字符。还有鼠标,每一个动作或按钮点击都会发送一个字符到 /dev/mouse 设备。字符设备可理解为商品零售商,可以一件一件的卖,卖的细自然就卖的少. 块设备:以更大的块读取数据的存储设备,如IDE硬盘也叫机械硬盘(/dev/hd)、SCSI硬盘也叫固态硬盘(/dev/sd) 和 CD-ROM (/dev/cdrom) 是块设备。输入输出与块设备的交互处理数据块,允许大量数据来回移动提高效率。块设备可理解为商品批发商,必须一箱一箱的卖,卖的粗但吞吐量大. 字符设备还是块设备的定义属于内核设备访问层,与实际物理设备的特性无必然联系。设备访问层下面是驱动程序,存取方式取决于驱动程序是否支持,也可以同时支持两种方式访问物理设备,是块设备还是字符设备由使用者(往往是内核)决定。
鸿蒙系统中常见的字符设备如下:
mem | 内存设备
/dev/mem 物理内存的全镜像。可以用来直接存取物理内存。
/dev/kmem 内核看到的虚拟内存的全镜像。其访问的是虚拟内存而不是物理内存。
/dev/null 空设备。也叫黑洞设备,任何写入都将被直接丢弃(但返回"成功");任何读取都将得到EOF(文件结束标志)。
/dev/port 存取I/O端口
/dev/zero 零流源。任何写入都将被直接丢弃(但返回"成功");任何读取都将得到无限多的二进制零流。
/dev/full 满设备。任何写入都将失败,并把errno设为ENOSPC(没有剩余空间);任何读取都将得到无限多的二进制零流。
这个设备通常被用来测试程序在遇到磁盘无剩余空间错误时的行为。
/dev/random 真随机数发生器。以背景噪声数据或硬件随机数发生器作为熵池,读取时会返回小于熵池噪声总数的随机字节。
若熵池空了,读操作将会被阻塞,直到收集到了足够的环境噪声为止。建议用于需要生成高强度密钥的场合。
[注意]虽然允许写入,但企图通过写入此文件来"预存"随机数是徒劳的,因为写入的数据对输出并无影响。
/dev/urandom 伪随机数发生器。更快,但是不够安全。仅用于对安全性要求不高的场合。
即使熵池空了,读操作也不会被阻塞,而是把已经产生的随机数做为种子来产生新的随机数。
[注意]虽然允许写入,但企图通过写入此文件来"预存"随机数是徒劳的,因为写入的数据对输出并无影响。
/dev/aio 异步I/O通知接口
/dev/kmsg 任何对该文件的写入都将作为printk的输出;而读取则得到printk的输出缓冲区内容。<span style="background-color: rgb(255, 255, 255);"> </span>
在鸿蒙,/dev/mem 是一个字符设备, 源文件是 kernel/drivers/char/mem/src/mem.c, 这个设备文件是专门用来读写物理地址用的。里面的内容是所有物理内存的地址以及内容信息。通常只有root用户对其有读写权限。利用 mmap和/dev/mem建立起直接读写系统物理内存的渠道。利用/dev/mem和mmap导出系统物理地址,免去了用户虚拟地址到内核逻辑地址的繁琐拷贝,提升效率。//文件和线性区的映射关系
static ssize_t MemMap(struct file *filep, LosVmMapRegion *region)
{
#ifdef LOSCFG_KERNEL_VM
size_t size = region->range.size;
PADDR_T paddr = region->pgOff << PAGE_SHIFT;
VADDR_T vaddr = region->range.base;
LosVmSpace *space = LOS_SpaceGet(vaddr);
if ((paddr >= SYS_MEM_BASE) && (paddr < SYS_MEM_END)) {
return -EINVAL;
}
/* Peripheral register memory adds strongly ordered attributes */
region->regionFlags |= VM_MAP_REGION_FLAG_STRONGLY_ORDERED;
if (space == NULL) {
return -EAGAIN;
}//映射
if (LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, size >> PAGE_SHIFT, region->regionFlags) <= 0) {
return -EAGAIN;
}
#else
UNUSED(filep);
UNUSED(region);
#endif
return 0;
}
// vfs 接口实现
static const struct file_operations_vfs g_memDevOps = {
MemOpen, /* open */
MemClose, /* close */
MemRead, /* read */
MemWrite, /* write */
NULL, /* seek */
NULL, /* ioctl */
MemMap, /* mmap */
#ifndef CONFIG_DISABLE_POLL
NULL, /* poll */
#endif
NULL, /* unlink */
};
// 注册/dev/mem 的驱动程序
int DevMemRegister(void)
{
return register_driver("/dev/mem", &g_memDevOps, 0666, 0); /* 0666: file mode */
}
tty | 终端设备
TTY 是 Teletype 或 Teletypewriter 的缩写,原来是指电传打字机,后来这种设备逐渐键盘和显示器取代。不管是电传打字机还是键盘显示器,都是作为计算机的终端设备存在的,所以 TTY 也泛指计算机的终端(terminal)设备,一般分成以下几种 串行端口终端(/dev/ttySn) 伪终端(/dev/pty/) 控制终端(/dev/tty) 控制台终端(/dev/ttyn, /dev/console),将在后续 控制台篇 中详细说明
RTC | 时钟设备
/dev/rtc 实时时钟(Real Time Clock)
I2C | 总线设备
/dev/i2c-0 第1个 I2C 适配器
...
/dev/i2c-n 第n-1个 I2C 适配器
I2C(Inter Integrated Circuit)总线是由Philips公司开发的一种简单、双向二线制同步串行总线。 I2C以主从方式工作,通常有一个主设备和一个或者多个从设备,主从设备通过SDA(SerialData)串行数据线以及SCL(SerialClock)串行时钟线两根线相连,如下图所示。 I2C数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。数据传输以字节为单位,高位在前,逐个bit进行传输。 I2C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。 I2C接口定义了完成I2C传输的通用方法集合,包括:
I2C控制器管理: 打开或关闭I2C控制器 I2C消息传输:通过消息传输结构体数组进行自定义传输
SPI | 串行外设设备 UART | 串口设备
/dev/ttyS0 第1个UART串口(Serial port)
...
/dev/ttyS200 第199个UART串口
LCD | 屏显设备
/dev/lcd 液晶(LCD)显示屏<span style="background-color: rgb(255, 255, 255);"> </span>
LCD(Liquid Crystal Display)液晶显示驱动,对LCD进行上电,并通过接口初始化LCD内部寄存器,使LCD正常工作。Display驱动模型基于HDF( Hardware Driver Foundation)驱动框架开发,实现跨OS、跨平台,为LCD硬件提供上下电功能、发送初始化序列功能,使LCD进入正常的工作模式,显示芯片平台侧的图像数据. 基于HDF驱动框架的Display驱动模型
Touchscreen | 触摸设备
Touch(触摸芯片)是 UI 设计中进行人机交互重要的一部分,一个完整的 UI 设计应该包括输入信息和输出信息,LCD 等屏幕设备负责显示输出,那么 Touch 设备就负责触点信息采集作为信息输入。 Touch 设备与主机通讯一般都是采用 I2C 总线协议来进行数据交互,所以一个 Touch 设备,就是一个标准的 I2C 从设备,而且为了提高接收 Touch 数据的实时性,触摸芯片都会提供中断支持,当有触摸事件(抬起,按下,移动)发生时,会触发中断通知 MCU 有触摸事件。主机可以通过中断回调函数去读取触摸点信息。 Touchscreen器件的硬件接口相对简单,根据PIN脚的属性,可以简单分为如下三类:
Touchscreen驱动用于驱动触摸屏使其正常工作,该驱动主要完成如下工作:对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口(I2C或SPI)、设定input相关配置、下载及更新固件等操作。 鸿蒙基于input驱动模型开发touchscreen器件驱动。Input驱动模型基于HDF驱动框架、PLATFORM接口、OSAL接口进行开发,向上对接规范化的驱动接口HDI(Hardware Driver Interface)层,通过Input-HDI层对外提供硬件能力,即上层input service可以通过HDI接口层获取相应的驱动能力,进而操控touchscreen等输入设备。 基于HDF驱动框架的input驱动模型
sensor | 传感设备
/dev/biometric/sensor0/fingerprint 第1个设备的第1个指纹传感器
/dev/biometric/sensor0/iris 第1个设备的第1个虹膜传感器
/dev/biometric/sensor0/retina 第1个设备的第1个视网膜传感器
/dev/biometric/sensor0/voiceprint 第1个设备的第1个声波传感器
/dev/biometric/sensor0/facial 第1个设备的第1个面部传感器
/dev/biometric/sensor0/hand 第1个设备的第1个手掌传感器
/dev/biometric/sensor1/fingerprint 第2个设备的第1个指纹传感器
/dev/biometric/sensor2/fingerprint 第3个设备的第1个指纹传感器
Sensor(传感器)是物联网重要的一部分,Sensor 之于物联网”就相当于“眼睛之于人类"。人类如果没有了眼睛就看不到这大千的花花世界,对于物联网来说也是一样。 如今随着物联网的发展,已经有大量的 Sensor 被开发出来供开发者选择了,如:加速度计(Accelerometer)、磁力计(Magnetometer)、陀螺仪(Gyroscope)、气压计(Barometer/pressure)、湿度计(Humidometer)等。这些传感器,世界上的各大半导体厂商都有生产,虽然增加了市场的可选择性,同时也加大了应用程序开发的难度。因为不同的传感器厂商、不同的传感器都需要配套自己独有的驱动才能运转起来,这样在开发应用程序的时候就需要针对不同的传感器做适配,自然加大了开发难度。 为了降低应用开发的难度,增加传感器驱动的可复用性, 鸿蒙Sensor(传感器)驱动模块为上层Sensor服务系统提供稳定的Sensor基础能力API,包括Sensor列表查询、Sensor启停、Sensor订阅及去订阅,Sensor参数配置等功能;基于HDF(Hardware Driver Foundation)驱动框架开发的Sensor驱动模型,实现跨操作系统迁移,器件差异配置等功能。 鸿蒙Sensor驱动模型图
watchdog | 看门狗
/dev/watchdog 看门狗(CONFIG_WATCHDOG)
/dev/watchdogs/0 第一只看门狗
...
/dev/watchdogs/n 第n-1只看门狗
WLAN | 无线网络设备 WLAN是基于HDF(Hardware Driver Foundation)驱动框架开发的模块,该模块可实现跨操作系统迁移,自适应器件差异,模块化拼装编译等功能。各WLAN厂商驱动开发人员可根据WLAN模块提供的向下统一接口适配各自的驱动代码,实现如下能力:建立/关闭WLAN热点、扫描、关联WLAN热点等;对HDI层向上提供能力如下:设置MAC地址、设置发射功率、获取设备的MAC地址等。 WLAN框架
WLAN模块有三部分对外开放的API接口
对HDI层提供的能力接口。 驱动直接调用WLAN模块能力接口。 提供给各厂商实现的能力接口。
鸿蒙内核源码分析.总目录
v08.xx 鸿蒙内核源码分析(总目录) | 百万汉字注解 百篇博客分析 | 51 .c .h .o
百万汉字注解.百篇博客分析
百万汉字注解 >> 精读鸿蒙源码,中文注解分析, 深挖地基工程,大脑永久记忆,四大码仓每日同步更新< gitee | github | csdn | coding >
百篇博客分析 >> 故事说内核,问答式导读,生活式比喻,表格化说明,图形化展示,主流站点定期更新中< 51cto | csdn | harmony | osc >
关注不迷路.代码即人生
QQ群:790015635 | 入群请填: 666
原创不易,欢迎转载,但请注明出处.