实现Web控制Led灯

基于boa服务器和led驱动实现同网段控制led灯

Posted by Jerry Chen on July 23, 2019

基于内容

进行之前需要完成下列内容:

开始

准备的资源

资源 用途 地址
led_ctl.html 访问的网页文件,用GET方法提交信息到后端 浏览
cgi_led_ctl.c 生成后端cgi程序,从进程环境变量取值调用驱动控制led 浏览

简单的介绍

功能:浏览器访问开发板web服务器,点击网页控件进而改变开发板led状态。

分步:

  • 开发板建立boa服务器 (已完成)
  • 建立led_ctl.html,放在服务器www目录下
    • 建立form(指定提交方法,指定后端程序文件)
    • 在form标签内建立输入控件、提交空间
  • 建立相应的后端程序文件的源文件cgi_led_ctl.c
    • 从环境变量获取提交内容(name1=xxx&name2=xxx)
    • 交叉编译为cgi_led_ctl.cgi,复制到服务器cgi-bin目录下

一些解释:

html表单form中有什么:

<form action="/cgi-bin/cgi_led_ctl.cgi" method="get" target="_blank">...</form>

  • action指定后端处理程序,这里用cgi(通用网关接口),还可以用xxx.php啥的;
  • method指定提交的方式,这里用get,还可以用post;使用get时,跳转url会附加表单信息,形如/cgi-bin/cgi_led_ctl.cgi?name1=value1&name2=value2
  • … 中务必包括“指定name的输入控件”以及“提交控件”。当点击提交控件后,就会发送一个http请求给服务器,然后由后端程序进行处理;
  • target为_blank,指定提交信息后打开新页面进行返回信息。

cgi(Common Gateway Interface)的源码xxx.c中有什么:

  • 手动printf打印网页header部分+空行+body(主体部分),返回给浏览器显示。cgi中标准输入输出被重定向到了http流,可以理解为web是cgi中控制台终端就ok了。
  • 从进程环境变量或者http流(由stdin重定向)获取浏览器提交的信息,然后使用系统编程的方法调用驱动进行控制。

cgi怎么获取提交的数据:

  • 请求是get,数据放在进程环境变量“QUERY_STRING”字段里,格式是name1=value1&name2=value2;get请求只有一包(header+body);
  • 请求是post,数据放在body(主体部分),格式也是name1=value1&name2=value2;不过post请求分为了两包,第一包发header(其中第二包也就是body的长度放在环境变量“CONTENT_LENGTH”),第二包发body(post的信息)。

下面是cgi预处理输入数据的demo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int get_inputs()
{
    int length;
    char *method;
    char *inputstring;

    method = getenv("REQUEST_METHOD"); //将返回结果赋予指针
    if(method == NULL)
        return 1;       //找不到环境变量REQUEST_METHOD
    if(!strcmp(method,"POST")) // POST方法
    {
        length = atoi(getenv("CONTENT_LENGTH")); //结果是字符,需要转换
        if(length != 0)
        {
            inputstring = malloc(sizeof(char)*length + 1); //必须申请缓存,因为stdin不带缓存
            fread(inputstring, sizeof(char), length, stdin); //从标准输入读取一定数据放到缓存
        }
    }
    else if(!strcmp(method,"GET"))
    {
        Inputstring = getenv("QUERY_STRING");   
        length = strlen(inputstring);
    }
    if(length == 0)
        return 0;
}

具体的操作(GET)

注意:移植的最小linux/boa对post的支持好像有点问题,但是ubuntu上boa完美支持post;

  1. ubuntu中新建文件,建议在nfs共享目录

    • led_ctl.html 内容如右 浏览

    • cgi_led_ctl.c 内容如右 浏览 ,然后交叉编译生成cgi_led_ctl.cgi

      1
      
      arm-none-linux-gnueabi-gcc cgi_led_ctl.c -o cgi_led_ctl.cgi -static
      
  2. 开发板复制上述新建的文件到对应目录

    复制建议使用nfs,挂载命令如下:

    1
    
    mount -t nfs 192.168.2.246:/home/nfsroot /mnt/nfs -o nolock
    
    • led_ctl.html复制到/boa/www
    • cgi_led_ctl.cgi复制到/boa/www/cgi-bin
    • 启动服务器/boa/boa
  3. 启动PC浏览器访问192.168.2.200/led_ctl.html

    启动正常如下图:

    在上述表单中勾选led1、led2对应复选框后,然后提交,会打开一个新页出现下面的结果

    下面的图形象解释了发生什么,get一次就会发送一个请求,cgi返回了一个网页信息: