资源描述
. . . .
linux嵌入式系统期末作业
选题: AD远程数据采集试验
学号:
姓名:
班级:
邮箱:
成绩:
2011年11月29日
目录
1、源代码···········································2
2、程序完成的主要功能·······························8
3、必要的操作步骤···································8
4、执行程序的结果···································11
5、本门课程体会与建议·······························12
1、 源代码
index.html文件解析:
<html>
<head>
<title>AD远程采集实验</title> //第一页网页标题
</head>
<body bgcolor="cyan">//设置网页背景颜色
<h1 align="center">AD远程采集实验</h1>
<p align="center">2008-12-11</p>
<form action="192.168.1.133/cgi-bin/run.cgi">/*提交表单后跳转到192.168.1.133/cgi-bin/run.cgi 页面*/
<p align="center"><input type="submit" value="查看"></p> /*设置按钮并且居中*/
</form>
</body>
</html>
adc.html文件解析:
<html>
<head>
<script type="text/javascript">
var XMLdoc;
function loadXML()
{
if(window.ActiveXObject) //判断浏览器是否支持activeX控件
{
XMLdoc = new ActiveXObject("Microsoft.XMLDOM");/*生成一个xml dom对象*/
XMLdoc.async = false; //设置对象属性,是否同步
XMLdoc.load("adc.xml");//使oDom对象指向adc.xml中的容
getmessage();
}
setTimeout("loadXML()", 1000); //每1000毫秒刷新一次
}
function getmessage()
{
document.getElementById("ch_0").innerHTML
= XMLdoc.getElementsByTagName("ch_0")[0].childNodes[0].nodeValue; /*获取ch_0的HTML代码*/
document.getElementById("ch_1").innerHTML
= XMLdoc.getElementsByTagName("ch_1")[0].childNodes[0].nodeValue; /*获取ch_1的HTML代码*/
document.getElementById("ch_2").innerHTML
= XMLdoc.getElementsByTagName("ch_2")[0].childNodes[0].nodeValue; /*获取ch_2的HTML代码*/
}
</script>
</head>
//生成第二个页面
<body onload="loadXML()" bgcolor="cyan">
<h1 align="center">AD远程测试实验</h1>
<form align="center">
<table width="50%" border="1" align="center">
<th align="center" colspan=2>AD远程测试实验</th>
<tr>
<td align="center">通道0</td>
<td align="center"><span id="ch_0"></span>V</td>
</tr>
<tr>
<td align="center">通道1</td>
<td align="center"><span id="ch_1"></span>V</td>
</tr>
<tr>
<td align="center">通道2</td>
<td align="center"><span id="ch_2"></span>V</td>
</tr>
</table>
</form>
<form action="192.168.1.133/cgi-bin/stop.cgi">
<p align="center"><input type="submit" value="停止采集"/></p>
</form>
</body>
</html>
Adc.xml文件代码解析:
<?xml version="1.0" encoding="UTF-8"?>
<measure>
<ch_0>0.0</ch_0>
<ch_1>1.0</ch_1>
<ch_2>3.0</ch_2>
<stop>A</stop>
</measure>
run.c文件代码解析:
//服务器后台程序对AD进行采样的程序
#include <stdio.h>//调用函数库中的标准输入输出
#include <fcntl.h>//浮点数处理
#include <sys/ioctl.h>
#include <unistd.h>
#include <time.h>
void getdata(char *buff, int adcfd, int ret)
/*读取并且转换三个通道中的AD值*/
{
int temp;
int i=0, j;
for(j=0; j<3; j++)//控制三个通道的循环
{
ioctl(adcfd, j, 0);//操作I/O通道
read(adcfd, &temp, sizeof(int));
temp += 16;
temp = temp/31;
for(; i<ret; i++)
{
if((buff[i] == '<') && (buff[i+1] == 'c') && (buff[i+2] == 'h'))
break;
}
buff[i+6] = (temp/10) + 48; //将得到的值做数值转换
buff[i+8] = (temp%10) + 48;
i++;
}
}
void lock_set(int fd, int type)
{
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = type;
while(1)
{
if((fcntl(fd, F_SETLK, &lock)) == 0)
return;
}
}
int main(void)
{
pid_t pc;
int adcfd, xmlfd, ret;
unsigned char buff[150];
int i;
pc = fork();
/*用于打印一些HTML代码,使页面跳转到ADC.HTML,打印完后退出 */
if(pc<0)
{
printf("fork error!\n");
return -1;
}
else if(pc>0)
{
/*打印Html文档*/
printf("Content-type:text/html\n\n");
printf("<body bgcolor=\"cyan\">\n");
printf("<meta -equiv=\"refresh\"content=\"1;url=192.168.1.133/adc.html\">");
printf("</body>");
exit(0);
}
else
{
setsid();//脱离父进程
chdir("/");//改变当前目录
umask(0); //重设文件权限掩码
for(i=0;i<65535;i++) //关闭设备文件描述符
close(i);
adcfd = open("/dev/adc", O_RDWR);
if(adcfd < 0)
{
printf("Cannot open adc device!\n");
return adcfd;
}
while(1)
{
while(1)
{
xmlfd = open("/var//adc.xml", O_RDWR); //打开标志文件
if(xmlfd<0)
{
continue;
}
else
{
lock_set(xmlfd, F_WRLCK);/*给文件上锁,避免其他进程对该文件进行写操作*/
break;
}
}
ret = read(xmlfd, buff, 150);
for(i=0; i<ret; i++)
if(buff[i] == '$')/*如果用户按下“停止采集”键,则退出程序*/
{
buff[i] = 'A';
lseek(xmlfd, 0, SEEK_SET); //移动文件指针
write(xmlfd, buff, ret);//写入修改后的值
lock_set(xmlfd, F_UNLCK);//给文件上锁,防止被删除
close(xmlfd);
close(adcfd);
return 0;
}
getdata(buff, adcfd, ret);
lseek(xmlfd, 0, SEEK_SET);
write(xmlfd, buff, ret);
lock_set(xmlfd, F_UNLCK);
close(xmlfd);
sleep(1);
}
close(xmlfd);
close(adcfd);
return 0;
}
}
stop.c文件代码解析:
/*这段代码是控制整个程序完毕的代码,当程序检测到“$”时,程序完毕*/
#include <stdio.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <fcntl.h>
void lock_set(int fd, int type)
{
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
lock.l_type = type;
while(1)
{
if((fcntl(fd, F_SETLK, &lock)) == 0)
return;
}
}
int main(void)
{
int fd, ret;
char buff[150];
int i;
/*打印HTML页面*/
printf("Content-type:text/html\n\n");
printf("<body bgcolor=\"cyan\">\n");
printf("<meta -equiv=\"refresh\" content=\"1;url=192.168.1.133\">\n");
printf("</body>");//隔1秒钟后刷新
while(1)
{
fd = open("../adc.xml", O_RDWR); //打开标志文件
if(fd<0)
continue;
else
{
lock_set(fd, F_WRLCK);/*给文件上锁,避免其他进程对该文件进行写操作*/
break;
}
}
ret = read(fd, buff, 150);
for(i=0; i<ret; i++)
if((buff[i] == 's') && (buff[i+1] == 't') && (buff[i+2] == 'o') && (buff[i+3] == 'p'))
break;
buff[i+5] = '$'; //i+5插入一个$
lseek(fd, 0, SEEK_SET);
write(fd, buff, ret); /*写文件,改变文件容,以便视频采集程序能检测到该变化*/
lock_set(fd, F_UNLCK);
close(fd); // 关闭设备文件描述符
return 0;
}
2、 程序完成的主要功能:
这个程序是在点击第一个页面(index.html)上的“查看”按钮后,程序会创建两个线程:一个主线程,用于打印一些HTML代码,使页面跳转到adc.html页面去,打印完HTML信息后该线程就退出;另一个子线程执行真正的AD数据采集,它读取三个通道的AD值,并对读出来的值进行转换,并将读取的结果写入adc.xml文件中,供用户检索。同时,这个线程还会检查adc.xml的<stop>标签中的容,如果为’$’,则说明用户按下了“停止采集”按钮,那么就完毕程序,否则继续执行。
3、 必要的操作步骤:
一、 解压ar zxvf boa-0.94.13.tar.gz
yqliu29up-tech:~/app/web$ tar zxvf boa-0.94.13.tar.gz
二、 然后进入源代码目录:
yqliu29up-tech:~/app/web$ cd boa-0.94.13/src/
三、 修改文件compat.h的第120行:
yqliu29up-tech:~/app/web/boa-0.94.13/src$ vi compat.h
四、 修改后,第120行的容如下:
#define TIMEZONE_OFFSET(foo) foo->tm_gmtoff
五、 即只是去掉了该行的两个’##’字符。
然后修改boa.c:
yqliu29up-tech:~/app/web/boa-0.94.13/src$ vi boa.c
六、 找到该文件的225~227行,注释掉这几行,不然运行的时候会出错。
源文件的修改就完成了,现在开始编译。
首先,运行configure程序对源文件进行配置:
yqliu29up-tech:~/app/web/boa-0.94.13/src$ ./configure
七、 配置完成后,修改Makefile:
yqliu29up-tech:~/app/web/boa-0.94.13/src$ vi Makefile
八、 修改第31行和32行如下:
CC = arm-linux-gcc
CPP = arm-linux-gcc -E
九、 修改完成后,保存文件,运行Make进行编译:
yqliu29up-tech:~/app/web/boa-0.94.13/src$ make
十、 编译完成后,会在该目录下生成我们需要的可执行文件boa。
然后,编译我们的CGI程序。CGI程序供两个,一个是run.c,另一个是stop.c,
分别运行如下命令进行编译:yqliu29up-tech:~/app/web$ arm-linux-gcc -o run.cgi run.c
yqliu29up-tech:~/app/web$ arm-linux-gcc -o stop.cgi stop.c
编译完成后,会在目录下生成run.cgi和stop.cgi两个应用程序。
Boa运行时需要在/etc/boa目录下有一个boa.conf文件,该文件的全部容如下:
Port 80
#Listen 192.68.0.5
User root
Group 0
ErrorLog /var/log/boa/error_log
AccessLog /dev/null
ServerName .your.org.here
DocumentRoot /var/
DirectoryIndex index.html
KeepAliveMax 1000
KeepAliveTimeout 10
MimeTypes /etc/mime.types
DefaultType text/plain
CGIPath /bin:/usr/bin:/usr/local/bin
AddType application/x- d-cgi cgi
ScriptAlias /cgi-bin/ /var//cgi-bin/
另外,在/etc目录下还需要一个mime.types文件,可以直接从主机上的/etc目录拷贝过来。
运行时需要的目录如下:
/var/ 这个是我们的html文件存放的目录
/var//cgi-bin 这个是CGI程序存放的目录
/var/log/boa/error_log 这个是boa服务器存放错误日志的地方
因此,把我们上面提到的index.html、adc.html和adc.xml三个文件拷贝到开发板的/var/www目录下;把刚才编译得到的run.cgi和stop.cgi拷贝到/var//sgi-bin目录下;还要在/var/log/boa目录下建立一个error_log文件,命令如下:
[rootup-tech /var/log/boa]pwd
/var/log/boa
[rootup-tech /var/log/boa]touch error_log
这样,服务器的配置就完成了,把刚才编译得到的boa可执行文件拷贝到/bin目录下,然后执行boa命令,就可以启动boa服务器了:
[rootup-tech /var/log/boa]boa
启动后,在PC机的IE浏览器中输入开发板的IP地址,打开页面。
4、 执行程序的结果(效果图):
图一:
图二:
5、 本门课程体会与建议:
12 / 13
展开阅读全文