您的位置 首页 ADAS

奔跑吧,SOC(一)软件是怎样操控硬件的

很多人肯定很疑惑,在嵌入式开发中,为什么写c代码,就能够控制硬件。这一切是怎么发生的了,下面我就给大家解剖一下,软件是怎么控制硬件的。我们从控制8个led为例来说明:从最简单的开始

  许多人必定很疑问,在嵌入式开发中,为什么写c代码,就能够操控硬件。这一切是怎样发生的了,下面我就给咱们解剖一下,软件是怎样操控硬件的。

  咱们从操控8个led为例来阐明:

  从最简略的开端,假如运用硬件,操控8个led,最简略的办法是什么:直接接上开关。便是以下的图。经过开关操控led管脚输出不同的电平,就能操控led了。可是这个办法很不灵敏,咱们要手动的去拨动开关,才干改动led状况。

  

clip_image001

 

  咱们将上面电路改一下,把开关的当地换成寄存器,并加一些额定的电路,这样就能够经过使能信号和信号值改动led值输出不同电平,直接的操控led了。而使能信号和信号值咱们是能够经过外部给的,就比开关要灵敏一些了。

  

clip_image003

 

  已然,上面有寄存器,咱们能够给这个寄存器界说一个地址,当然这个地址现在是能够随意界说的。假定为0x77777777。你可能会有疑问,为什么要给寄存器界说地址了?并且界说的地址为什么是32位了,这个先不着急,听我渐渐道来。

  咱们持续在前面加电路

  

clip_image005

 

  这儿,多了一个前级电路,前级电路供给两个信号,一个地址,一个数据。在地址信号通路上,有一个电路模块,判别地址是不是0x77777777,是的话,使能信号为1,这样数据不就直接传递给寄存器了。不是的话,使能信号为0。寄存器的输出不变。这样,经过地址和数据就能改动led了。

  这儿0x77777777是不是很熟悉,这不便是之前界说的寄存器A的地址吗?本来,地址便是用来判别是否发生使能信号的,使能才干使数据能够输入到寄存器中。

  到了这儿,是不是对软件操控硬件有些端倪了。别着急,咱们持续往下走。

  已然前级电路只需求供给地址和数据,并且地址是0x77777777,就能够操控寄存器A的值了,而操控了寄存器A,就操控led。那么咱们将前级电路换成一个32位CPU。

  咱们知道,CPU是能够发生3种总线信号的,一种地址总线,一种数据总线,一种操控总线。操控总线咱们这儿用不到。将地址总线接到地址线上,将数据总线接到数据线上。便是以下的电路:

  

clip_image007

 

  假如咱们让CPU发生地址为0x77777777,然后宣布想要写入寄存器A的数据B,那么数据B不就被写入到寄存器A中,这样,不就操控led了。这儿知道为什么地址要32位的把,由于CPU是32位的,地址便是32位宽的。之所以界说32位的地址,意图是为了和CPU的地址总线32位宽兼容。

  到这儿,是不是有恍然大悟的感觉了。咱们再持续。

  咱们知道CPU是要取机器码然后履行的。假如刚好某条机器码,能让地址总线上发生0x77777777,数据总线上发生数据B。那么成果,数据B不就被写入到寄存器A中了。假定CPU是32位risc的CPU,机器码便是32位。那么该机器码应该是如下:

  1001 0000 1110 0000 1011 1010 1111 0010(假定)

  已然这是一条机器码,那么就应该有一个汇编指令与之对应,假定是

  str r0, r1

  咱们预先将地址0x77777777写入到r0中,数据B写入到r1中,那么上面一条句子履行后,不就将数据B写入到寄存器A中了,不就操控led了。这样不就完成了软件操控了硬件了。已然汇编代码能够操控硬件了,那么高档言语相同也是操控硬件的,只需编译后的汇编代码是以上代码就行了。

  全体操控硬件的代码便是

  ldr r0, = 0x77777777

  ldr r1, =B

  str [r0], r1

  对应的C代码便是

  (*(volatile unsigned long *)0x77777777) = B;

  运用指针操作,往0x77777777地址的寄存器写入数据B,参加volatile关键字,是避免编译器对操作进行优化。

  经过上面的进程,是不是也能够了解,为什么在嵌入式底层驱动开发中,根本都是用C言语,而不必其他高档言语,比方JAVA等。由于这些高档言语没有指针,你就不能操控寄存器,不能操控寄存器了,你当然就操控不了硬件了。C++也很少用,由于底层驱动开发需求高效率代码,不能太杂乱,而C++在这方面,比不过C言语。

  以上是写入的进程了,假如想要知道led的状况呢?经过读取寄存器A的值,不就知道led的状况了。原理是相同的。只不过数据线要变成两根,一个是担任写,一根担任读。电路图如下:

  

clip_image009

 

  由于只考虑了一个寄存器,当不选中寄存器A时,读取的数据为全0。

  经过,上面的叙述,对软件操控硬件有没有了解一些了。软件操控硬件,本质上,便是经过写代码去修正或读取硬件对应的寄存器的值。这样,就相当于直接的操控了硬件。而硬件的寄存器关于一个处理器来说,都是固定的,都预先界说好了地址。所以在看ARM的数据手册中,能够看到许多寄存器的地址。这些地址的效果,也便是能够让你在写程序的时分,能够正确的往这些寄存器里边写入或读取正确的值,然后操控硬件。

  CPU对外看到的都是寄存器,所以硬件规划的时分,就要对硬件的功用设置几个寄存器,然后对这几个寄存器别离界说几个地址,这样CPU才能够去操控这几个寄存器,也就能操控硬件了。界说的寄存器地址位宽是和CPU的地址线位宽是有联系的,假如是一个8位的CPU,也便是经典的C51,地址的宽度便是8位,所以你能够在头文件reg51.c中看到运用sfr界说的地址位宽是8位。在STM32中,CPU是32位的,所以地址的宽度便是32位的,所以你看到STM32数据手册中,寄存器的地址都是32位的,并且是4字节对齐的。

  以上,CPU仅仅操控了一个硬件,led,可是咱们知道,CPU是能够操控许多硬件的,那这又是怎样完成的了?这个就得谈谈片上互联总线了。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/adas/115977.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部