衔接软硬的HAL
0赞近日特权同学对系统架构思考得很多,虽然工作中还多是在做模块化的半成品,但是越来越感觉到构建一个软硬件协同开发平台的必要性。无论从个人偏好还是开发灵活性上来说,Altera的NIOS2都是一个很好的选择。
晚上专门看了几篇阐述HAL概念的application note,我想我是受益匪浅,对一些过去不曾深入思索过的东西有了一个更清晰的看见,也很是惊叹软硬件设计衔接上的微妙关系。不禁要发出 “人类太有才了” 的赞叹,当然了,归根结底,是要感谢那位说“我们要按着我们的形象和样式造人”的宇宙主宰者了。
首先,很推荐各位有心的看官去瞅瞅下面几篇不错的文章,也许写得比我精彩,说得比我有深度。
《NIOS整体开发结构基础》、《Nios ii设备管理分析》。
如果单从逻辑角度来看,一个NIOS2系统可以归结为如图1所示的简单示意。在最底层,也就是Nios II Processor System Hardware,基本上是一些最基本的逻辑门电路,它用于实现整个系统的外设协议,也可以理解为这个层之间和FPGA外部的各种芯片或接口打交道,比如 简单的你可以在这个层实现一个GPIO控制流水灯或是做一些脉冲采集和中断沿触发的功能;复杂一点可以在这个层实现一个SD卡控制器、USB控制器、 CAN总线控制器等等;再复杂一些恐怕你也可以去做一些压缩算法或是图像识别算法;总之,用户尽可以在这个层发挥FPGA的灵活性、实时性。而向上的 Device Driver层,实际上在前面提Nios II Processor System Hardware层时应该提到它,他们是协同工作来完成各种各样的控制器设计的。Nios II Processor System Hardware层趋向于直接和硬件接口的实现,而Device Driver往往是利用一串串又长又臭的状态机来实现更复杂一些的控制,同时也在这里实现一些上层可访问的总线从接口,以及一些用于控制他们本身的寄存器 访问接口。
再往上,暂且不说HAL API这个层,我们先讨论User Program这个层,也就是用户程序执行的层,它就是系统的软件开发部分。用户在这个层通常不需要傻乎乎的写程序用GPIO再去模拟SPI协议、IIC 协议或是FLASH的读写时序(在单片机上我们经常干这种傻事的)。在NIOS2中,看到最多的可能也就是调用诸如printf();IOWR (BASE,0x0); IORD (BASE,0x0);之类的函数而已。实际上很多的外设接口就是通过这些简单函数的调用,从而读写一些相关的寄存器,这些寄存器都是在Device Driver中设计好的。
图1
最后来说HAL API,在NIOS2系统中,它其实从某种意义上可以理解为就是Alalone总线,总线在一个处理器系统中的重要性毋庸置疑,Device Driver层需要实现和这个系统总线相连的从接口。而处理器在软件编程时只要一个简单的IOWR或IORD函数就能够发起一次总线主接口的时序,这个时 序通过不同的片选或是地址来区别访问不同的外设。从软件实现上看,只要用户添加好一些定义着相应地址的.h头文件,正确的访问这些外设的地址即可。
图2
有了这个HAL,实际上能够给整个系统开发带来很多的便利,如用户可以直接利用newlib ANSI C标准库函数来开发软件;可以在硬件底层就做好了整个系统外设的初始化(软件开发者根本不需要关心这些底层硬件的任何细节);另一个很大的好处是让硬件驱 动开发者和软件设计者各司其责,更加专注于自己分内的工作,只一个总线就完成了相互之间的衔接。
如图3所示,从一个简单的SPI外设的系统集成可以看出,软硬件的衔接不过就是avalone总线的主从机的结合而已。
图3