嵌入式技术论坛
直播中

申根换

8年用户 1681经验值
私信 关注
[经验]

RT-Thread使用webserver的步骤

STM32F407,rt-thead studio版本版本:2.2.6 .3。
以RT-Thread中Lan8720和lwip协议栈的使用文章创建的工程为基础。
在rtthread工程中新建文件夹webserver,存放webserver相关封装文件。
编译,正常通过。
需要修改的代码,过程如下:


rt-threadcomponentsnetlwip-2.0.2srcincludelwipappshttpd_opts.h 文件中的宏定义


LWIP_HTTPD_CGI默认为0,修改为1
LWIP_HTTPD_SSI默认为0,改为1
HTTPD_USE_CUSTOM_FSDATA默认为0
LWIP_HTTPD_DYNAMIC_FILE_READ默认为0,改为1
将 rt-threadcomponentsnetlwip-2.0.2srcappshttpd 文件夹 添加结构
httpd文件夹下的fsdata.c排除结构。
在主机数中增加如下代码


extern void httpd_init(void);
httpd_init();
  while (count++)
  {
          LOG_D("Hello RT-Thread!");
          rt_thread_mdelay(10000);
  }
编译正常,下载到开发板,效果如图1:
2.jpg

如何使用自己的网页呢?修改如下:
将rt-threadcomponentsnetlwip-2.0.2srcappshttpd文件夹下的fsdata.c替换自己的fsdata.c,(使用makefsdata.exe这个软件自动生成即可)。
在webserve文件夹下创建httpd_cgi_ssi.c文件(CGI和SSI句柄数)
参考以下代码,如下所示

#include
#include "lwip/tcp.h"
#include
#include
#include
int LED1=0;
int BEEP=0;
#define NUM_CONFIG_CGI_URIS (sizeof(ppcURLs) / sizeof(tCGI))
#define NUM_CONFIG_SSI_TAGS (sizeof(ppcTAGs) / sizeof(char *))
//extern short Get_Temprate(void);
//extern void RTC_Get_time(u8 *hour,u8 *min,u8 *sec,u8 *ampm);
//extern void RTC_Get_Date(u8 *year,u8 *month,u8 *date,u8 *week);
//控制LED的CGI handler
const char* LEDS_CGI_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]);
const char* BEEP_CGI_Handler(int iIndex,int iNumParams,char *pcParam[],char *pcValue[]);
static const char *ppcTAGs[]=  //SSI的Tag
{
    "t", //ADC值
    "w", //温度值
    "h", //时间
    "y"  //日期
};
static const tCGI ppcURLs[]= //cgi程序
{
    {"/leds.cgi",LEDS_CGI_Handler},
    {"/beep.cgi",BEEP_CGI_Handler},
};
//当web客户端请求浏览器的时候,使用此函数被CGI handler调用
static int FindCGIParameter(const char *pcToFind,char *pcParam[],int iNumParams)
{
    int iLoop;
    for(iLoop = 0;iLoop < iNumParams;iLoop ++ )
    {
        if(strcmp(pcToFind,pcParam[iLoop]) == 0)
        {
            return (iLoop); //返回 iLOOP
        }
    }
    return (-1);
}
//SSIHandlerÖ中adc处理函数
void ADC_Handler(char *pcInsert)
{
    char Digit1=0, Digit2=0, Digit3=0, Digit4=0;
    static uint32_t ADCVal = 0;
     //ADCVal = Get_Adc_Average(5,10);//ADC1_CH5的电压值
    ADCVal+=10;
    ADCVal=ADCVal%3000;
     //转换为 ADCVval * 0.8mv
     ADCVal = (uint32_t)(ADCVal * 0.8);
     Digit1= ADCVal/1000;
     Digit2= (ADCVal-(Digit1*1000))/100 ;
     Digit3= (ADCVal-((Digit1*1000)+(Digit2*100)))/10;
     Digit4= ADCVal -((Digit1*1000)+(Digit2*100)+ (Digit3*10));
     /* 准备添加到html中的数据 */
     *pcInsert       = (char)(Digit1+0x30);
     *(pcInsert + 1) = (char)(Digit2+0x30);
     *(pcInsert + 2) = (char)(Digit3+0x30);
     *(pcInsert + 3) = (char)(Digit4+0x30);
}
//SSIHandler中需要用到的内部处理温度传感器
void Temperate_Handler(char *pcInsert)
{
    char Digit1=0, Digit2=0, Digit3=0, Digit4=0,Digit5=0;
    static short Temperate = 0;
    //Temperate = Get_Temprate();
    Temperate+=1.3;
    Digit1 = Temperate / 10000;
    Digit2 = (Temperate % 10000)/1000;
    Digit3 = (Temperate % 1000)/100 ;
    Digit4 = (Temperate % 100)/10;
    Digit5 = Temperate % 10;
    /* 准备添加到html中的数据 */
    *pcInsert       = (char)(Digit1+0x30);
    *(pcInsert+1) = (char)(Digit2+0x30);
    *(pcInsert+2)   =   (char)(Digit3+0x30);
    *(pcInsert+3) = '.';
    *(pcInsert+4) = (char)(Digit4+0x30);
    *(pcInsert+5) = (char)(Digit5+0x30);
}
//SSIHandler中需要用到的处理RTC日时间的函数
void RTCTime_Handler(char *pcInsert)
{
    static uint8_t  hour,min,sec,ampm;
    hour++;
    min++;
    sec++;
    ampm++;
    //RTC_Get_Time(&hour,&min,&sec,&m);
    /* 准备添加到html中的数据 */
    *pcInsert =         (char)((hour/10) + 0x30);
    *(pcInsert+1) = (char)((hour%10) + 0x30);
    *(pcInsert+2) = ':';
    *(pcInsert+3) = (char)((min/10) + 0x30);
    *(pcInsert+4) = (char)((min%10) + 0x30);
    *(pcInsert+5) = ':';
    *(pcInsert+6) = (char)((sec/10) + 0x30);
    *(pcInsert+7) = (char)((sec%10) + 0x30);
}
//SSIHandler中需要用到的处理RTC日期的函数
void RTCdate_Handler(char *pcInsert)
{
    static uint8_t year,month,date,week;
    //RTC_Get_Date(&year,&month,&date,&week);
    year++;
    month++;
    date++;
    week++;
    /* 准备添加到html中的数据 */
    *pcInsert = '2';
    *(pcInsert+1) = '0';
    *(pcInsert+2) = (char)((year/10) + 0x30);
    *(pcInsert+3) = (char)((year%10) + 0x30);
    *(pcInsert+4) = '-';
    *(pcInsert+5) = (char)((month/10) + 0x30);
    *(pcInsert+6) = (char)((month%10) + 0x30);
    *(pcInsert+7) = '-';
    *(pcInsert+8) = (char)((date/10) + 0x30);
    *(pcInsert+9) = (char)((date%10) + 0x30);
    *(pcInsert+10) = ' ';
    *(pcInsert+11) = 'w';
    *(pcInsert+12) = 'e';
    *(pcInsert+13) = 'e';
    *(pcInsert+14) = 'k';
    *(pcInsert+15) = ':';
    *(pcInsert+16) = (char)(week + 0x30);
}
//SSI的 Handler 句柄
static u16_t SSIHandler(int iIndex,char *pcInsert,int iInsertLen)
{
    switch(iIndex)
    {
        case 0:
                ADC_Handler(pcInsert);
                break;
        case 1:
                Temperate_Handler(pcInsert);
                break;
        case 2:
                RTCTime_Handler(pcInsert);
                break;
        case 3:
                RTCdate_Handler(pcInsert);
                break;
    }
    return strlen(pcInsert);
}
//CGI LED控制句柄
const char* LEDS_CGI_Handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
{
    uint8_t i=0;  //注意根据自己的GET的参数的多少来选择i值范围
    iIndex = FindCGIParameter("LED1",pcParam,iNumParams);  //找到LED的索引号
    //只有一个CGI句柄 iIndex=0
    if (iIndex != -1)
    {
        LED1=1;
        for (i=0; i         {
          if (strcmp(pcParam , "LED1")==0)  //检查参数"led"
          {
            if(strcmp(pcValue, "LED1ON") ==0)
            {
                LED1=0;
                rt_kprintf("LED1ONn");
            }
            else if(strcmp(pcValue,"LED1OFF") == 0)
            {
                LED1=1;
                rt_kprintf("LED1OFFn");
            }
          }
        }
     }
    if(LED1 == 0 && BEEP == 0)      return "/STM32F407LED_ON_BEEP_OFF.shtml";   //
    else if(LED1 == 0 && BEEP == 1) return "/STM32F407LED_ON_BEEP_ON.shtml";    //
    else if(LED1 == 1 && BEEP == 1) return "/STM32F407LED_OFF_BEEP_ON.shtml";   //
    else return "/STM32F407LED_OFF_BEEP_OFF.shtml";                             //
}
//BEEP的CGI控制句柄
const char *BEEP_CGI_Handler(int iIndex,int iNumParams,char *pcParam[],char *pcValue[])
{
    uint8_t i=0;
    iIndex = FindCGIParameter("BEEP",pcParam,iNumParams);  //找到BEEP的索引号
    if(iIndex != -1) //找到BEEP的索引号
    {
        BEEP=0;  //
        for(i = 0;i < iNumParams;i++)
        {
            if(strcmp(pcParam,"BEEP") == 0)  //
            {
                if(strcmp(pcValue,"BEEPON") == 0) //
                {
                    BEEP = 1;
                    rt_kprintf("BEEPONn");
                }
                else if(strcmp(pcValue,"BEEPOFF") == 0) //
                {
                    BEEP = 0;
                    rt_kprintf("BEEPOFFn");
                }
            }
        }
    }
    if(LED1 == 0 && BEEP == 0)      return "/STM32F407LED_ON_BEEP_OFF.shtml";   //
    else if(LED1 == 0 && BEEP == 1) return "/STM32F407LED_ON_BEEP_ON.shtml";    //
    else if(LED1 == 1 && BEEP == 1) return "/STM32F407LED_OFF_BEEP_ON.shtml";   //
    else return "/STM32F407LED_OFF_BEEP_OFF.shtml";   //
}
//SSI句柄初始化
void httpd_ssi_init(void)
{  
    //配置内部温度传感器的SSI句柄
    http_set_ssi_handler(SSIHandler,ppcTAGs,NUM_CONFIG_SSI_TAGS);
}
//CGI句柄初始化
void httpd_cgi_init(void)
{
  //配置CGI句柄 LEDs control CGI) */
  http_set_cgi_handlers(ppcURLs, NUM_CONFIG_CGI_URIS);
}
主机数中代号如下:

    extern void httpd_ssi_init(void);
    extern void httpd_cgi_init(void);
    extern void httpd_init(void);
    httpd_cgi_init();
    httpd_ssi_init();
    httpd_init();
重新编译,下载到开发板,在浏览器输入开发板ip地址,查看效果。效果如图2:
2.jpg



原作者:YZRD

更多回帖

×
20
完善资料,
赚取积分