ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:118.66KB ,
资源ID:23893173      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23893173.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(基于ARM9和Linux的嵌入式打印终端系统.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

基于ARM9和Linux的嵌入式打印终端系统.docx

1、基于ARM9和Linux的嵌入式打印终端系统河南理工大学计算机科学与技术学院课程设计报告2012 2013学年第 一 学期 课程名称:嵌入式系统课程设计设计题目:基于ARM9和Linux的 嵌入式打印终端系统学生姓名: 学 号: 专业班级: 指导教师: 2012 年 12月 23 日 1 嵌入式打印终端系统的设计原理22 嵌入式打印终端系统的硬件设计3 2.1硬件开发平台S3C2410结构 3 2.2 嵌入式开发板 3 2.3打印机与开发板接口电路的设计33 嵌入式打印终端系统的软件设计5 3.1软件选型5 3.2 打印机驱动的编写 5 3.3 扫描仪串口的设置 7 3.4 主应用程序的设计1

2、1参考文献 12附录 12基于ARM9和Linux的嵌入式打印终端系统引 言 随着开放源代码运动的飞速发展, Linux 操作系统越来越受到人们的 重视。其良好的可裁减性与可移植性, 卓越的效率和稳定性, 以及支持多种处 理 器体系架构的特点, 使得Linux 越来越广泛的应用于嵌入式领域。同时, ARM9 处理器高主频的处理速度、大容量的闪存芯片和MMU控制单元的支持, 使得运 行嵌入式Linux 变得稳定而高效。本文设计与实现的打印终端系统, 正是基于 这两个软硬件平台搭建起来的。1 嵌入式打印终端系统的设计原理图1 嵌入式移动打印终端架构嵌入式打印终端原理连接图如图1所示。主要由开发板、

3、主机、打印机和扫描仪四部分组成。主机是一台PC机。开发板采用的是三星公司S3C2410开发板,ARM9的核,跑的是2.4内核版本的嵌入式Linux操作系统。扫描仪为超市等用的手持扫描仪。再加一台微型打印机接在开发板的GPIO口上。工作流程为:开发板将扫描仪的数据从串口读出,然后通过网口将数据发送给主机进行检索处理。开发板等待直至接收到主机处理完毕的数据后转发给打印机,将信息打印出来。2 嵌入式打印终端系统的硬件设计2.1硬件开发平台S3C2410结构三星公司的S3C2410开发板用的是32位RISC架构基于ARM920T核,其增强的MMU单元、AMBA总线,可以支持Win CE、 Linux等

4、实时操作系统。片上资源丰富接口众多,包含LCD控制器、USB Host、CS9800A网络芯片、SD卡、3个UART通用异步串行口等设备接口。 2.2 嵌入式开发板嵌入式开发板是本系统的核心部件,它担负着整个系统中心枢纽的重担,同时,它的选型也直接影响到上层操作系统和其它部件的选型。所以,在选择这个部件时,要站在整个系统的高度来进行。选择嵌入式开发板要考虑的因素非常多,但必须首先考虑下面几个核心要素: 接口类型:在本系统中,嵌入式开发板连接着扫描仪、远程服务器和微型打印机。所以,开发板上必须具备和这些部件连接的接口,如和扫描仪连接时需要的RS-232C串口,和远程服务器连接时的网络接口,和微型

5、打印机连接时的打印接口。 所支持的操作系统:嵌入式开发和单片机开发核心的区别之一就是嵌入式开发往往基于一个操作系统之上来进行。嵌入式操作系统种类繁多,各具特色,因此,必须要选择一个较通用和易用的操作系统平台。在本开发实例中,我们选择嵌入式Linux作为后面的平台开发。 性价比:如果作为产品来开发,必须要考虑产品在价格上的竞争要素。嵌入式开发板可以自己设计,也可以直接购买市场上已有的成熟开发板,当然这种开发板一定是能够满足使用的最小系统,即裁减掉任何用不到的多余软/硬件。如果选择购买其他公司已有的开发板,首先要看该开发板是否稳定,其次要看该开发板是否能够提供所需的软件,比如各个部件的驱动;再次要

6、看开发板的售后支持。2.3打印机与开发板接口电路的设计我们使用的微型打印机使用的是并行接口。由于开发板上没有提供并口,所以必须自己设计一个板卡接口电路,以连接打印机的并口和我们的嵌入式开发板。查看S3C2410的电路原理图,由于此系统不需要用到LCD屏,可以将板子上用于LCD连接的GPIO口进行改造,根据ARM9core的LCD电路引脚和板上的LCD插槽定义,如图2,找到了14根空闲的GPIO口:gpio_c8gpio_d15,gpi0_d0gpio_d4。用这14根通用输入输出口连接微型打印机的并口。 图2 核心core 的LCD引脚和板上LCD引脚原理图同时查看打印机的电路手册和管脚定义,

7、选用其STB选通线、ACK回答脉冲线、BUSY线、DATA0-DATA7数据线来与开发板的GPIO口相连,并初始化高低电平值。为了避免接线过紧互相干扰,制作一个接口板定义各引脚连接如图3所示。至此,硬件的电路设计及连接基本完成。 图3 打印机并口与开发板GPIO口接口板设计图3 嵌入式打印终端系统的软件设计软件平台采用的是基于2.4内核的嵌入式Linux系统。采用的交叉编译器工具包为CROSS2.95.3.tgz(包含arm-linux-gcc等)。 3.1软件选型嵌入式系统是一个软/硬件相结合的系统,硬件好比人的身体,而运行在其上的软件则好比人的灵魂。没有软件的驾驭,硬件只是一些废铜烂铁,因

8、此,相比较硬件选型而言,软件的选择也异常重要。在整个软件选型中,要特别重视两个方面的因素: 运行其上的嵌入式操作系统:嵌入式操作系统是整个软件的核心和基础,的功能的强大与否直接影响后面整个系统的设计,因此必须加以重视。目前嵌入式操作系统有几百种之多,它们各具特色,各有相应的用武之地。通常来说,各个嵌入式开发板提供商,在其嵌入式开发板上会提供已经移植好的的几个嵌入式操作系统,这些操作系统通常为嵌入式Linux、Win CE、Vx Works和u CosII。uCosII是一个非常好的教学操作系统,但由于其功能较少,在商用领域使用比较少。而Vx Works由于较昂贵的使用费用,在中小型公司中使用也

9、较少。WinCE主要用于PDA等领域,嵌入式Linux由于其源码开放,共享资源丰富,整个系统功能异常强大,因此在嵌入式领域应用得也最为广泛。 软件驱动支持:由于不同的嵌入式开发板上提供的接口也各不相同,因此Linux内核源码包不可能提供所有外设接口的底层驱动。通常情况下,这些底层驱动或者由嵌入式开发板提供商做好后提供给用户使用,或者由用户自己开发出来。而底层驱动的开发是整个系统设计中比较耗时的工作,所以用户在选择开发板时,尽量选择已提供自己所需要的底层驱动的开发板,这样可以缩短项目的开发周期,减少项目投资,提高整个产品的竞争力。 3.2 打印机驱动的编写Linux的设备分为块设备,字符设备和网

10、络设备,该系统使用到的微型打印机属于字符设备,下面将具体说明如何设计打印机驱动。 3.2.1 定义设备名#define DEVICE_NAME weida_printer 3.2.2 模块函数设计在该系统中,采用模块化加载驱动程序的方法,因此必须实现模块的初始化函数和卸载函数。采用devfs方式注册打印机。初始化函数weida_init通过devfs_register函数向系统注册设备。函数原型devfs_register(NULL, DEVICE_NAME, DEVFS_FL_DEFAULT, 0, 0, S_IFCHR | S_IRUSR | S_IWUSR, &weida_printer

11、_fops, NULL);其中,DEVICE_NAME为主设备名,weida_printer_fops为定义的一个数据结构,用来实现的文件操作,包括open、close、write等。 3.2.3 初始化打印端口初始化打印机第一个要做的事情就是要对GPIO口进行初始化,初始化函数如下:static void weida_init(void)devfs_register(); /*注册设备驱动*/set_gpio_ctrl(WEIDA_STB|GPIO_PULLUP_DIS|GPIO_MODE_OUT); /*设置STB口*/ write_gpio_bit(WEIDA_STB,1); weida

12、_printer_io_port_init();/*设置其它IO口,以及赋初值*/ 其中,WEIDA_STB为连接打印机选通口初始化为高电平,GPIO_PULL_DIS是设置是否需要上拉电阻,GPIO_MODE_OUT 设置GPIO口为输出口。最后使用module_init(weida_printer_init);采用模块方式加载驱动。 3.2.4打印机驱动测试程序设计通过上面几个步骤,打印机驱动模块已经注册到内核,在/dev目录下可以找到weida_printer设备。编写如下简单程序测试代码。int main(void) int weida_fd,ret; char *data=“Hell

13、o,welcom to use weida printer!“; weida_fd=open(“/dev/weida_printer”,O_WRONLY); /打开/dev/weida_printer设备 if(weida_fd0) perror(“open device buttons”); exit(1);ret=write(weida_fd,data,strlen(data);/向打印机输出数据,打印“Hello”字符串if(ret!=strlen(data) perror(“print wrongn”);ioctl(weida_fd,WEIDA_IOCSLINESPACE,1);sle

14、ep(1);ret=write(weida_fd,data,strlen(data);if(ret!=strlen(data) perror(“print wrongn”);close(weida_fd);return 0; 3.2.5接口函数设计 ioctl()函数主要完成打印机字体、行距等参数的设置,在设计过程中必须解决用户数据和内核数据之间如何传递。从用户态读取数据,然后在内核态运行,可以使用copy_from_user函数来完成传递数据。 weida_printer_write ( )先对打印机是否在线,是否忙,是否准备好做进一步的判断,然后再进行打印。在打印的时候要注意每发一个字符要

15、延迟150毫秒,因为如果打印数据发得过快打印机的来不急处理,所以要设置延时。open/close函数打开/关闭文件,因为在LINUX下设备都是当作文件来操作的,所以需要open和close这两个接口函数。 3.3 扫描仪串口的设置 嵌入式移动打印终端中使用到的扫描仪是串口扫描仪,这种扫描仪相对于USB接口的扫描仪来说,控制较简单,在扫描仪扫描后,可以直接从串口读取数据。 3.3.1 串口设置 设置串口速率函数:set_speed(int fd, int speed),其中fd 为打开的设备文件,speed为速率。设置串口参数:set_parity(int fd,int data bits,in

16、t stop bits,int parity),data bits为有多少个数据位,stop bit为设置多少个停止位,parity为奇偶校验位设置。设置串口波特率为9600,数据位为8位,一位停止位,没有校验位。void set_speed(int fd,int speed)int j;int status;struct termios Opt;tcgetattr(fd,&Opt);for(i=0;isizeof(speed_arr)/sizeof(int);i+)if(speed=name_arri)tcflush(fd,TCIOFLUSH);cfsetispeed(&Opt,speed_

17、arri);cfsetospeed(&Opt,speed_arri);status=tcsetattr(fd,TCSANOW,&Opt);if(status!=0)perror(“tcsetattr fd!”);return;tcflush(fd,TCIOFLUSH); set_partity(int fd,int databits,int stopbits,int partity)用于设置串口的通信参数,其中databits设置数据位位数,stopbit设置停止位位数,partity设置奇偶校验位。具体的函数代码如下:int set_partity(int fd,int databits,i

18、nt stopbits,int partity) struct termiios options; if(tcgetattr(fd,&options)!=0perror(“SetupSerial 1”);return FALSE;options.c_cflag &=CSIZE;switch(databits)case 7: options.c_cflag!=CS7; break;case 8: options.c_cflag|=CS8; break;default: fprintf(stderr,”Unsupported data sizen”); return FALSE;switch(pa

19、rtity)case n:case N: options.c_cflag=PARENB;options.c_cflag=INPCK; break;case o:case O: options.c_cflag|=(PARODD|PARENB);options.c_cflag|=INPCK; break;case e:case E: options.c_cflag|=PARENB;options.c_cflag&=PARODD;options.c_cflag|=INPCK; break;case s:case S: options.c_cflag&=PARENB;options.c_cflag&=

20、CSTOP; break;default: fprintf(stderr,”Unsupported partityn”); return FALSE;switch(stopbits)case 1: options.c-cfag&=CSTOPB; break;case 2: options.c-cfag|=CSTOPB; break;default:fprintf(stderr,”Unsupported stop bitsn”); return FALSE; 3.3.2 编写读取扫描仪数据函数 首先打开设备文件,该系统中使用的串口为串口2,因此打开函数为:open(“/dev/ttyS1”,O_

21、RDWR|O_NONBLOCK|O_NDELAY);其中,O_RDWR表示可读可写,O_NONBLOCK表示非堵塞模式,O_NDELAY表示没有延迟,立即发出去。 3.3.3 客户端和服务器的socket编写 嵌入式打印终端采用C/S的模式,把PC机作为服务器,开发板作为客户端,通过以太网连接。客户端建立一个socket连接去寻找PC机上的服务程序。PC机上同时也运行一个socket用来listen请求和绑定。采用的是TCP的连接方式。 3.4 主应用程序的设计 开发板上的应用程序Main函数注册两个线程p1和p2,两个全局数组c1和c2。线程p1将从串口读到的数据放入c1中,然后sent s

22、ocket直接从c1中取走数据发送给服务器。线程p2负责将received socket数据放入c2数组中,然后直接从c2取走数据交给打印机去打印。 这里对线程使用了两个信号量,并初始化为:sem_init(&sem1,0,1); sem_init(&sem2,0,0);两个线程的核心代码如下:void thread1(void) 打开串口;设置串口;建立连接; while(1) sem_wait(&sem1); 从串口读书据;用clinetsocket发送出去; sem_post(&sem2);void thread2(void) 打开打印机设备; while(1) sem_wait(&se

23、m2); 接收数据;扔给打印机; sem_post(&sem1); 如此可以使两个线程得以同步运行,并可以执行多次扫描和打印任务。总结 本文创新点及其经济效益:本系统具有移动性强,功耗低等特点,而且与以往传统的用PC 机实现的打印终端相比,还具有低成本优势。能广泛地应用于超市收银系统,银行自动存取款机,等各种工业领域。把802.11g的无线网卡移植到开发板上,就可以成功实现和主机的无线通信,使得该系统更加便携。参考文献1 ARM嵌入式系统原理及应用开发.谭会生.西安电子科技大学出版社,2012 .2 CORBET J, RUBINI A. LINUX设备驱动程序(第三版)M. 中国电力出社,

24、2006. 46-74 TP316.813 孙琼. 嵌入式LINUX应用程序开发详解M. 人民邮电出版社, 2006. 184-191 TP316.894 田家林,陈利学,寇向辉 LINUX嵌入式操作系统在ARM上的移植J. 微计算机信息, 2007,4-2:P60-62附录:(部分程序)#define DEVICE_NAME “weida_printer”#define WEIDA_MAJOR 234 module_init(weida_printer_init);module_exit(weida_printer_exit);MODULE_LICENSE(“GPL”);static int

25、 module_init(weida_printer_init) int ret; ret=register_chrlev(WEIDA_MAJOR,DEVICE_NAME,&weida_printer_fops); if(ret0) printf(DEVICE_NAME ”cant register major numbern”); return ret;weida_printer_io_port_init();weida_init();printf(“weida_printer_init!n“);return ret;gpio_data_tb=GPIO_C8,GPIO_C9,GPIO_C10

26、,GPIO_C11,GPIO_C12,GPIO_13,GPIO_C14,GPIO_C15;#define DATA_NUM(sizeof gpio_data_tab)/sizeof(gpio_data_tab0)#define WEIDA_DATA_READY GPIO_D0#define WEIDA_ACK GPIO_D1#define WEIDA_BUSY GPIO_D2#define WEIDA_SELECT GPIO_D3#define WEIDA_ERROR GPIO_D4 static void weida_printer_to_init(void) int I; unsigned

27、 gpio; for(i=0;iDATA_NUM;i+) gpio=gpio_data_tabi; set_gpio_ctrl(gpio|GPIO_PULLUP_DIS|GPIO_MODE_OUT); write_gpio_bit(gpio,0);set_gpio_ctrl(WEIDA_DATA_READY|GPIO_PULLUP_DIS|GPIO_MODE_OUT);set_gpio_ctrl(WEIDA_ACk|GPIO_PULLUP_DIS|GPIO_MODE_IN);set_gpio_ctrl(WEIDA_BUSY|GPIO_PULLUP_DIS|GPIO_MODE_IN);set_g

28、pio_ctrl(WEIDA_SELECT|GPIO_PULLUP_EN|GPIO_MODE_IN);set_gpio_ctrl(WEIDA_ERROR|GPIO_PULLUP_EN|GPIO_MODE_IN);printf(“init port!n”);static int weida_printer_write(struct file *file,const char8 buffer,size_t count,loff_t *ppos) unsigned char *kbuf; int ready; /判断打印机是否忙 ready=read_gpio_bit(WEIDA_BUSY); if(ready) return EBUSY;/判断打印机是否在线 readyread_gpio_bit(WEIDA_SELECT); if(!ready) return EAGAIN; ready=read_gpio-bit(WEIDA_ERROR); if(!ready) return EINVAL; kbuf=kmalloc(count+1,GFP_KERNEL); memset(kbuf,”0”,count+1); if(copy_from_user(kbuf,buffer,count) printf(“copy form user wrong!”); kfree(kbuf);

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1