本文和设计代码由FPGA爱好者小梅哥编写,未经作者许可,本文仅允许网络论坛复制转载,且转载时请标明原作者。
1、什么是NIOS 开发环境中IP自带驱动
在开发基于NIOS II的应用程序时,常用到包括SPI、定时器、UART串口等IP核,只要在Qsys中添加好这些IP,然后在NIOS II的开发环境(定制版Eclipse)中编写驱动程序和应用程序即可完成该控制器的使用。当然,为了让这些IP用起来更加的方便,Intel(Altera)也是为大多数的IP提供了相应的驱动程序,例如最典型的使用串口时,我们可以直接使用printf来通过串口发送数据,通过scanf来从串口接收数据,这就是使用了Intel开发好的驱动程序和HAL库。同样的,对于Qsys中提供的定时器运行在不同的模式,也有相应的驱动程序。比如看门狗模式、系统心跳时钟模式等。
2、为啥要关闭?
出于某些原因,我们需要自己直接通过读写IP的寄存器来控制其实现相应功能,比如嫌弃软件自带驱动太过臃肿,增加了程序尺寸,比如想学习下如何通过读写IP寄存器实现其控制,比如软件自带驱动无法很好的满足自己的需求等。总之,我们就是有理由在需要的时候想将其关闭。
3、不关闭会怎么样?
由于这些软件自带的驱动在NIOS II初始化的时候就会开始执行,如果我们在用户程序中通过读写直接寄存器的方式操作这些IP,那么就会出现实际上有两个程序同时操作某个寄存器的情况,当一个程序操作了这个寄存器,另一个程序可能就无法操作该寄存器,或者操作该寄存器时无法得到正确的执行。举个简单的例子:
对于串口驱动,系统自带的驱动是使用了中断的方式来完成数据的收发,而我们自己写程序的时候有时候只想简单的通过查询寄存器状态的方式来读写数据。那么假设当串口接收到一个字节的数据后:
a、首先,由于系统驱动是使用的中断的方式响应,理论上当串口接收到数据后,系统驱动的中断首先响应该事件,并进入中断服务函数读取状态寄存器,根据状态寄存器来获知是接收到了新数据,再去读取接收到寄存器,把收到的数据读出并存起来。
b、可是,不要忘了,我们用户层也有一个接收的函数,该函数可能就是拼命的读取串口的状态寄存器,再根据状态寄存器的结果来决定是否收到了数据,如果收到了数据,就把数据寄存器中的数据读取出来并存起来。
c、了解串口IP核的用户应该要知道,串口的状态寄存器中的位是自动置位,在读取过后自动清零的,也就是说,假设串口收到了一个数据,就会将状态寄存器中的对应位设置为1,然后,当用户自己的程序或者系统自带的驱动只要有一个程序去读取了该状态寄存器的值,那么该寄存器中的一些位就被自动清零了。
好了,相信不用我再多说,大家也都知道问题出在哪里了,假设系统自带的驱动通过中断的方式抢先响应了接收到一个字节的数据这个事情,并读取了状态寄存器,那么我们自己用户编写的驱动再后面去读取状态寄存器时,就读不到有效的值,这样以来,这个接收到的数据就丢了,哎,丢了。
4、如何关闭?
关闭方法非常简单,鼠标左键选中bsp工程,注意,是bsp工程,不是app工程,什么是bsp工程,什么是app工程,简单点说,假设你按照我们的教程创建了一个名为hello的nios工程,那么软件会自动帮你创建一个名为hello_bsp的工程,那么这个hello就是app工程(应用工程),hello_bsp就是bsp工程(班级支持包工程)。
关闭方法非常简单,鼠标左键选中bsp工程,然后在键盘上按下 Ctrl+ 9 组合键,就能进入到bsp设置界面,在该界面中切换到drivers选项中,然后在你希望关闭驱动的IP后面,将默认打开的勾选项取消即可。
退出之后需要选中bsp工程,右键执行一次NIOS II ->Generate BSP操作,然后再编译工程(ctrl + B)。
|