芯片的引脚跟寄存器是相对应的 写入的是01100001,则芯片上与之对应的8个引脚的电压状态(分为高电平与低电平两种)会输出:低高高低低低低高 驱动无非就是硬件跟软件的中间层

 

C 语言如何调用硬件? - 知乎 https://www.zhihu.com/question/39846396?sort=created

C 语言如何调用硬件? - awayisblue的回答 - 知乎
https://www.zhihu.com/question/39846396/answer/84753336

【单片机芯片STM8】

 

 

这款芯片里面有cpu, 内存,寄存器(先不要觉得看到新名词压力大,继续往下看)等等,相当于我们的电脑了,但还要外接其它硬件。

这里你需要知道的概念是:

  • 芯片的引脚跟寄存器是相对应的,寄存器是8位的内存单元(对,存在于内存上面),当你往这个内存单元里面写入数据时,芯片的引脚的电压会发生变化,比如说我写入的是01100001,则芯片上与之对应的8个引脚的电压状态(分为高电平与低电平两种)会输出:低高高低低低低高。
  • cpu可以执行代码指令,指令可以操作内存。

 

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

 

 液晶显示器LCD1602

 

 

关于这款显示器,我们需要知道的是:

  • 它是有引脚的,这些引脚可以跟到前面介绍的那款单片机芯片的引脚相连
  • 该显示器有自带的内存,用于存储要显示的字符,显示器从该内存里面读取字符来来显示。
  • 单片机芯片与该显示器相连后,可以通过引脚往该显示器的内存里写数据(通过多个引脚电平的高低不同来代表不同的数据,比如说:低高高低低低低高 代表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 = RGBA(0xff,0xff,0xff,0xff);

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

3 那这个地址怎么拿到呢?什么样的数据才是合法的呢?要解答这些问题,就需要查阅具体设备的spec了。例如这个一眼看过去就能的明白的例子(一眼没看明白请反复阅读以完全理解上面第二点内容):

代码:

Tonc: My first GBA demo

规范:

Tonc: Graphics introduction

https://www.zhihu.com/question/39846396/answer/84722884

PS:x86架构的代码不能这么写,原因见北极的回答。

 
 

Tonc: Graphics introduction http://www.coranac.com/tonc/text/video.htm

4.1. General introduction

The GBA has an LCD screen that is 240 pixels wide, 160 pixels high and is capable of displaying 32768 (15 bit) colors. The refresh rate is just shy of 60 frames per second (59.73 Hz). The GBA has 5 independent layers that can contain graphics: 4 backgrounds and one sprite layer and is capable of some special effects that include blending two layers and mosaic and, of course, rotation and scaling.

Whereas sound and joypad functionality have to make do with only a few measly registers, the video system has a great deal of memory at its disposal (relatively speaking). Apart from a multitude of registers in I/O memory, there's the 96kb of video memory (starting at 0600:0000h), palette memory (0500:0000h) and OAM memory (0700:0000h).

 

####

与硬件打交道就是读写寄存器。寄存器都有自己的地址,那么读写寄存器就可以简单的表示为

MOV ADDR1,ADDR2 

那么对于C语言来说,就是简单的赋值

*ADDR = 0x0001

 

####

作者:知乎用户
链接:https://www.zhihu.com/question/39846396/answer/2351685847
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

硬件的本质是超大规模集成电路,控制电路的必然可变电流开关.

CPU封装了百亿级的晶体管可变电流开关)可以控制硬件(解码器、多路选择器).

C语言本质是二进制的ASCII码,通过键盘输入以.C拓展名文本文件存放在硬盘上,这是运行不了的.

所以需要CPU运算把混乱的文本格式转换成秩序的二进制可执行格式(COFF、PE、ELF、Mach-O)

其中汇编阶段就是生成各架构平台(X86,ARM)机器语言. 汇编语言就是机器指令人类可阅读形式

经过编译最终可执行文件以二进制的电信号的形式储存在硬盘上.

当然可执行文件放在硬盘上你不双击也是运行不了的

运行后可执行文件会加载到内存上给CPU执行,接下来是CPU工作了,CPU流水线般的取指,译码执行访存回写, 最后CPU往显存里写数据,GPUFramebuffer中内容显示到显示器.

OVER,自此一个执行周期结束,中间省略了亿点点细节

 

最后答案:

冯诺依曼计算机的基本思想:数据和指令都是以二进制形式存储在存储器中的,换句话说软件的本质是存储器中的电荷状态集合,编程的本质是指令和数据的排列组合.

CPU上电自检后运行的第一软件是BIOS,然后bootloder加载内核,也就是固件才是操作系统和硬件沟通的桥梁 ,BIOS现在发展成为UEFI,具体实现是EDKII

 

硬件/固件 (ASM)——> UEFI——> Bootloaders

——>OS Kernel ——> C lib ——>API

总结:通过Compiler封装CPU指令集接口供程序猿使用

 

####

对硬件的操作就是控制他的管脚的高低电平,而处理器操作硬件的方式就是把这些管脚和处理器管脚连接在一起。

有些是连接在地址管脚和数据管脚上面实现读写某些地址实现操作硬件,RAM 是典型的使用案例(读写地址会让地址线和数据线产生高低电平的变化)。

也有些是连接在通用的管脚上面,然后通过操作处理器的寄存器来控制这些管脚的高低电平。

简单的说,处理器是通过访问某些地址,然后导致地址线的高低电平产生变化,这些变化也会改变它所连接到的硬件的管脚的高低电平,这样硬件就被他控制了。

C 语言最后也会被编译成机器码,而处理器通过机器码得知他要访问哪些地址,最后达到操作硬件的效果。

 

 

 

 

posted @ 2017-03-24 02:07  papering  阅读(176)  评论(0编辑  收藏  举报