志在指尖
用双手敲打未来

linux串口驱动(linux安装串口驱动命令详解)

linux串口驱动

1串口本质上也是字符设备!!!!!!!!!!!!串口是不支持热拔插的。假如强行热拔插,简单损坏串口芯片!!!!!!!!!!!!!!!!!!!!!
名词解释:流控”软件”流操控:帧头帧尾
“硬件”流操控:信号线
一。流程
个人建议只要能够读懂代码,根据实际需求进行验证和装备即可。
1翻开串口,一般使用open函数,翻开之后会回来句柄,这个句柄就能够提供给发送和接纳函数使用。
2初始化串口,串口需求装备波特率,数据位,校验位等等一系列的参数,初始化的过程把握了,发送和接纳都比较简单完成。
3发送和接纳数据,前面提到过串口是属于字符设备的,能够使用read函数和write函数完成。
4关闭,使用函数close即可关闭串口。
1翻开串口
1.1确认设备节点dev目录下,在4412开发板中,设备节点使用的是ttySAC*系列(0-3)
1.2原理图上对应:先在底板上找到外设,在到核心板上找对应的引脚名称
1.3例程:翻开串口设备节点
2初始化串口
2.1open()读取句柄
2.2structtermio来自内核文件arch\arm\include\asm
成员tcflag_tc_iflag:输入形式标志
成员tcflag_tc_oflag:输出形式标志
成员tcflag_tc_cflag:操控形式标志
成员tcflag_tc_lflag:本地形式标志
成员cc_tc_line:linediscipline
成员cc_tc_cc[NCC]:controlcharacters
2.3#include
#include//装备串口通用头文件
inttcgetattr(intfd,structtermios*termios_p)//读取当时串口参数
参数1:fd是open回来的文件句柄。
参数2:*termios_p是前面介绍的结构体
履行成功回来0,失利回来-1
intcfsetispeed(structtermios*termios_p,speed_tspeed);//修正输入波特率
intcfsetospeed(structtermios*termios_p,speed_tspeed);修正输出波特率linux
参数1:*termios_p是前面介绍的结构体。
参数2:speed波特率,常用的B2400,B4800,B9600,B115200,B460800等等。
履行成功回来0,失利回来-1
speed_tcfgetispeed(conststructtermios*termios_p)//读取当时串口输入的波特率
speed_tcfgetospeed(conststructtermios*termios_p)//读取当时输出的波特率
inttcflush(intfd,intqueue_selector);用于清空串口中没有完成的输入或许输出数据。在接纳或许发送数据的时候,
串口寄存器会缓存数据,这个函数用于铲除这些数据
参数1:fd是open回来的文件句柄。
参数2:操控tcflush的操作。
TCIFLUSH铲除正收到的数据,且不会读取出来;
TCOFLUSH铲除正写入的数据,且不会发送至终端;
TCIOFLUSH铲除一切正在产生的I/O数据。
履行成功回来0,失利回来-1
inttcsetattr(intfd,intoptional_actions,conststructtermios*termios_p);设置参数
参数1:fd是open回来的文件句柄。
参数2:optional_actions是参数收效的时刻。
TCSANOW:不等数据传输完毕就立即改变属性;
TCSADRAIN:等候一切数据传输结束才改变属性;
TCSAFLUSH:清空输入输出缓冲区才改变属性
参数3:*termios_p在旧的参数基础上修正的后的参数
履行成功回来0,失利回来-1
2.4代码
A函数不明白用man命令查,里边有详细的参数介绍
B关于堵塞与非堵塞要评论(已解决)
Cuartinit01.c—-pds
D总是读不出数,可能是open函数的选项选错了(不是这个原因,但是参数要好美观)
这仅仅是应用程序,不是驱动程序,驱动程序是直接调用4412开发板写好的串口驱动,今后有时刻去看一下
#include//规范输出头文件
#include//文件操作头文件1
#include//文件操作头文件2
#include//文件操作头文件3
#include//文件操作头文件4
#include//strlen()函数需求
#include//串口头文件
#include//Linux界说错误的头文件
intset_opt(intfd,intnSpeed,intnBits,charnEvent,intnStop);
voidmain()
{undefined
intfd,w,i;
char*uart3=”/dev/ttySAC3″;//需求改动
char*buffer=”pleaseinput”;
charbuffer1[100];
memset(buffer1,0,sizeof(buffer1));
if((fd=open(uart3,O_RDWR|O_CREAT,0777))<0)
{undefined
printf(“open%sfailed!\n”,uart3);
}else
{undefined
printf(“open%ssuccess!!\n”,uart3);
set_opt(fd,115200,8,’N’,1);
w=write(fd,buffer,strlen(buffer));
while(1)
{undefined
if((i=read(fd,buffer1,100))>0);
{undefined
w=write(fd,buffer1,strlen(buffer1));
memset(buffer1,0,sizeof(buffer1));
i=0;
}
}
}
close(fd);
}
intset_opt(intfd,intnSpeed,intnBits,charnEvent,intnStop)
{undefined
structtermiosnewtio,oldtio;
if(tcgetattr(fd,&oldtio)!=0){undefined
perror(“SetupSerial1”);
return-1;
}
bzero(&newtio,sizeof(newtio));
newtio.c_cflag|=CLOCAL|CREAD;
newtio.c_cflag&=~CSIZE;
switch(nBits)
{case7:
newtio.c_cflag|=CS7;
break;
case8:
newtio.c_cflag|=CS8;
break;
}
switch(nEvent)
{case’O’:
newtio.c_cflag|=PARENB;
newtio.c_cflag|=PARODD;
newtio.c_iflag|=(INPCK|ISTRIP);
break;
case’E’:
newtio.c_iflag|=(INPCK|ISTRIP);
newtio.c_cflag|=PARENB;
newtio.c_cflag&=~PARODD;
break;
case’N’:
newtio.c_cflag&=~PARENB;
break;
}
switch(nSpeed)
{undefined
case2400:
cfsetispeed(&newtio,B2400);
cfsetispeed(&newtio,B2400);
break;
case4800:
cfsetispeed(&newtio,B4800);
cfsetispeed(&newtio,B4800);
break;
case9600:
cfsetispeed(&newtio,B9600);
cfsetispeed(&newtio,B9600);
break;
case115200:
cfsetispeed(&newtio,B115200);
cfsetispeed(&newtio,B115200);
break;
default:
cfsetispeed(&newtio,B9600);
cfsetispeed(&newtio,B9600);
break;
}
if(nStop==1)
{undefined
newtio.c_cflag&=~CSTOPB;
}
elseif(nStop==2)
{undefined
newtio.c_cflag|=CSTOPB;
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;
}
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{undefined
perror(“comseterror”);
return-1;
}
return0;

linux安装串口驱动命令详解

1、串口驱动中的数据结构
UART驱动程序结构:structuart_driver驱动
UART端口结构:structuart_port串口
UART相关操作函数结构:structuart_ops串口操作函数集
UART状况结构:structuart_state串口状况
UART信息结构:structuart_info串口信息
2、串口驱动程序-初始化
3、串口驱动剖析-打开设备
staticints3c24xx_serial_startup(structuart_port*port)
{structs3c24xx_uart_port*ourport=to_ourport(port);intret;
dbg(“s3c24xx_serial_startup:port=%p(%08lx,%p)\n”,
port->mapbase,port->membase);
rx_enabled(port)=1;
ret=request_irq(ourport->rx_irq,s3c24xx_serial_rx_chars,0,
s3c24xx_serial_portname(port),ourport);if(ret!=0){
printk(KERN_ERR”cannotgetirq%d\n”,ourport->rx_irq);returnret;
}
ourport->rx_claimed=1;
dbg(“requestingtxirq…\n”);
tx_enabled(port)=1;
ret=request_irq(ourport->tx_irq,s3c24xx_serial_tx_chars,0,
s3c24xx_serial_portname(port),ourport);if(ret){
printk(KERN_ERR”cannotgetirq%d\n”,ourport->tx_irq);gotoerr;
}
ourport->tx_claimed=1;
dbg(“s3c24xx_serial_startupok\n”);/*theportresetcodeshouldhavedonethecorrect
*registersetupfortheportcontrols*/returnret;
err:
s3c24xx_serial_shutdown(port);returnret;
}
3、串口驱动程序-数据发送
staticvoids3c24xx_serial_start_tx(structuart_port*port)
{structs3c24xx_uart_port*ourport=to_ourport(port);staticinta=1;//tempif(port->line==3){//printk(“485_start_tx\n”);if(a){
s3c_gpio_cfgpin(S3C64XX_GPK(5),S3C_GPIO_SFN(1));
a=0;
}
gpio_set_value(S3C64XX_GPK(5),1);
}if(!tx_enabled(port)){if(port->flags&UPF_CONS_FLOW)
s3c24xx_serial_rx_disable(port);
enable_irq(ourport->tx_irq);
tx_enabled(port)=1;linux串口驱动
}
}
staticirqreturn_ts3c24xx_serial_tx_chars(intirq,void*id)
{structs3c24xx_uart_port*ourport=id;structuart_port*port=&ourport->port;structcirc_buf*xmit=&port->state->xmit;intcount=256;if(port->x_char){
wr_regb(port,S3C2410_UTXH,port->x_char);
port->icount.tx++;
port->x_char=0;gotoout;
}/*ifthereisn’tanythingmoretotransmit,ortheuartisnow
*stopped,disabletheuartandexit*/if(uart_circ_empty(xmit)||uart_tx_stopped(port)){
s3c24xx_serial_stop_tx(port);gotoout;
}/*tryanddrainthebuffer…*/while(!uart_circ_empty(xmit)&&count–>0){if(rd_regl(port,S3C2410_UFSTAT)&ourport->info->tx_fifofull)break;
wr_regb(port,S3C2410_UTXH,xmit->buf[xmit->tail]);
xmit->tail=(xmit->tail+1)&(UART_XMIT_SIZE-1);
port->icount.tx++;
}if(uart_circ_chars_pending(xmit)<WAKEUP_CHARS)
uart_write_wakeup(port);if(uart_circ_empty(xmit))
s3c24xx_serial_stop_tx(port);out:returnIRQ_HANDLED;
4、串口驱动程序-数据接收
s3c24xx_serial_rx_chars(intirq,void*dev_id)
{structs3c24xx_uart_port*ourport=dev_id;structuart_port*port=&ourport->port;structtty_struct*tty=port->state->port.tty;
unsignedintufcon,ch,flag,ufstat,uerstat;intmax_count=64;while(max_count–>0){
ufcon=rd_regl(port,S3C2410_UFCON);
ufstat=rd_regl(port,S3C2410_UFSTAT);if(s3c24xx_serial_rx_fifocnt(ourport,ufstat)==0)break;
uerstat=rd_regl(port,S3C2410_UERSTAT);
ch=rd_regb(port,S3C2410_URXH);if(port->flags&UPF_CONS_FLOW){inttxe=s3c24xx_serial_txempty_nofifo(port);if(rx_enabled(port)){if(!txe){
rx_enabled(port)=0;continue;
}
}else{if(txe){
ufcon|=S3C2410_UFCON_RESETRX;
wr_regl(port,S3C2410_UFCON,ufcon);
rx_enabled(port)=1;gotoout;
}continue;
}
}/*insertthecharacterintothebuffer*/flag=TTY_NORMAL;
port->icount.rx++;if(unlikely(uerstat&S3C2410_UERSTAT_ANY)){
dbg(“rxerr:portch=0x%02x,rxs=0x%08x\n”,
ch,uerstat);/*checkforbreak*/if(uerstat&S3C2410_UERSTAT_BREAK){
dbg(“break!\n”);
port->icount.brk++;if(uart_handle_break(port))gotoignore_char;
}if(uerstat&S3C2410_UERSTAT_FRAME)
port->icount.frame++;if(uerstat&S3C2410_UERSTAT_OVERRUN)
port->icount.overrun++;
uerstat&=port->read_status_mask;if(uerstat&S3C2410_UERSTAT_BREAK)
flag=TTY_BREAK;elseif(uerstat&S3C2410_UERSTAT_PARITY)
flag=TTY_PARITY;elseif(uerstat&(S3C2410_UERSTAT_FRAME|S3C2410_UERSTAT_OVERRUN))
flag=TTY_FRAME;
}if(uart_handle_sysrq_char(port,ch))gotoignore_char;
uart_insert_char(port,uerstat,S3C2410_UERSTAT_OVERRUN,
ch,flag);
ignore_char:continue;
}
tty_flip_buffer_push(tty);out:returnIRQ_HANDLED;

未经允许不得转载:IT技术网站 » linux串口驱动(linux安装串口驱动命令详解)
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

志在指尖 用双手敲打未来

登录/注册IT技术大全

热门IT技术

C#基础入门   SQL server数据库   系统SEO学习教程   WordPress小技巧   WordPress插件   脚本与源码下载