一、背景说明
以前在互联网干活,主要讲的是4A、集群这些偏应用层的概念;现在转入物联网行业,主要讲的变成了串口、驱动这些偏硬件的概念。
之前没怎么注意,但这两天看着身旁的开发板,突然想到自己对硬件的很多概念都一知半解,有必要探究明确一番。
二、各种问题和名词
2.1 分时操作系统和实时操作系统的区别?
我们在网上常看到的定义如下:
分时操作系统指将CPU时间分成多个时间片段,以轮转方式供不同进程使用,常见于桌面系统。特征是可多用户同时登录(多用户必然导致多进程)、可同时运行多个程序。
实时操作系统指在规定时间内必须完成给定任务的系统,常见于嵌入式设备。
应该说分时操作系统定义没有什么问题,但实时操作系统的定义就让人看不懂。“规定时间内必须完成给定任务”?那我是不是让你一秒运行亿亿亿次也可以?那我们还研究什么超级计算机,大家写个实时操作系统就完事了,想跑多快跑多快----显然这是瞎扯淡,巧妇难为无米之炊到哪都一样,我不太明白为什么还到处是这种定义且没人纠正。
按个人理解,分时操作系统的关键点是时间分片、时间轮转、进程优先级;实时操作系统应该也是这几个点,唯一的区别应该是在进程优先级上。分时操作系统中高优先级任务到来时,任务被分配到下一时间片,需要等待当前任务用完当前时间片;而在实时操作系统中,当高优先级任务到来时,不管当前CPU在执行什么任务执行到什么状态都必须马上中止,转而执行到来的高优先级任务,至于什么时候完成或者完不完得成都得看硬件。
再回头看,我们为什么要使用实时操作系统而且尤其是嵌入式设备里面使用实时操作系统?原因是原先的嵌入式设备计算能力有限,比如我们希望1秒内处理完某件事情原来计算能力弱只能一来就处理才能满足需求,由于摩尔定律的作用现在计算能力很强了即便是分时也完全可以满足需求,反倒是运行实时操作系统不断切换上下文显得浪费CPU资源。事实上比如我们常听说的航空航天上常用的vxWorks,其市场已经萎缩其,开发者Wind River不得不开发基于Linux的分时操作系统Wind River Linux。当然一般工业界一般没什么门户之见而是不管黑猫白猫抓到老鼠就是好猫,如果真有时间要求严苛或需要占用大量计算资源的任务,现在的架构上一般是设计一个专门的芯片去处理,CPU只管任务分配和获取结果不管计算过程。最典型的就如手机上加个AI芯片之类的。
2.2 CPU是怎么计算的?能说的通俗一点吗?
说电路又想起我《数字电路》只有可怜的七十来分,和高数大概并列最惨的两门课,也只能说得通俗一点技术一点是不太行的。
从微观到宏观角度:
数字电路中最基础的是与、或、非三种门电路。
使用这三种门电路进行一定的并串联组合可以得到有一定意义的组合电路,如8-3编码器、3-8译码器等。对于CPU需要的是这些门组合成一种微指令译码器,就是接收到某条微指令就会打开某些门关门某些门得到某些输出。所有微指令的集合叫微指令集。
多条微指令构成一个微程序,亦即一条机器指令;或者说,机器指令是微指令集的排列组合。
多条机器指令构成一行高级语言代码;或者说,代码是机器指令的排列组合。如果是精简指令集(RISC,reduced instruction set computing)那么机器指令数量一般是百来条,如果是复杂指令集(CISC,complex instruction set computer)那么机器指令数量一般两百条以上。
多行代码构成了最终的程序;或者说,程序是代码的排列组合。
从宏观到微观角度:
程序由代码构成,代码由指令构成,指令由微指令构成,而微指令执行者是与或非门构成的译码器;简而言之,不管你程序如保千变万化最终就是一套固定的微指令集的排列组合,即对CPU而言就只是那几个固定的电路开开关关操作;(一如千变万化的字其实也就是横竖撇捺折的排列组合,千变万化的音乐也就哆来咪发唆拉西的排列组合。)
2.3 驱动是什么?
坐旁边的就是驱动开发部,上周突然想到我还是回答不上来长久以来没搞清楚的一个问题:驱动是什么?
这问题最早起源应该是每次给电脑插上U盘等硬件时一开始都提示“正在安装驱动”,加重于重装系统时上不了网窒友说需要先离线安装网卡驱动。
关于驱动最常见的说法是,操作系统需要通过驱动来操作硬件。应该说这种说法是没什么问题的,但从编程角度说还是不是很令人满意,因为还是不能让人明白驱动是哪部分的代码。
一个驱动就是一组内核态的API。具体到Linux上就是一个ko文件,安装驱动就是把驱动ko通过insmod安装到内核里;windows也差不多,安装驱动就是把驱动api安装到内核里。
操作系统已经为通用硬件设备(如USB)准备了驱动,需要时直接安装上去就可以了。如果非通用设备那就需要设备厂商提供驱动,设备厂商提供的驱动api操作系统认不认识是不重要的,因为最终操作这些非通用设备的不是操作系统而是设备厂商提供的应用软件,只要这些应用软件知道怎么传参和处理返回结果就可以了。
我们可以看到硬件厂商中通常会有“应用开发部”和“驱动开发部”,应用开发部就是开发操作硬件的应用软件,而驱动开发部的就是响应应用开发部的需求整合提供相应的内核态接口。
总而言之,对最终用户而言,驱动就是一套内核态api;对企业内部内言,驱动更侧重于该套api的分析、实现、维护的整个过程。
参考:https://docs.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/what-is-a-driver-
2.4 硬件接口必定要么是串口要么是并口吗?
串口(Serial Port),串行接口,又称COM(Communication)口。一个独立信道数据收发各一根线,数据一位一位(bit)地传(或者叫一时钟一数据)。
并口(Parallel Port),并行接口,又称LPT(Line Printer Terminal)口。一个独立信道数据收发各有多根线,数据一次传送多位(或者叫一时钟多数据),通常是8位。
数据传输要么是串行的要么是并行的(应该没有人设计成一下串行一下并行这么吃力不讨好的事),从这个概念出发所有硬件接口确实要么是串口要么是并口。
理论上,一时钟多数据的并口速度快于一时钟一数据的串口,但在电路上线路间距很小并行数据之间容易相互干扰,无法辩别时还要重传所以并口在处理不好的状态下并不比串口快。当下只有打印机、扫描仪等少数接口使用并口。
也就是说除了打印机、扫描仪的接口外都可以叫串口,但一般地,串口只指RS232和RS485(两者的驱别只是后者使用的电压范围较宽可传输的距离更远)等URAT(Universal Asynchronous Receiver/Transmitter)口。因为USB、HDMI、网口等接口是“一个独立信道数据收发各一根线”,但他们同时有多个独立信道,并非传统上严格的串口。或者叫原理上是串行的但效果上是并行的。
我们也很难从外观上判断一个接口是并口还是串口,因为多根线完全可以做得像一根一样,而且串口也不一定只有收、发、电源这几根线。
参考:https://www.zhihu.com/question/27815296
2.5 电脑上的bios和硬盘对应到手机上是什么?
在电脑上概念还是很明确的:
CPU能直接寻址访问的存储器叫内部存储器,简称内存;不能直接寻址访问的存储器叫外部存储器,简称外存。
内存包括高速缓存Cache、RAM(主要就是内存条)和ROM(主要就是安装BIOS的CMOS);外存包括硬盘、移动硬盘、U盘、SD卡等。
硬盘属于外存而不是内存,所以很显然硬盘既不是RAM也不是ROM。
但到智能手机普及后概念就有点混乱了:
内存直接被用来指存文件的FLASH,在手机内存只有512M的年代就被叫做内存有8G、16G;后来修正了一些,弄了运行内存和机身内存两个名词。
这种外行糊弄倒还能理解,真让认知陷入危机的原因是回答不上以下几个问题:ROM真的是只能读不能写的吗?如果FLASH是外存相当于电脑的硬盘,那么相当于电脑BIOS的BootLoader装到哪里去了?如果BootLoader在FLASH上,那FLASH是不是确实可以叫内存?
ROM(Read-Only Memory),最开始是如其名只能读不能写的,但发展到EPROM开始就已经可读写了。所以现在的ROM其实也是可读写的,只是因为其承载原先ROM的功能所以还叫ROM(所谓功能主要是存放BIOS)。现在纯正的ROM基本都被淘汰了,所谓的ROM基本都是存放BIOS的FLASH。
FLASH又分Nor Flash和NAND Flash两种,Nor Flash和RAM一样可按字节读取、速度较快、成本较高;NAND Flash和硬盘一样按块读取(通常是512字节)、速度较慢、成本较低。现在通常的做法是“小块Nor Flash+NAND Flash”的组合。BootLoader安装在NAND Flash上,手机启动时自动将NAND Flash中的前4K BootLoader加载到Nor Flash上完成必要硬件和寄存器的初始化及将BootLoader剩余部分复制到RAM的操作。也就是说嵌入式设备中,相当于BIOS的BootLoader确实是存放在FLASH上,至于说为什么刷机没有破坏BootLoader那是因为BootLoader在专门的一块地址空间,升级系统时无权限写该地址。
系统固件被称为ROM是因为Flash被称为ROM,而Flash被称为ROM是因为其上装载着相当于BIOS的BootLoader,这是一种从功能传呈角度出发得出的结果。但从严格的定义出发是内存还是外存取决于CPU能否寻址,从以上分析可以看到,在当前嵌入式设备中设计总体而言CPU是不能直接对Flash进行寻址的,所以Flash不能算内存。
另外,桌面Linux中最常见的bootloader是grub,嵌入式中最常见的bootloader是uboot;高通处理器bootloader一般是高通自己开发的lk(little kernel),当然很多手机厂商也会改写或编写bootloader。
参考:
https://www.cnblogs.com/wrjvszq/p/4204703.html
https://blog.csdn.net/liangkaiyang/article/details/5955653
https://www.zhihu.com/question/24645885
2.6 固态硬盘为什么比机械硬盘快?
机械硬盘慢的主要原因是需要费很多时间将读写磁头从当前位置移动到目标位置上(具体计算公式记不清了)。
我们前面说硬态硬盘是一种FLASH----更具体一些是NAND Flash----FLASH对所有空间是编好地址然后使用电子方式读写的,可以认为寻址是瞬间完成的。
FLASH以固态硬盘形式展现时,模拟的是机械硬盘,操作系统让它去寻址时它就直接回已就绪。寻址这个大头被去掉了读写速度自然就快了。
关于SLC、MLC、TLC和QLC:
SLC----Single-Level Cell,单阶存储单元。一个存储单元存储一比特(1 bit)信息。
MLC----Multi-Level Cell,多阶存储单元,现一般用来指双阶存储单元。一个存储单元存储两比特(2 bit)信息。
TLC----Triple-Level Cell,三阶存储单元,也叫3-bit MLC。一个存储单元存储三比特(3 bit)信息。
QLC----Quad-Level Cell,四阶存储单元。一个存储单元存储四比特(4 bit)信息。
通常我们说低电平(压)表示0高电平(压)表示1----这也是SLC的实现----那1个存储单元怎么实现存储多比特信息呢?答案是通过细分更多的电平区间,如下图所示。
对一块固态硬盘的一次完整读写,对于SLC物理上也是一次读写,而对于MLC是两次对于TLC是三次对于QLC是四次,这也正是总说越多LC越容易坏的原因所在。
参考:https://zh.wikipedia.org/wiki/%E9%97%AA%E5%AD%98#SLC
2.7 两张网卡两个网口,只有一个网口接线,为什么从别的主机也能ping通未接线网口对应的IP?
首先,当两个网口共用一个协议栈时,操作系统并不区分当前询口的是存活网口的IP还是未存活网口的IP,只要是该协议栈的IP的数据包操作系统都会响应。
其次,在通常情况下操作系统会选择一个网口作为默认路由网口,当该网口down掉时,又会自动选择一个存活的网口作为其默认路由网口。所以(在没有自己配置相应静态路由前提下)响应数据包总会根据自身的路由表能从存活的网口出去。
由此,在网口共用协议栈情况下,其他主机上总能访问到未接网线的网口的IP。
2.8 QoS是什么?
QoS,Quality of Service,服务质量。
当到来的数据超出了交换机或路由器的处理能力时,交换机和路由器将会丢弃部分数据包只转发部分数据包(此所谓尽最大能力交付)。给交换机和路由器指出数据包重要程度以供其参考要转发哪些数据包丢弃哪些数据包的功能就是QoS。
更具体点说说就是Eth头和IP头上各有一个表示该数据包重要程度(或者叫优先级)的字段,数值越大表示越重要,在交换机和路由器的转发优先级就应越高丢弃优先级就应越低。
交换机还好说,只拆Eth头所以优先级就按Eth头的QoS字段排就好了。但到路由器,是即拆Eth头也拆IP头的,如果Eth头和IP头上QoS字段的值不一致(应该说大概率是不一样的因为两者的长度不一样)甚至相左时,优先级应当以哪个为准呢?这个不一定,看路由器代码开发者决定。