UART串口驱动程序移植 仇洁婷,陈儒军
在嵌入式控制系统采集站的设计方案中,需要用到
AT91RM9200
的
5
个
UART
串口,就会涉及到多个中断的优先级分配问题,而且也可能造成串行通信的中断不能及时响应,从而造成数据丢失。在
Linux2.6.21
内核中,
UART
驱动程序成功地解决了这个问题,它采用了
DMA
传输的串行通信方式。
DMA
(
Direct Memory Access
)是一种高速的数据传输操作,在外部设备和存储器之间直接读
/
写数据,提高了通信的可靠性。
Linux
对串口驱动支持很完善,具有统一的编程接口。
包含
3
层:
tty
核心、
tty
线路规范和
tty
驱动。
tty
核心层向上提供统一的访问接口,使得用户不必关注具体终端的类型。
tty
线路规范指定数据交互的形式。
tty
驱动层用来操作硬件。一般只需针对不同的串口功能在
tty
驱动层中添加相应的配置宏即可。本系统将
Linux-2.6.21
打上
at91rm9200dk
体系结构的补丁后,基本上就能够使用
UART
设备驱动。
根据本系统的硬件设计要求,还需进行如下修改:
一、注册串口次设备号
在
Linux2.6
内核中,就只引出了
2
个串口的驱动注册信息,需要增加其他
3
个串口。可以在
linux2.6.21/arch/mach-at91/board-dk.c
文件中只定义了
DEBUG UART
和
UART1
,因此要改为
.nr_tty = 5,
.tty_map = { 4, 0, 1, 2, 3 }
UART0
、
UART1
、
UART2
、
UART3
和
Debug UART
这些串行端口和设备名称、设备号、次设备号的对应关系如下表
:
串行端口
|
设备名称
|
设备号
|
次设备号
|
UART0
|
/dev/ttyS1
|
4
|
1
|
UART1
|
/dev/ttyS2
|
4
|
2
|
UART2
|
/dev/ttyS3
|
4
|
3
|
UART3
|
/dev/ttyS4
|
4
|
4
|
Debug UART
|
/dev/ttyS0
|
4
|
0
|
在本方案中,需要用到
UART0
和
UART2
串口的时钟信号
SCK
,但是在
Linux2.6
内核的串口驱动程序中,并没有引出
UART0
~
UART3
所带有的时钟信号,所以需要进行修改。
二、注册时钟信号SCK引脚
在
AT91RM9200
芯片的定义中,
UART0
和
UART2
串口的时钟信号
SCK
分别是
PA19
和
PA24
管脚中的外设
A
功能,因此,需要用
at91_set_A_periph
函数把
PA19
和
PA24
引脚赋予
Periph A
。
在
linux-2.6.21/arch/arm/mach-at91/at91rm9200_devices.c
文件中的
configure_ usart0_pins
和
configure_usart2_pins
函数中增加:
at91_set_A_periph(AT91_PIN_PA19, 0);
at91_set_A_periph(AT91_PIN_PA24, 0);
三、设置UART模式寄存器的CLKO
UART
模式寄存器
US_MR
中提供了
UART
时钟的设置位
CLKO
。若
CLKO
设置位为
0
,
UART
不驱动
SCK
引脚;
CLKO
设置位为
1
,如果
US_MR
寄存器的
USCLKS
设置位(时钟选择)没有选择外部时钟
SCK
,则
UART
驱动
SCK
引脚。在
/linux-2.6.21/drivers/serial/atmel_serial.c
文件中,
USCLKS
设置位没有选择外部时钟
SCK
,则只需要在
atmel_set_termios
函数中设置
CLKO
位即可。
UART_PUT_MR(port, mode | ATMEL_US_CLKO);
|