📄 chapter10.txt
字号:
本文是nios2文档的第十章的翻译稿,希望能对各位同仁有所帮助。
转载时请标明出处。
译者:姜黎
南京气象大学2000级
QQ:44425312
UART的寄存器:
UART 通过Avalon总线和一组寄存器文件打交道。UART有6个16位的寄存器。
它们是control,status,rxdata,txdata,divisor,endofpacket。
UART的中断:
当串口收到一个数据或者为发送一个字节准备好时,它就会产生一个高有效
的中断信号。
UART的DMA操作:
UART支持流模式传输,因此它可以用来和存储器进行DMA操作。
UART的接口:
由于大多数FPGA芯片不支持RS-232的数据接口,因此它需要在片外加一个电平
转换芯片来完成电平转换。逻辑'0'代表数据为1,逻辑'1'代表数据为0。
发送逻辑单元:
UART内部的发送逻辑由发送保持寄存器(holding register)和发送移位寄存器(shifting register)
组成。当主设备向发送寄存器(txdata)写数据时,如果移位寄存器发送完上一个数据后,
就会把该数据载入。数据就会从最低位开始通过TXD引脚从位移寄存器一位一位移出。
由于有了保持寄存器和位移寄存器的双缓冲,串口在把数据移出的同时又可以向保持寄存器
写入新的数据。主端口还可以实时监控发送status寄存器,可以读取发送准备好位(trdy),
发送位移寄存器空位(tmt),发送溢出位(toe)。
接收逻辑单元:
UART内部的接收逻辑由接收保持寄存器(holding register)和接收移位寄存器(shifting register)
组成。当移位寄存器接收完一个完整的数据后,主设备就可以读取接收保持寄存器(txdata)的数据。
由于有了保持寄存器和位移寄存器的双缓冲,串口在把数据移到保持寄存器的同时,又可以向接收
位移寄存器移入新的数据了。主端口还可以实时监控接收status寄存器,可以读取接收准备好位(rrdy),
接收溢出位(roe),停止侦测位(brk),奇偶校验位(pe),帧错误位(fe)。
波特率的产生:
波特率可以通过以下两种方式产生:
1。在系统生成时设定固定的值。
2。设置16位的分配寄存器(divisor register)。
当波特率在系统生成时被设成固定值时,系统生成后是不能被改变的。相反,把波特率设成可变的话,
在系统生成后,可以通过软件设定分配寄存器的值来改变波特率。
下面是波特率和分配因子的计算方法:
divisor = int( (clock frequency)/(baud rate) + 0.5 )
baud rate = (clock frequency)/(divisor + 1)
数据位数的设定:
数据的数据位、停止位、奇偶校验位在系统生成时是可以配置的。一旦系统生成后,这些参数是不能被
改变的。
数据流(DMA)的控制方式:
UART可以支持流模式的Avalon传送方式。这样可以使得uart准备好接受下一个字符时主端口才会向它发送
数据,或者uart接收到数据时主端口才去读它接收的数据。此时可以设置SOPC Builder来选择给uart构造
end of packet寄存器。
在加入end of packet 寄存器后,uar就会在基地址+5的位置多了一个寄存器;在status寄存器中多一位
eop位;在control寄存器中多一位ieop位;在Avalon总线上多一个endofpacket信号用来和支持流模式数据
传输的主端口进行接口。如果没有设定该寄存器,则不会加入上述资源。
End-of-packet(EOP)侦测可以决定UART和支持流模式传输的Avalon主端口在什么时候中止流模式数据传输。
EOP侦测可以和DMA控制器中一起使用,例如,可以实现将UART中接收到的数据自动写入存储器,直到接收到一个
特定的字符。这个中止字符的就是被写入到endofpacket寄存器的值。
软件编程模式:
HAL 系统库支持
Altera公司为Nios II系统提供了设备驱动,该驱动将HAL层的字符型设备驱动集成到了HAL系统库中。
HAL用户可以通过熟悉的HAL API和ANSI C标准库,而不是访问UART的寄存器组。用户可以使用ioctl()请求
来控制和uart硬件相关的操作。
(注:如果在程序中使用HAL设备驱动来访问UART的话,此时直接对设备的寄存器进行访问会干扰设备驱动
的正常运行。)
对于Nios II CPU用户来说,HAL系统库的API提供了完整的对UART的访问函数。Nios II的程序把uart当
成一个字符型的设备,发送和接收数据都使用ANSI C标准库函数。
下面的代码示范了一个最简单的应用,用printf()打印一段消息到stdout。在这个例子中HAL系统库已经
配置了一个串口作为stdout。
----------------------------------------------------------------------------------------------
#include <stdio.h>
int main ()
{
printf("Hello world.\n");
return 0;
}
----------------------------------------------------------------------------------------------
下面的代码示范了如何通过C标准库从uart读字符和向uart发送消息。在这个例子中程序把该设备当成
和HAL文件系统中任何其他的节点一样来处理。
----------------------------------------------------------------------------------------------
/* A simple program that recognizes the characters 't' and 'v' */
#include <stdio.h>
#include <string.h>
int main ()
{
char* msg = "Detected the character 't'.\n";
FILE* fp;
char prompt = 0;
fp = fopen ("/dev/uart1", "r+"); //Open file for reading and writing
if (fp)
{
while (prompt != 'v')
{ // Loop until we receive a 'v'.
prompt = getc(fp); // Get a character from the UART.
if (prompt == 't')
{ // Print a message if character is 't'.
fwrite (msg, strlen (msg), 1, fp);
}
}
fprintf(fp, "Closing the UART file.\n");
fclose (fp);
}
return 0;
}
---------------------------------------------------------------------------------------------
驱动实现的两种选择:Fast vs. Small
根据不同系统的需要,uart驱动提供了两种形式:快速模式和小模式。快速模式是默认模式。这两种
模式都支持C标准库函数和HAL API。
快速模式是一种中断实现方式,这种方式可以使得CPU在UART未准备好收发数据时做其他的事情。
小模式是一种查询方式,这种方式必须一直在等待uart准备好以后才能收发数据。使能小模式可以
通过两种方式:1。设置HAL系统库工程属性,开启small footprintf(这种方法也会影响其他设备驱动);
2。定义预处理宏 -DALTERA_AVALON_UART_SMALL ,使用这个选项不会影响到其他设备的驱动。
ioctl()操作:
uart驱动支持ioctl()函数,该函数允许程序基于HAL层的设备相关操作请求。
------------------------------------------------------------------------------------------
请求 含义
TIOCEXCL 锁定设备避免被再次访问。对该设备用open()函数再次访问会失败,直到这个
设备的文件描述符被关闭,或者用TIOCNXCL ioctl请求解锁。在使用该请求时
"arg"参数可忽略。
TIOCNXCL 对前一次的访问解锁。在使用该请求时"arg"参数可忽略。
以下请求只对快速模式有效:
TIOCMGET 向termios结构填入内容,返回当前的设备配置情况。指向这个结构的指针
是作为ioctl的"opt"参数。
TIOCMSET 根据输入termios结构的值来配置设备。指向这个结构的指针是作为ioctl的
"arg"参数。
-----------------------------------------------------------------------------------------
termios结构在Newlib C标准库里被定义。在<Nios II kit path>/components/altera_hal/HAL
/inc/sys/termios.h文件中有它的定义。
软件开发文件:
UART的核还配有以下软件开发文件。这些文件定义了底层硬件的接口,并且提供了HAL驱动。
应用程序开发者不要去修改这些文件。
altera_avalon_uart_regs.h
该文件定义了寄存器映射,提供了符号名称来访问底层硬件。这些符号名称只是被设备驱动函数所
使用。
altera_avalon_uart.h,altera_avalon_uart.c
该文件实现了uart HAL系统库的设备驱动。
另外,UART还支持第一代Nios处理器遗留的SDK子程序。
UART的中断行为:
UART会输出一个IRQ信号到Avalon总线接口,它可以和任何主设备接口,例如,Nios II处理器。
主外设必须读status寄存器来决定是哪种类型中断。
每一种中断会在status和interrupt-enable寄存器中有相应的位。当任意一种中断条件满足时,
相应的寄存器位就会被置位,直到完全响应中断才会被清除。中断信号输出信号在任何status寄存器
的某一位被置位且那一位是被中断使能的。而主外设通过清除status寄存器来相应这个IRQ。
在系统复位时,所有的中断使能寄存器的位都被置为0,因此只有当主外设对中断使能寄存器的
一位或多位置1时,才能产生IRQ信号。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -