好好学习,天天向上,自学网欢迎您!
当前位置:首页 >  考试 >  计算机类 > 内容页

C语言是如何调用硬件的

2021-08-30 08:05:01计算机类访问手机版519

  C语言是如何调用硬件

  大师都知道我们可使用C语言写一段顺序来把持硬件工作,但你知道其工作道理吗?c语言在实际运行中,都是以汇编指令的体式格局运行的,由编译器把C语言编译成汇编指令,CPU间接执行汇编指令。下面是小编为大师带来的关于C语言是如何调用硬件的的常识,欢送阅读。

  体式格局一:

  经由过程向内存空间写数据。硬件会把硬件上的各类存放器外行可以懂得为拜访硬件的接口大概操纵硬件的东西映射到某一块内存地点空间上,之后只要用汇编指令,甚至C语言去读写这一段内存地点空间并不是真正操纵物理内存,就能够到达操纵硬件的目的了。

  假如题主还有WindowsXP环境假造机也能够,就能够用汇编指令间接操纵显存:

  MOV AX,B800

  MOV ES,AX

  XOR DI,DI

  MOV CX,0800

  MOV AX,5555

  REPZ STOSB

  硬件的各类存放器会被映射到某一块物理内存中,这种体式格局称为MMIO,在Windows的设置装备摆设办理器里,右键点设置装备摆设,看属性-》资源里,很多硬件设置装备摆设都有“内存范畴”的参数,这里的内存范畴就透露表现这个硬件的资源可以经由过程拜访这一段内存来把持它。

  体式格局二:

  x86汇编中,还有两个非凡的指令是IN和OUT,这是x86平台湾的独立有的,上面图里的I/O范畴,就是用IN/OUT这两个指令来拜访和把持的。

  以上两种拜访硬件的体式格局,第一种是可以用C语言实现的,上面一段汇编,实质上类似于C语言代码:

  char ptr = 0xB8000;

  int i;

  for i = 0; i 《0x800; i++

  ptr + i = 0x55;

  第二种IN/OUT体式格局没有间接的C语言语法对应,必要本人封装汇编。

  那么为何日常平凡很难用C语言操纵硬件呢?这是因为日常平凡写的代码大少数都在维护模式下,维护模式下,间接拜访物理地点会受到限制,C语言操纵的地点都是虚地点。

  关于Windows来说,要拜访物理地点,必要工作在内核模式,也就是的写驱动才行。

  而在显存方面,首先,题次要先理解理睬物理地点和假造地点的观点。

  本来的8086cpu计划的时候,地点空间有一块地区640K-1M之间,有一块作为显存使用

  这里你说的预留的地点,是指物理地点,这一段地点的准确范畴是000A0000-000BFFFF,不论是32位还是64位CPU,这一段物理内存地点不断都保存给显存使用,不辨别32位还是64位,也不辨别维护模式还是实模式。

  可见这一段内存至今仍然是留给显卡使用的。

  那么目下当今为何不克不及间接用这段内存了?

  因为目下当今的软件都运行在维护模式下,拜访的地点都是假造地点,而并不是物理地点,包含你使用cmd饬令翻开的环境,都是假造地点,固然32位XP里能用debug饬令向000B8000上写数据并能表现在cmd的界面里,但实质上,这都是假造出来的。

  假如要想用这段显存怎么办?

  本人写一个简略单纯的操纵系统,不启动显卡的各类图形加快功效,CPU进入维护模式后在GDT里映射一个4G的数据段,与物理地点分歧,那么向000B8000上写数据,就会像过来DOS一样表现在屏幕上,所以维护模式下也能够拜访这一段内存。所以,维护模式下,也能够用它。

  显卡那么多显存是怎么映射的?

  有很多内存地点被映射给显存了,就是经由过程这种映射干系,把一些物理地点留给显存,使得CPU能像拜访内存一样拜访显存资源。

  固然,实际环境是,2G显存未必完全映射,而是只映射一局部地点,显卡有一些开放的存放器可以或许把持哪局部显存映射过去,这样就可以使得CPU在使用比拟少的物理地点范畴的环境下,拜访全部的显存。

  还有一个很成心思的工作:在假造机里,找到映射的高地点局部的第一块内存地区,写一个能间接拜访物理地点的顺序比方一个驱动,去读这一块内存,然后写到文件里,再用屏幕截图,也写到文件里,会发明截图的内容和显存里读出来的内容根本上是一样的。

  网友awayisblue

  要答复你的成绩,我们必要要知道:

  硬件是一种什么样的存在

  什么是驱动。

  C语言怎么操纵硬件

  我就不严格去界说这些观点了,我就以一个例子来通俗地讲授一下吧。

  首先讲硬件:

  先介绍一款单片机芯片STM8。

  这款芯片里面有cpu, 内存,存放器先不要感到看到新名词压力大,持续往下看等等,相当于我们的电脑了,但还要外接别的硬件。

  这里你必要知道的观点是:

  芯片的引脚根存放器是相对于应的,存放器是8位的内存单位对,存在于内存上面,当你往这个内存单位里面写入数据时,芯片的引脚的电压会发作变革,比方说我写入的是01100001,则芯片上与之对应的8个引脚的电压状态分为高电平与低电平两种会输出:低高凹凸低低低高。

  cpu可以执行代码指令,指令可以操纵内存。

  结论:所以从上面两点可以我们可以知道,cpu可以执行指令,使芯片的引脚电平电压发作变革。

  关于这款表现器,我们必要知道的是:

  它是有引脚的,这些引脚可以跟到后面介绍的那款单片机芯片的引脚相连。

  该表现器有自带的内存,用于存储要表现的字符,表现器从该内存里面读取字符来来表现。

  单片机芯片与该表现器相连后,可以经由过程引脚往该表现器的内存里写数据经由过程多个引脚电平的凹凸差别来代表差别的数据,比方说:低高凹凸低低低高 代表01100001,这个数据写在表现器的内存里面,被表现器所表现,固然,会按照ASCII来表现数字对应的字符,01100001对应的字符是‘a’,除了接纳数据的引脚外,还有把持表现器的引脚这个我们会在驱动那里介绍,持续往下看。

  结论:单片机芯片与表现器相连,可以经由过程引脚输出的电平来把持表现器的字符表现。

  那么,综合上面,也就是说,单片机芯片cpu可以经由过程执行指令来把持表现器的字符表现。

  而这里,题主所说的硬件,指的就是这个表现器了。

  接下来讲驱动:

  那么,什么是驱动呢?驱动不过就是硬件跟软件的中间层,但我们不纠结这种干系,间接来看一下,关于我们这个例子,驱动指的是什么。首先我们要知道:

  表现器撑持很多种操纵,比方说断根表现,光标移动,读取数据,写数据等等。

  这些操纵数据引脚和把持引脚来实现。

  引脚可以经由过程单片机芯片来把持。

  结论:我们可以经由过程在单片机芯片里面写表现器的“驱动”顺序来屏蔽掉硬件表现器硬件层。

  于是这里驱动顺序,指的是表现器所撑持操纵的'顺序透露表现。比方说断根表现,我们可以编写一个clear函数,光标移动,我们编写一个move_cursor函数,读取数据和写数据辨别为read和write,然后辨别实现就能够了经由过程向存放器里写数据的方式,进而把持引脚的电平变革,再而把持表现器,这个过程后面已有介绍。这些函数就是驱动顺序了。为何上面说驱动顺序可以屏蔽掉硬件呢?因为顺序员可使用后面的驱动顺序来间接操纵表现器硬件,而不必知道太多关于硬件的工作,而一样平常的驱动顺序也能够由厂家来供给。

  再阐明一点:一样平常这些驱动顺序可以用汇编写出于运行服从的考虑,也能够用C语言来编写的,比方说我上面的例子,就能够间接用C语言来编写。固然C语言内联汇编的方式也能够。

  最后讲C语言怎么操纵硬件:

  相信到这里,C语言是怎么操纵硬件的曾经比拟理解理睬了。

  这里总结一下:

  C语言由CPU运行其实是先编译成呆板码存在芯片里面然后执行,可以去操纵内存。

  内存里有一段是跟存放器相对于应的,而存放器是跟芯片的引脚相对于应的,于是操纵该段内存就可以把持芯片引脚的电压变革。

  硬件比方说表现器有引脚大概说排线,这些也是一样的工具,这些引脚根芯片的引脚相连可以承受芯片的把持。

  可以把对某个硬件的操纵做成一系列操纵函数,这些操纵函数就是驱动顺序了。

  于是我们的C语言只要去调用这个驱动顺序就能够间接操纵硬件了。固然驱动顺序也能够由C语言来编写,所以C语言操纵硬件其实不必定要颠末驱动顺序。

  1 语言层面上,C能间接操纵的“硬件”只有内存地点。固然C撑持register关头字,但是不克不及指定某个特定的存放器,所以只有内存地点。而C中操纵内存地点的体式格局就是指针。比方:

  char p = 。..;p = 。..;

  2 按照1反推,可以理解理睬假如要开放给C来操纵某个硬件,最间接的计划就是计划硬件的时候预先分派好一些固定的地点的用途,然后实际项目中往这些固定地点写入合法的数据。这样就能够经由过程类似

  uint32_t p = SCREEN_ADDR;p = RGBA0xff,0xff,0xff,0xff;

  这样的代码来实现对硬件的操纵了。

  3 那这个地点怎么拿到呢?什么样的数据才是合法的呢?要解答这些成绩,就必要查阅具体设置装备摆设的spec了。比方这个一眼看过来就可以的理解理睬的例子一眼没看理解理睬请重复阅读以完全懂得上面第二点内容:

  PS:x86架构的代码不克不及这么写,缘故原由见北极的答复。

  我们是用电脑的键盘来输入的指令,每个指令都对应一个ASCII码,而这里的ASCII码就是有序的电压的凹凸或电流的有没有,下面只提电压的凹凸,即我们输入的是电压的凹凸,你所看到代码是这些电压的凹凸把持表现器所表现的图像,其实电脑也不知道它是什么,只知道这样表现。

  结论:代码其实就是存储在存储器内存、硬盘大概闪存等等中有序的电压的凹凸。

  再说编译:

  编译是一个有序的电压的凹凸向另外一种有序的电压凹凸的一种转换过程,下面以52单片机为例,我们编译是从透露表现ASCII码的那种有序电压凹凸转换为52单片机可以或许辨认的另外一种规则好的有序电压凹凸,即透露表现HEX文件的电压凹凸。

  结论:编译出的成果还是电脑中存储的有序电压凹凸。

  到单片机烧录:

  接下俩就是烧录,懂得了上面两点就很简单懂得下面的内容,烧录就是电脑中的有序电压凹凸经由过程数据线传输到单片机中的ROM中。

  接下来ROM就能够释放此中的电压来把持核心的电路。

  总结:从代码的编纂到最后对电路的把持都是电压在起感化,只是为了方面我们而给我们揭示的方式纷歧样罢了,而其实质都是电压,这样也就不存在转换。

  懂得这句话:世界上没有软件,软件只是对硬件的一种反应,就像意识是对世界的一种反应是一样的!

  相信这样就很简单懂得了。

  看到有人附和了我的概念,很高兴,针对标题问题我再补充一点:

  只要你提到0/1,提到软件,这个成绩就没法懂得。..因为软件【包含0/1】和硬件始终存在一道无法超过的鸿沟;

  你说你在单片机中写0,叨教你是如何写0的?在键盘上敲个0?实际还是电平【和我们懂得的数字不妨事】,阿谁0只是你在电脑表现器上电平的出现方式,阿谁所谓的0【本色是电平】可以传输到单片机中的ROM中,电平把持电平没什么疑问吧,这样就输出低电平了。

TAG标签: 调用 语言 硬件