基于ARM9和嵌入式Linux的并口驱动开发标签:armlinux并口驱动分享到发表评论(0)编辑词条开心001人人网新浪微博随着计算机技术的急速发展,嵌入式系统已成为继Pc和Internet以后,IT技术热点。嵌入式系统容积小、功能强、开发灵活便捷,在工业控制、通信、航空航天、军事技术等领域取得了广泛的应用。在嵌入式系统的开发中,并口通信的设计是一个十分重要的部份,即使通用的并口驱动可以满足好多系统的须要,但在一些工业控制中,对并口讯号的数据格式,码率等都有着严格的限制,这就要求针对系统需求对并口进行重新开发。本文就基于ARM9芯片S3C2410和Linux系统,以某设备特殊的通信方法为例,详尽剖析并口驱动的开发方式,实现设备的通信。Linux下驱动开发简介在嵌入式Linux系统中,因为内核的保护机制,用户通常不能直接访问硬件,而是要通过调用驱动程序来实现对硬件的控制。进行嵌入式系统的开发,很大的工作量是为各类设备编撰驱动程序。设备驱动是介于硬件和操作系统之间的软件插口,主要功能包括:侦测和初始化设备;从设备接收数据并递交给内核;从内核接收数据送到设备;检查和处理设备错Linux下设备驱动的开发就是编撰各类函数实现设备的注册、初始化、IO操作、卸载等功能。
其通常模式如下。//定义主次设备号intUART_MAJOR=125;intUART_MINOR=2;//文件系统人口定义structfile_operationsuart_fops=//编撰人口函数,实现设备控制staticintuart_open(structinode}inode,structfile}flip){//编撰设备初始化和卸载函数intinituart_init(void){……exituart_cleanup(void){//初始化和卸载函数调用module_init(uart_init);voidexituart_cleanup(void);S3C2410芯片并口的控制S3C2410提供了三个通用异步串行通讯插口,每位并口都有一个码率发生器、接收寄存器、发送寄存器和一个控制单元,另外,还有两个16字节的FIFO寄存器作为发送和接收的缓冲装置,其结构框图如图1所示。在S3C2410中,对并口的控制是通过设置相应的控制寄存器来实现的,其常用的寄存器主要有以下几个:(1)ULCONn寄存器:主要拿来设置并口工作模式,包括数据位宽度、停止位个数,以及数据校准方法等。S3C2410支持四种校准方法,分别是奇校准、偶校准、MARK校准和SPACE校准。
(2)UCONn寄存器:该寄存器涉及到中断模式控制、DMA模式控制,以及时钟的选择等。(3)UTRSTATn寄存器:并口的状态寄存器,用于指示并口是否接收或发送完毕。(4)UTXHn和URXHn寄存器:发送和接收寄存器。(5)UBRDIVn寄存器:码率设置寄存器,用于对时钟分频,形成须要的码率。其值通过如下估算确定:UBRDIVn=(int)(PCLK/(bps%16))一1或则UBRDIVn=(int)(UCLK/(bps%16))一I其中PCLK或UCLK是选择的时钟,bps是须要的码率。并口驱动设计及应用实例下边通过一个设计实例来详尽剖析并口驱动的设计方式。某设备通过并口实现对下位机的控制,其控制指令由四个字节的并口数据组成,数据格式为8位数据位、一位停止位、一位校准位,其中第一个数据为MARK校准,后三个数据为SPACE校准,并口的码率为77.2kb/s。对于这么码率和校准方法都不常用的并口通信形式linux论坛,通用的并口驱动就无能为力了,这就要求针对硬件芯片的特征重新编撰驱动程序。依据系统要求中国linux,使用并口1实现该并口通讯的功能,其具体的编程实现如下:(1)在初始化函数中,注册并口设备。
retregister_chrdev(MAJOR_NR,DEVICE_NAME,&uart_fops);(2)在open函数中对并口进行初始化,选择端口并设置端口状态,确定并口的码率。在本系统中,系统时钟PCLK=50.7MHzarm linux 串口驱动,根据公式UBRDIVn=(int)(PCLK/(bps16))可得UBRDIVn=40。staticintuart_open(structinodeinode,structfilefilp){UBRDIV1=40;(3)采用ioctl函数实现对并口校准方法的选择设置,在应用程序中,通过系统调用在并口的两种校准方法中切换。staticintuart_ioctl(struclinodeinode。structfileflip,unsignedintcmd,unsignedlongparam){switch(cmd){caseFRAMEI:ULCON1&=0x00:ULCON1I=0x33;break;caseFRAME2:ULCON1&=0x00:ULCON1I=0x3b;break;(4)通过写函数write实现并口数据的发送。借助函数copy_from_user()即将发送的数据从用户空间调入到内核空间,并监视UTRSTATI寄存器,判定数据是否发送完成。
staticssize_uart_write(structfileflip,constcharbur,size_count,loff_t}fops){copy_from_user(&temp,bur,count);UTXH1=temp;;if((UTRSTAT1&~0x3)!=4);(5)最后,卸载设备驱动,释放资源。voidexituart_cleanup(void){unregister_chrdev(MAJOR_NRarm linux 串口驱动,DEVICE_NAME);至此,针对S3C2410芯片的特性,完成了并口驱动的整个驱动设计,满足了该设备特殊的并口通讯要求,在应用程序中对该并口的使用实例如下:XXXintzhl[4]={……};uart_fd=open(”/dev/uart”,O_RDWR);while(1){ioctl(uart_fd,FRAME1);write(uart_fd,&zH[0],1);ioctl(uart_fd,FRAME2);