嵌入式系统软硬件设计.docx
《嵌入式系统软硬件设计.docx》由会员分享,可在线阅读,更多相关《嵌入式系统软硬件设计.docx(11页珍藏版)》请在冰豆网上搜索。
嵌入式系统软硬件设计
课程名称:
嵌入式系统的软硬件设计
论文题目:
基于嵌入式web服务器的远程控制系统
姓名:
组号:
日期:
一、设计背景介绍
目前,Internet技术已在全球普及,嵌入式也开始采用这一技术,并成为热点。
嵌入式的Internet技术具有广泛的应用前景,比如智能公路、信息家电、工业自动化、电子商务、设备管理等。
在嵌入式Internet技术中,嵌入式web服务器的研究有这种用意义。
它可以为我们管理、控制和监测各式各样的设备提供了已很好的途径。
嵌入式Web服务器可以运行在硬件受限的嵌入式系统上,通过用户端的浏览器,可以使用图形界面来访问嵌入式系统,而这种方式是基于Internet的,这种设备可以在世界的任何一个地方,只要它连入Internet就能控制它,非常的方便。
随着Internet技术和嵌入技术的高速发展,基于Internet的远程控制越来越普遍,工业现场运行维护模式正在发生深刻的网络变化:
即将web服务器“嵌入”工业控制系统中接入Internet网中,在世界的任何一个地方可以通过网络Internet获得该工业控制的实时控制的信息。
进而实现实时远程控制,调节,维护。
显然这种基于web服务器的远程控制维护将大大减少成本。
但是现有的远程控制系统都是基于C/S模式的,需要客户端程序的支持,这不仅加大客户端的编程,还加大客户端的维护的工作量。
本小组选择了基于嵌入式web服务器远程控制系统。
提供简单的人机交互页面的,减少了远程控制系统程序开发的难度。
二、系统总体方案
2.1硬件资源
本次课程实验采用的硬件平台友善公司的MINI2440开发板,如图1所示。
Mini2440是一款真正低价实用的ARM9开发板,是目前国内性价比最高的一款学习板;它采用SamsungS3C2440为微处理器,并采用专业稳定的CPU内核电源芯片和复位芯片来保证系统运行时的稳定性。
开发板提供了3个串行口、一个USBHost、一个USBSlaveB、4个USERLED、1个PWM控制蜂鸣器、一个可调电阻等。
根据本系统所涉及的模块做出系统硬件框图如图2所示。
图1MINI2440
图2系统硬件框图
2.2软件设计
首先分析系统的功能需求,我们设计题目是基于嵌入式web服务器的远程控制系统,那么此系统需要完成以下几个功能:
1)WEB服务器的搭建
经过查阅资料我们选择BOA服务器作为本系统的WEB服务器,BOA服务器是一个小巧高效的web服务器,是一个运行于unix或linux下的,支持CGI的、适合于嵌入式系统的单任务的http服务器,源代码开放、性能高。
具体的搭建流程参考网络资料。
2)控制页面的编写
控制页面主要是通过html语言编写,将页面文件放置在web服务的文件根目录下,等待浏览器访问web服务器时,服务器能够自动的返回我们所编写的页面,从而实现与远程的交互
3)服务器端CGI程序的编写
根据html和CGI调用的规范,我们将事先写好的程序编译成CGI文件放置到web服务器的相应文件夹中,当有相应的请求发生时,web服务器会自动条用相应的CGI程序。
4)linux驱动的编写
linux驱动主要涉及LED驱动、PWM驱动及DS18B20驱动。
本系统大体的流程图如下:
系统流程图
三、驱动设计(个人工作)
1、主要内容
1)蜂鸣器驱动的编写
2)DS18B20驱动的编写
2、设备驱动原理
linux系统设备分为3类:
字符设备、块设备、网路设备。
基本框架如下图所示:
字符设备:
是指只能按字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后。
字符设备是面向流的设备,常见的设备有鼠标、键盘、串口、控制台和LED设备等。
块设备:
是指可以从设备的任意位置读取一定长度的设备。
块设备包括硬盘、磁盘、U盘和SD卡等。
编写字符设备驱动之前可以通过下图了解用户空间与字符设备是如何进行交互的:
3、蜂鸣器驱动编写
蜂鸣器的控制时通过改变PWM的占空比来实现的,MINI2440开发板提供了如下资源,通过控制GPB0的输出可以控制蜂鸣器的状态,因为本实验要实现的是对蜂鸣器响声的调节,所以需要调节引脚输出电平的频率和占空比来实现,这样就需要编写PWM驱动了。
整个驱动设计流程如下图所示:
1)字符设备的定义
structpwm_dev{
structcdevcdev;//字符设备结构体
};
定义一个结构体用来存放相关变量,有利于提高驱动的扩展性。
2)设备初始化
cdev_init(&dev->cdev,&pwm_fops);
通过调用cdev_init函数进行设备的初始化,第一个参数为字符设备结构体的地址,第二个变量为pwm设备的操作函数结构体地址。
3)设备号获取
if(pwm_major)//主设备号已经分配直接注册设备
{
devno=MKDEV(pwm_major,pwm_minor);
result=register_chrdev_region(devno,1,DEV_NAME);
}
else//主设备号未分配,需要动态分配
{
result=alloc_chrdev_region(&devno,0,1,DEV_NAME);
pwm_major=MAJOR(devno);
}
if(result<0)//注册失败或分配失败
{
returnresult;
}
这段代码主要实现设备号的获取首先驱动文件中定义一个pwm_major变量存储了主设备号,首先判断主设备号是否已经分配,如果已经分配(主设备号可以自己手动分配)则使用register_chrdev_region直接注册设备,否者就通过alloc_chrdev_region函数动态获取主设备号
4)添加设备
dev->cdev.owner=THIS_MODULE;
dev->cdev.ops=&pwm_fops;
err=cdev_add(&dev->cdev,devno,1);
对字符设备结构体的一些变量进行初始化,然后调用cdev_add进行设备的添加。
5)设备操作函数的定义
structfile_operationspwm_fops=
{
.owner=THIS_MODULE,
.open=pwm_open,
.release=pwm_release,
.unlocked_ioctl=pwm_ioctl,
};
定义一个file_operations结构体用于指明此设备驱动在系统调用的时候回调用哪些函数,由于本设备只需要具备open(打开操作)、release(释放操作)和unlocked_ioctl(设备控制操作)。
pwm_open
staticintpwm_open(structinode*inode,structfile*filp)
{
intretval=0;
filp->private_data=pwm_devp;
tyy_pwm_init();
printk("PWMinitOK!
\n");
returnretval;
}
voidtyy_pwm_init(void)
{
tyy_pwm_gpio_init();
tyy_pwm_config();
}
pwm_open函数中主要实现有关PWM引脚的配置、寄存器的配置,设定PWM引脚为TOUT、时钟频率62.5KHZ,同时定时器自动装载计数值。
pwm_release
staticintpwm_release(structinode*inode,structfile*filp)
{
tyy_pwm_close();
printk("closeok\n");
return0;
}
voidtyy_pwm_close(void)
{
unsignedlongval_TCON=__raw_readl(PWM_TCON);
val_TCON&=~PWM_TCON_TXRELOAD;
__raw_writel(val_TCON,PWM_TCON);
s3c2410_gpio_cfgpin(PWM_GPIO,S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(PWM_GPIO,0);
}
pwm_release主要实现PWM的关闭,当设备文件关闭时,会调用此函数实现PWM定时器的停止,GPB0端口输出的设置(主要防止端口处于高定平导致蜂鸣器叫,因此需要设置为低电平)
pwm_ioctl
staticlongpwm_ioctl(structfile*file,unsignedintcmd,unsignedlongarg)
{
switch(cmd)
{
casePWM_IOCTL_START:
tyy_pwm_start();
return0;
default:
return-EINVAL;
}
}
pwm_ioctl函数主要实现对PWM的一些控制,本驱动中总共定义了三个CMD
#definePWM_IOCTL_START_IO(PWM_MAGIC,0)
#definePWM_IOCTL_SET_TCNTB_IOW(PWM_MAGIC,1,int)
#definePWM_IOCTL_SET_TCMPT_IOW(PWM_MAGIC,2,int)
第一个为启动PWM定时器、第二个为设置PWM中TCNTB寄存器的值用于设定定时器的计数值、第三个为设置PWM中TCMPT的值用于设定占空比。
6)设备驱动的测试
intfd;
fd=open("/dev/pwm_ctl",O_RDWR);
if(fd<0)
{
perror("Opendevicefailed!
\n");
exit
(1);
}
ioctl(fd,PWM_IOCTL_SET_TCNTB,3000);
ioctl(fd,PWM_IOCTL_SET_TCMPT,0);
ioctl(fd,PWM_IOCTL_START);
通过读取设备文件然后通过ioctl来控制PWM的输出及启动。
4、DS18B20驱动编写
DS18B20是常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。
硬件连接图如下图所示(本系统DS18B20接在GPB1上)。
其操作主要通过1-wire协议完成,根据数据手册提供的操作时序及命令定义即可实现温度的获取。
由于DS18B20的驱动也是采用字符设备驱动所以在设计时很多东西都是和PWM设备驱动是相同的,下面主要介绍两者不同的地方。
虽然在linux驱动说明提供有关的1-wire但一直没有找到相关使用资料,所以整个DS18B20的驱动只能采用IO的控制来实现读取数据。
1)字符设备的定义
structds18b20_dev{
structcdevcdev;//字符设备结构体
structmutexres_mutex;//互斥锁结构体
};
定义一个结构体用来存放相关变量,有利于提高驱动的扩展性。
与上面结构体不同的地方在于定义了一个mutex变量,主要是因为DS18B20操作过程中有时序的操作,而时序又不能被其他程序所打扰,不然读出的数据是错误的,所以通过