判断串口是否有驱动 c语言,串口驱动程序设计

1、发送和接收

发送:循环buffer->发送fifo->发送移位寄存器

接收:接收移位寄存器-->接收fifo->Flip_buf

发送的过程是:把数据写到发送fifo中,fifo把收到的数据传给发送移位寄存器(自动的,非driver控制),然后每个时钟脉冲往串口上写一bit数据。

接收的过程是:接收移位寄存器受到数据,发送给接收fifo,接收fifo事先设置好了触发门限,当里面的数据量超过门限时就会触发一个中断,调用驱动中的中断处理函数,把数据写到flip_buf中

2、寄存器

(1)UART Line Contrl Register

ULCONn(线控制寄存器)

Word Length: 数据位长度

Number of Stop Bit:停止位数

Parity Mode: 奇偶校验位类型

Infra-Red Mode:UART/红外模式选择(当以UART模式工作时,需设为"0")

(2)UART Contrcl Register(UCON

n)

Recevice Mode:选择接收模式。如果是采用DMA模式的话,还需要指定说使用的DMA信道。

Transmit Mode :同上

Send Break Signal:选择是否在传1帧资料中途发送Break信号

Loopback Mode:选择是否将UART置于Loopback测试模式

Rx Error Status Interrupt Enable: 选择是否使能当发生接收异常时,是否产生接收错误中断。

Rx Time Out Enable:是否使能接收超时中断

Rx Interrupt Type:选择接收中断类型

选择0:Pulse(脉冲式/边沿式中断,非FIFO模式时,一旦接收缓冲区中有数据,即产生一个中断;为FIFO模式时,一旦当FIFO中的资料达到一定的触发水平后,即产生一个中断)

选择1:Level(电平模式中断,非FIFO模式时,只要接收缓冲区中有数据,即产生中断;为FIFO模式时,只有FIFO中的资料达到触发水平后,即产生中断)

Tx Interrupt Type:类同于Rx Interrupt Type

(3)UART FIFO Contrcl Register

FIFO Enable: FIFO使能选择

Rx FIFO Rest:选择当复位接收FIFO时是否自动清除FIFO中的内容。

Tx FIFO Rest:选择当复位发送FIFO时是否自动清除FIFO中的内容。

Rx FIFO Trigger Level:选择接收FIFO的触发水平。

Tx FIFO Trigger Level: 选择发送FIFO的触发水平。

(4)UART TX/RX Status Register(UTRSTATn)

Receive buffer data ready:当接收缓冲寄存器从UART接收端口接收到有效资料时将自动置"1",反之为"0"则表示缓冲器中没有资料。

Transmit buffer empty:当发送缓冲寄存器中为空,自动置"1"反之表明缓冲器中正有资料等待发送。

Transmit empty:当发送缓冲器中已经没有有效资料时,自动置"1",反之表明尚有资料发送。

(5)UART FIFO Status Register

Rx FIFO Count:接收FIFO中当前存放的字节数

Tx FIFO Count:发送FIFO中当前存放的字节数

Rx FIFO Full:为"1"表明接收FIFO已满

Tx FIFO Full:为"1"表明发送FIFO已满。

3、函数介绍

/*模块初始化函数*/

static int __init s3c2440uart_init(void)

{

return uart_register_driver(&s3c2440_reg);//使用uart_register_driver注册串口驱动

}

static struct uart_driver s3c2440_reg = {

owner: THIS_MODULE,

normal_major: SERIAL_S3C2440_MAJOR,

normal_name:"ttyS%d",

callout_name:"cua%d",

normal_driver:&normal,

callout_major:CALLOUT_S3C2440_MAJOR,

callout_driver:&callout,

table:s3c2440_table,

termios: s3c2440_termios,

termios_locked: s3c2440_termios_locked,

minor: MINOR_START,

nr: UART_NR,

port: s3c2440_ports,

cons: S3C2440_CONSOLE,

};

static struct uart_port s3c2410_ports[UART_NR] = {

{

iobase: (unsigned long)(UART0_CTL_BASE),

iotype: SERIAL_IO_PORT,

irq: IRQ_RXD0,

uartclk: 130252800,

fifosize: 16,

ops: &s3c2410_pops,

tyoe: PORT_S3C2410,

flags: ASYNC_BOOT_AUTOCONF,

},

....... ....... .......

}

static struct uart_ops s3c2410_pops = {

tx_empty: s3c2410uart_tx_empty,

set_mctrl: s3c2410uart_set_mctrl,

get_mctrl: s3c2410uart_get_mctrl,

stop_tx: s3c2410uart_stop_tx,

start_tx: s3c2410uart_start_tx,

stop_rx: s3c2410uart_stop_rx,

enable_ms: s3c2410uart_enable_ms,

break_ctl: s3c2410uart_break_ctl,

startup: s3c2410uart_startup,

shuwdown: s3c2410uart_shutdown,

change_speed: s3c2410uart_change_speed,

type: s3c2410uart_type,

config_port: s3c2410uart_config_port,

release_port: s3c2410uart_release_port,

request_port: s3c2410uart_request_port,

};

/*3.1阻止发送函数uart_stop_tx*/

static void s3c2410uart_stop_tx(struct uart_port *port,u_int from_tty)

{

disable_irq(TX_IRQ(port));

}

/*停止发送的功能,器内部的函数disable_irq是停止中断的功能,发送数据时通过中断来完成的,关闭中断也就关闭了发送*/

/*3.2发送使能函数uart_start_tx*/

static void s3c2410uart_start_tx(struct uart_port *port,u_int nonempty,u_int from_tty)

{

enable_irq(TX_IRQ(port));

}//与上面的过程类似,就是一个相反的过程。

/*3.3阻止接收函数uart_stop_rx*/

static void s3c2410uart_stop_rx(struct uart_port *port)

{

disable_irq(RX_IRQ(port));

}

/*发送缓冲空判断函数uart_tx_empty*/

static u_int s3c2410uart_tx_empty(struct uart_port *port)

{

return (UART_UTRSTAT(port) & UTRSTAT_TR_EMP ? 0 : TIOCSER_TEMT);

}

/*如果发送缓冲为空则返回0,否则返回1*/

/*3.5获取控制信息函数uart_get_mctrl*/

static u_int s3c2410uart_get_mctrl(struct uart_port *port)

{

return (TIOCM_CTS | TIOCM_DSR | TIOCM_CAR);

}

/*获取控制信息,TIOCM_CTS,TIOCM_DSR和TIOCM_CAR,这几个宏代表串口的控制信息,分别是clear to send,data set ready 和 data carrier detect(详见/serial Programming Guide for POSIX Operating Systems)*/

/*3.6接收中断函数uart_rx_interrupt*/

static void s3c2410uart_rx_interrupt(int irq,void *dev_id,struct pt_regs *regs)

{

struct uart_info *info = dec_id;

struct tty_struct *tty = info->tty;

unsigned int status,ch,max_count = 256;

struct uart_port *port = info->port;

status = UART_UTRSTAT(port);

while((status & UTRSTAT_RX_RDY) && max_count--)

{

if(tty->flip.count >= TTY_FLIPBUF_SIZE)

{

tty->flip.tqueue.routine((void*)tty);

if(tty->flip.count >= TTY_FLIPBUF_SIZE)

{

printk(KERN_WARING "TTY_DONT_FLIP set\n");

return;

}

}

ch = UART_URXH(port);

*tty->flip.char_buf_ptr = ch;

*tty->flip.flag_buf_ptr = TTY_NORMAL;

port->icount.rx++;

tty->flip.flag_buf_ptr++;

tty->flip.char_buf_ptr++;

tty->flip.count++;

status = UART_UTRSTAT(port);

while((staus & UTRSTAT_RX_RDY) && max_count--)

{

if(tty->flip.count >= TTY_FLIPBUF_SIZE)

{

tty->flip.tqueue.routine((void*)tty);

if(tty->flip.count >= TTY_FLIPBUF_SIZE)

{

printk(KERN_WARNING "TTY_DONT_FLIP set\n");

return;

}

}

ch = UART_URXH(port);

*tty->flip.char_buf_ptr = ch;

*tty->flip.flag_buf_ptr = TTY_NORMAL;

port->icount.rx++;

tty->flip.flag_buf_ptr++;

tty->flip.char_buf_ptr++;

tty->flip.count++;

status = UART_UTRSTAT(port);

}

tty_flip_buffer_push(tty);

return;

}

}

/*发送中断函数uart_tx_interrupt*/

static void s3c2410uart_tx_interrupt(int irq, void* dev_id,struct pt_regs *reg)

{

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值