信息家電網絡服務器設計
Network Server forInformation Appliance
2016 年 6 月
(
第三章 嵌入式平臺開發環境
3.2 軟件開發環境
第一步 下載VMware在電腦上一鍵安裝,打開虛擬機,在虛擬機中安裝RetHat Linux操作系統,具體步驟如下:參考附圖(一)
第二步 安裝交叉工具鏈
打開VMware裏的RethatLinux系統,在根目錄下新建一個文件夾爲test,把下載的工具鏈通過samba服務器從window傳到Linux系統中的test文件下,然後解壓出來,在進行編譯安裝,具體步驟如下:
1.下載arm-linux-gcc-3.4.1.tar.bz2放在 /usr/local目錄下
2.解壓arm-linux-gcc-3.4.1.tar.bz2
#tar -jxvf arm-linux-gcc-3.4.1.tar.bz2
3.進入該文件夾,將arm文件夾拷貝到/usr/local/下
# cd usr/local/
#cp -rv arm /usr/local/現在交叉編譯程序集都在/usr/local/arm/3.4.1/bin下面了
3.修改環境變量,把交叉編譯器的路徑加入到PATH。修改/etc/bash.bashrc文件 #vim /etc/bash.bashrc
在最後加上:export PATH=$PATH:/usr/local/arm/3.4.1/bin
4.立即使新的環境變量生效,不用重啓電腦:
#source /root/.bashrc
5.檢查是否將路徑加入到PATH:
# echo $PATH 顯示的內容中有/usr/local/arm/bin,說明已經將交叉編譯器的路徑加入PATH。至此,交叉編譯環境安裝完成。
6.測試是否安裝成功
# arm-linux-gcc –v
7.編譯Hello World程序,測試交叉工具鏈
寫下下面的Hello World程序,保存爲hello.c
#include <stdio.h>
intmain()
{
printf("HelloWorld!/n");
return 0;
}
執行下面的命令:
# arm-linux-gcc -o hello hello.c
第四章 嵌入式web服務器的移植與實現
4.3 boa服務器的移植
常見的w嵌入式eb服務器有:boa、 appweb、lighttpd、 shttpd、 mathopd、 minihttpd、 goahead等
1. 從www.boa.org 下載 Boa 服務器的最新版:boa-0.94.13.tar.gz。
2. 解壓:tar xzfboa-0.94.13.tar.gz
3. 進入解壓後的文件夾boa-0.94.13內部的 src文件夾,對源文件進行如下修改
1 由於arm-linux-gcc 編譯器版本過高,對語法的支持有一些改變,所以需要修改compat.h中的
2 #define TIMEZONE_OFFSET(foo) foo##->tm_gmtoff
3 爲:
4
5 #define TIMEZONE_OFFSET(foo) foo->tm_gmtoff
4. 然後生成Makefile:./configure
5. 修改生成的Makefile:默認生成的Makefile針對x86平臺,我們的目標是針對嵌入式平臺,所以需要修改編譯器.
1 更改Makefile的31行和32行:
2 CC = gcc
3 CPP = gcc -E
4 更改爲
5 CC = arm-linux-gcc
6 CPP = arm-linux-gcc –E
6. 在當前目錄下編譯Boa源文件:make
7. 將生成好的boa可執行文件去掉冗餘信息: arm-linux-strip boa.
4.3.2 Boa移植到OK6410中
1 (1) 修改25行的port端口,用來設置服務器監聽的端口:
2 # Port: The port Boa runs on. The default port for http servers is 80.
3 # If it is less than 1024, the server must be started as root.
4
5 Port 80
6 (2) 註釋43行的監聽IP地址:默認監聽該主機上的所有IP地址
7 #Listen 192.68.0.5
8 (3) 修改53、54行的user和Group 啓動的UID和GID,使其以root身份啓動
9 # User: The name or UID the server should run as.
10 # Group: The group name or GID the server should run as.
11
12 User root
13 Group root
14 (4) 修改116行的DocumentRoot地址,即客戶端要顯示的HTML頁面存放位置
15 # DocumentRoot: The root directory of the HTML documents.
16 # Comment out to disable server non user files.
17
18 DocumentRoot /usr/local/boa
19 (5) 修改輸入網頁輸入主機IP時要顯示的頁面:這裏設爲index.html
20 # DirectoryIndex: Name of the file to use as a pre-written HTML
21 # directory index. Please MAKE AND USE THESE FILES. On the
22 # fly creation of directory indexes can be _slow_.
23 # Comment out to always use DirectoryMaker
24
25 DirectoryIndex index.html
26 (6) 修改CGI程序存放的位置:以http://IP/cgi-bin/cginame 的方式運行cgi 程序時將在/usr/local/boa/cgi-bin 目錄下尋找該程序
27 # ScriptAlias: Maps a virtual path to a directory for serving scripts
28 # Example: ScriptAlias /htbin/ /www/htbin/
29
30 ScriptAlias /cgi-bin/ /usr/local/boa/cgi-bin/
2. 將配置文件boa.conf 移動到OK6410的 /etc/boa/ 目錄下。
3. 創建/var/log/boa/ 目錄,這樣Boa服務器啓動時會在該目錄下創建日誌文件。
4. 將Linux系統上/etc/mime.types 文件複製到OK6410的/etc 目錄下,否則Boa服務器啓動不起來。
5. 將生成的boa文件移植到嵌入式板中的/sbin目錄下並更改腳本文件 /etc/init.d/rcS, 新增一行: /sbin/boa ,確保boa服務器隨系統上電自啓動
4.3.3 測試boa服務器
1. 靜態頁面測試:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Boa 靜態網頁測試</title>
</head>
<body>
<h1> Welcome to Boa sever! </h1>
</body>
</html>
2. CGI 程序測試:
#include <stdio.h>
int main()
{
printf("Content-type: text/html\n\n");
printf("<html>\n");
printf("<head>\n");
printf("<title>CGI Output</title>\n");
printf("</head>\n");
printf("<body>");
printf("<h1> Hello, world. </h1>");
printf("</body>");
printf("</html>\n");
return 0;
}
4.4 sqlite數據庫的移植
4.4.1 sqlite的編譯
1.下載sqlite-3.5.6.tar.gz
2.解壓#tarxvfz sqlite-3.5.6.tar.gz
3. #./configure--prefix=/home/user_name/sqlite/sqlite-arm --disable-tcl --host=arm-linux--prefix=/home/sqlite-3.6.18/sqlite-arm-linux/
4.編譯並安裝 #make && make install
6.爲了減小執行文件大小,去掉其中的調試信息#arm-linux-strip sqlite3
4.4.2 sqlite移植到OK6410中
1.將bin目錄下的sqlite3拷貝到根文件系統的bin目錄下。
2.將lib目錄下的.so系列文件和pkgconfig目錄拷貝到根文件系統的usr/lib目錄下
第五章 ARMlinux下實現動態頁面的cgi技術
5.2 登錄實現
Index.html
<html>
<head>
<title></title>
</head>
<bodybackground="./image/bg.jpg">
<br>
<br>
<h1align="center"><font color="red">智能網絡家居系統</font></h1>
<p><center><b><fontsize="5">請登錄</font></b></center></p>
<formalign="cgi-bin/login.cgi"method="post"><center>
用戶名:
<inputtype="text" name="name"><br>
密 碼:
<inputtype="password" name="passwd"><br><br>
<inputtype="submit" value="登錄">
<inputtype="reset" value="重新輸入">
</body>
</html>
Demo.c
#include<stdio.h>
#include<stdlib.h>
intmain()
{
char *str_len=NULL;
int len=0;
char buf[100]="";
char user[20]="";
char passwd[20]="";
printf("%s\r\n\r\n","Content-Type:text/html");
printf("<html>\n<head>\n<title>CGI3:登錄結果</title></head><br>\n");
str_len = getenv("CONTENT_LENGTH");
if((str_len==NULL)||(sscanf(str_len,"%d",&len)!=1)||(len>80))
printf("sorry!error!");
fgets(buf,len+1,stdin);
sscanf(buf,"name=%[^&]&password=%s",user,passwd);
if((strncmp(user,"yugengde",8)==0)&&(strncmp(passwd,"133435",6)==0))
printf("<h1>Welcome!登錄成功!");
else
printf("<h1>Sorry!用戶名或密碼錯誤!");
return 0;
}
Login.c
#include<stdio.h>
#include<stdlib.h>
intmain()
{
char *str_len=NULL;
int len=0;
char buf[100]="";
char user[20]="";
char passwd[20]="";
printf("%s\r\n\r\n","Content-Type:text/html");
printf("<html>\n<head>\n<title>CGI3:登錄結果</title></head><br>\n");
str_len =getevn("CONTENT_LENGTH");
if((str_len==NULL)||(sscanf(str_len,"%d",&len)!=1)||(len>80))
fgets(buf,len+1,stdin);
sscanf(buf,"name=%[^&]&password=%s",user,passwd);
if((strncmp(user,"yugengde",8)==0)&&(strncmp(passwd,"133435",6)==0))
{
printf("<scriptlanguage=\"JavaScript\">self.location="main.cgi";</script>");
}
else
printf("<h1>Sorry!用戶名或密碼錯誤");
returnn 0;
}
5.3 主控制界面
Main.c
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include"leds.h"
#include"adc.h"
#include"18b20.h"
voidconfig(int *led_config,int led_num);
intmain()
{
int led_num = 0 ;
int adc_data = 0 ;
float tmp_temp ;
unsigned short tmp_data ;
int led_config[8] = {0 , 0 , 0 , 0} ;
FILE *fp_html ;
char bur[512] = "" ;
char *len ;
printf("%s\r\n\r\n" ,"Content-Type: text/html") ;
len = getenv(" CONTENT_LENGTH") ;
if( len != NULL)
{
unsigned int content_len = 0 ;
char *data ;
content_len = atoi(len) ;
data = malloc(content_len + 1) ;
read(0 , data , content_len) ;
sscanf(data , "led%d" ,&led_num) ;
free(data) ;
}
else
{
led_num = 0 ;
}
config(led_config , led_num) ;
led_fun(led_config) ;
if((fp_html = fopen("main_html", "r")) == NULL)
{
exit(1) ;
}
while(fgets(buf , 512 , fp_html))
{
if(strncmp(buf ,"$FLAG1S" , 7) == 0)
{
tmp_data = ds18b20_fun() ;
tmp_temp = tmp_data *0.0625 ;
tmp_data = tmp_temp * 10 +0.5 ;
if(tmp_data < 1000)
printf(" %2d . \n" , tmp_data/10 ,tmp_data%10) ;
else
printf("  85.0 \n") ;
}
else if(strncmp(buf ,"$FLAG2S" , 7) == 0)
{
adc_data = adc_fun(0) ;
printf(" nbsp;nbsp;nbsp;%2d %\n" , adc_data/11) ;
}
else if(strncmp(buf ,"$FLAG3S" , 7)
{
adc_data = adc_fun(1) ;
printf(" nbsp;nbsp;nbsp;nbsp;%2d %\n" , adc_data/11) ;
}
else if(strncmp(buf ,"$FLAG4S" , 7)
{
int i = 0 ;
for(i = 0 ; i < 4 ; i++)
{
if(led_config[i] ==0)
{
printf("<imgsrc = \" ../image/off.png\"width = 30 height = 30 hspace =45">") ;
}
else
{
printf("<imgsrc = \" ../image/on.png\"width = 30 height = 30 hspace =45">") ;
}
}
}
else
printf("%s" ,buf) ;
}
return 0 ;
}
voidconfig(int *led_config , int led_num)
{
FILE *fp ;
if( (fp = fopen("config.ini" ,"r+")) == NULL )
{
printf("<p> fopen error! <a href = \"/cgi-bin/main.cgi\">Return /a>") ;
exit(1) ;
}
fscanf(fp , "led1 = %d , led2 = %d,led3 = %d , led4 = %d " , led_config , led_config+1 , led_config+2 ,led_config+3) ;
if(led_num > 0)
{
if(led_config[led_num - 1] == 1)
{
led_config[led_num - 1] = 0;
}
else
{
led_config[led_num - 1] = 1;
}
fseek(fp , 7 * (led_num - 1) + 5 ,SEEK_SET) ;
fprintf(fp , "%d" ,led_config[led_num - 1]) ;
}
fclose(fp) ;
}
HTML界面:
Main_html
<script>
functionAddDataPost(sUserId,sUserName)
{
var obj = newActiveXObject("Microsoft.XMLHTTP");
sUserId = escape(sUserId);
sUserName = escape(sUserName);
var userInfo ="userid="+sUserId+"&username="+sUserName;
obj.open("POST","getData.asp",false);
obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
obj.send(userInfo);
return unescape(obj.responeText);
}
functionshow()
{
var data = new Date();
var now = "";
now = data.getFullYear()+"";
now = now +(data.getMonth()+1)+"";
now = now +(data.getData()+1)+"";
now = now +(data.getHours()+1)+"";
now = now +(data.getMinutes()+1)+"";
now = now + (data.getSeconds()+1)+"";
document.getElementById("nowDiv").innerHTML= now;
setTimeout("show()",1000);
}
</scropt>
<html>
<head>
<title>智能網絡家電主頁</title>
</head>
<body bgcolor="silver">
<center>
<h2 align=center><fontcolor=blue><body onload="show()">
<div in="nowDiv"></div></h2></font>
</body>
<br>
<h1align="center"><font color="crimson">智能網絡家居系統</h1>
<br><br><br>
<FORM METHOD="post">
<p><fontcolor="red"><h2 align=center>溫 度
$FLAG1S</h2><b>
<p><fontcolor="red"><h2 align=center>溼 度
$FLAG2S</h2><b>
<br><br><br>
<input type="submit"name="view" value="">
</FORM>
<br></b>
<h1align="center"><font color="orangered">電燈控制</h1>
<br>
<FORM METHOD="post">
$FLAG3S
<br>
<input type="submit"name="led1" value="led1">
<input type="submit"name="led2" value="led2">
<input type="submit"name="led3" value="led3">
<input type="submit"name="led4" value="led4">
<br>
</html>
Led燈的配置文件
Config.ini
led1=0,led2=1,led3=0,led4=1
顯示結果如下: