一、实验目的
搭建基于arm开发板的web服务端程序,通过网页控制开发板LED状态
二、boa简介
Boa服务器是一个小巧高效的web服务器,是一个运行于unix或linux下的,支持CGI的、适合于嵌入式系统的单任务的http服务器,源代码开放、性能高。Boa是一种非常小巧的Web服务器,其可执行代码只有大约60KB左右。作为一种单任务Web服务器,Boa只能依次完成用户的请求,而不会fork出新的进程来处理并发连接请求。但Boa支持CGI,能够为CGI程序fork出一个进程来执行。Boa的设计目标是速度和安全。
三、源码下载
下载链接直达:http://www.boa.org/news.html
四、源码编译
# 解压 tar- xvf boa-0.94.14rc21.tar.gz cd boa-0.94.14rc21 # 配置生成makefile ./configure # 修改makefile编译工具:这里选择自己的交叉编译器 vim ./src/Makefile CC = arm-linux-gcc CPP = arm-linux-gcc -E # 编译 make
为了保险期间我们使用file指令查看一下生成的文件是否为arm版本
然后我们开始准备开发板上需要的文件配置
mkdir nuc977 cp src/boa cp src/boa ./nuc977/ cp examples/boa.conf ./nuc977/ cp /etc/mime.types ./nuc977/ touch ./nuc977/group mkdir ./nuc977/www mkdir ./nuc977/www/cgi-bin touch ./nuc977/index.html cd nuc977/
// 如果这里没有example文件夹可以使用“find ./ -name boa.conf”这个命令查找一下源码下conf文件的位置一定有的
然后将这些文件传输到nfs文件夹中
五、开发板配置
mkdir /etc/boa cp /mnt/nuc977/www / -rf cp /mnt/nuc977/boa /etc/boa cp /mnt/nuc977/boa.conf /etc/boa cp /mnt/nuc977/mime.types /etc cp /mnt/nuc977/group /etc cp /mnt/nuc977/index.html /www
然后需要修改我们的etc/boa/box.conf文件内容
Group nogroup 改为Group 0 // 修改nogroup为0 ErrorLog /etc/boa/error_log // 更改路径 AccessLog /etc/boa/access_log // 更改路径 ServerName www.your.org.here // 取消注释 DocumentRoot /www // 修改路径 ScriptAlias /cgi-bin/ /www/cgi-bin/ // 修改路径
修改index.html界面,内容如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>LED控制页面</title> </head> <body> <input type="button" value="开"/> <input type="button" value="关"/> </body> </html>
cd /etc/boa ./boa
然后我们ifconfig查看开发板ip,然后在我们pc端浏览器输入该ip地址查看效果
六、控制led灯实验
方案1
boaapp.c文件
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> void led_on() { char ubuf[2] = {1, 0}; int fd; fd = open("/dev/led",O_RDWR); if(fd < 0) { printf("open runled device error\r\n"); return; } write(fd, ubuf, 1); close(fd); } void led_off() { char ubuf[2] = {0, 0}; int fd; fd = open("/dev/led",O_RDWR); if(fd < 0) { printf("open runled device error\r\n"); return; } write(fd, ubuf, 1); close(fd); } int main(void) { char *data; printf("Content-Type:text/html;charset=gb2312\n\n");//它是一个MIME头信息,它告诉Web服务器随后的输出是以html的形式 printf("<html>\n"); printf("<body>\n"); printf("<title>this is title</title> "); printf("<h3>this is h3</h3> "); data = getenv("QUERY_STRING");//得到客户端发送过来的数据 printf("<p>接受到的数据为:%d</p>",data); if(strcmp(data,"on")) { led_on(); }else if(strcmp(data,"off")) { led_off(); } printf("</body>\n"); printf("</html>\n"); // free(data); return 0; }
编译
arm-linux-gcc boaapp.c -o boaapp.cgi -static
然后我们将编译出来的文件拷贝到开发板的www/cgi-bin文件夹中,然后我们进入浏览器进行访问,然后一直出现错误,经过实验可以得知问题出在函数getenv上(http://192.168.1.3/cgi-bin/boaapp.cgi)
只要把这里注释掉就正常访问了
方案2
下载https://github.com/boutell/cgic
修改cgictest.c
#include"cgic.h" #include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> void led_on() { char ubuf[2] = {1, 0}; int fd; fd = open("/dev/led",O_RDWR); if(fd < 0) { printf("<p align=\"center\">open onled device error<\p>>"); return; } write(fd, ubuf, 1); close(fd); } void led_off() { char ubuf[2] = {0, 0}; int fd; fd = open("/dev/led",O_RDWR); if(fd < 0) { printf("<p align=\"center\">open offled device error<\p>>"); return; } write(fd, ubuf, 1); close(fd); } int cgiMain() { char state[10]; // cgiFormString("led_num", led_num, 10); // 从表单中的led_num字段获取值存入到led_num cgiFormString("state", state, 10);// 从表单中的led_state字段获取值存入到led_state cgiHeaderContentType("text/html"); // 设定输出的内容格式 这里我们要输出HTML fprintf(cgiOut,"<title>LED Test</title>"); fprintf(cgiOut,"<p align=\"center\">recv from arm:</p>"); fprintf(cgiOut,"<form action=\"cgictest.cgi\" align=\"center\">LED_STATE<br><input type=\"text\" name=\"state\" \ value=\"on\"><br><input type=\"submit\" value=\"push\"></form>"); // fprintf(cgiOut,"led_num: %s", led_num); fprintf(cgiOut,"<br> <p align=\"center\">state: %s</p>", state); if(!strcmp(state,"on")) { led_on(); system("echo 1>/dev/led"); }else if(!strcmp(state,"off")) { led_off(); system("echo 0>/dev/led"); } return 0; }
修改makefile:参考
CFLAGS=-g -Wall CC=arm-linux-gcc AR=arm-linux-ar RANLIB=arm-linux-ranlib LIBS=-L./ -lcgic all: libcgic.a cgictest.cgi install: libcgic.a cp libcgic.a /usr/local/lib cp cgic.h /usr/local/include @echo libcgic.a is in /usr/local/lib. cgic.h is in /usr/local/include. libcgic.a: cgic.o cgic.h rm -f libcgic.a $(AR) rc libcgic.a cgic.o $(RANLIB) libcgic.a #mingw32 and cygwin users: replace .cgi with .exe cgictest.cgi: cgictest.o libcgic.a $(CC) cgictest.o -o cgictest.cgi ${LIBS} clean: rm -f *.o *.a cgictest.cgi capture cgicunittest test: $(CC) -D UNIT_TEST=1 cgic.c -o cgicunittest ./cgicunittest
最后目录组成
执行make然后将生成的.cgi文件拷贝到板子的www/cgi-bin目录下然后打开浏览器
最终效果(目前)