ESP32 html升级

文章目录


前言

前提:需要先设置好分区表,下载固件到设定的分区空间中,此文升级不开启http文件服务器,使用webserver进行直接升级。

一、创建web_server.c

#include <include.h>


static const char *TAG = "example";

/* html转成文本*/
const char head_char[]="<!DOCTYPE html>\
<html>\
  <head>\
    <meta charset=\"UTF-8\">\
	<style type=\"text/css\">\
	li {list-style: none;}\
	a {text-decoration: none;color: #444444;display: block;}\
	a:hover {color: white;}\
	ul {width: 1100px;height: 40px;background-color: #e7e7e2;margin: 40px auto;}\
	ul > li {float: left;height: 40px;line-height: 40px;width:150px;text-align: center;}\
	ul > li:hover {background-color: #403f40;}\
	form {width: 800px;margin: 40px auto;}\
	</style>\
</head>\
  <body>\
<script type=\"text/javascript\">   \
    function post(url, params) {\
        var temp = document.createElement(\"form\");\
        temp.action = url;\
        temp.method = \"post\";\
        temp.style.display = \"none\";\
        for (var x in params) {\
            var opt = document.createElement(\"textarea\");\
            opt.name = x;\
            opt.value = params[x];\
            temp.appendChild(opt);\
        }\
        document.body.appendChild(temp);\
        temp.submit();\
        return temp;\
    }\
</script>\
    <ul>\
      <li><a onclick=\"javascript:post('/index', {id:1,name:'index'})\">主页</a></li>\
	  <li><a onclick=\"javascript:post('/update', {id:6,name:'update'})\">固件升级</a></li>\
    </ul>";
const char tail_char[]="</body></html>";

void index_send(httpd_req_t *req)
{
    httpd_resp_send_chunk(req, head_char, strlen(head_char));
    httpd_resp_send_chunk(req, tail_char, strlen(tail_char));
}



const char update_html_char[]="<form method='POST' action='/update' enctype='multipart/form-data' id='upload_form'>\
   <input type='file' name='update' accept='.bin,.BIN'>\
   <input type='submit' value='Update'>\
   <div id='prg'>progress: 0%</div>\
</form>\
<script>\
	$('form').submit(function(e){\
		e.preventDefault();\
		var form = $('#upload_form')[0];\
		var data = new FormData(form);\
		$.ajax({\
			url: '/update',\
			type: 'POST',\
			data: data,\
			contentType:false,\
			processData:false,\
			xhr: function() {\
				var xhr = new window.XMLHttpRequest();\
				xhr.upload.addEventListener('progress', function(evt) {\
				if (evt.lengthComputable) {\
				var per = evt.loaded / evt.total;\
				$('#prg').html('progress: ' + Math.round(per*100) + '%');\
				}\
				}, false);\
				return xhr;\
			},\
			success:function(d, s) {\
				console.log('success!')\
			},\
			error: function (a, b, c) {\
			}\
		});\
	});\
 </script>;";

void update_send(httpd_req_t *req)
{
    httpd_resp_send_chunk(req, head_char, strlen(head_char));
    httpd_resp_send_chunk(req, update_html_char, strlen(update_html_char));
    httpd_resp_send_chunk(req, tail_char, strlen(tail_char));
}
/* An HTTP GET handler */
static esp_err_t hello_get_handler(httpd_req_t *req)
{
    char*  buf;
    size_t buf_len;
    /* Read URL query string length and allocate memory for length + 1,
     * extra byte for null termination */
    buf_len = httpd_req_get_url_query_len(req) + 1;
    if (buf_len > 1) {
        buf = malloc(buf_len);
        if (httpd_req_get_url_query_str(req, buf, buf_len) == ESP_OK) {
            ESP_LOGI(TAG, "Found URL query => %s", buf);
            char param[32];
            /* Get value of expected key from query string */
            if (httpd_query_key_value(buf, "query1", param, sizeof(param)) == ESP_OK) {
                ESP_LOGI(TAG, "Found URL query parameter => query1=%s", param);
            }
            if (httpd_query_key_value(buf, "query3", param, sizeof(param)) == ESP_OK) {
                ESP_LOGI(TAG, "Found URL query parameter => query3=%s", param);
            }
            if (httpd_query_key_value(buf, "query2", param, sizeof(param)) == ESP_OK) {
                ESP_LOGI(TAG, "Found URL query parameter => query2=%s", param);
            }
        }
        free(buf);
    }
    index_send(req);
    return ESP_OK;
}

static const httpd_uri_t hello = {
    .uri       = "/",
    .method    = HTTP_GET,
    .handler   = hello_get_handler,
    /* Let's pass response string in user
     * context to demonstrate it's usage */
    .user_ctx  = NULL
};

/* An HTTP POST handler */
static esp_err_t index_post_handler(httpd_req_t *req)
{
    char buf[1024];
    int ret, remaining = req->content_len;

    while (remaining > 0) {
        /* Read the data for the request */
        if ((ret = httpd_req_recv(req, buf,
                        MIN(remaining, sizeof(buf)))) <= 0) {
            if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
                /* Retry receiving if timeout occurred */
                continue;
            }
            return ESP_FAIL;
        }

        /* Send back the same data */
        // httpd_resp_send_chunk(req, buf, ret);
        remaining -= ret;

        /* Log data received */
        ESP_LOGI(TAG, "=========== RECEIVED DATA ==========");
        ESP_LOGI(TAG, "%.*s", ret, buf);
        ESP_LOGI(TAG, "====================================");
    }
    index_send(req);

    // End response
    httpd_resp_send_chunk(req, NULL, 0);
    return ESP_OK;
}
static const httpd_uri_t index_post = {
    .uri       = "/index",
    .method    = HTTP_POST,
    .handler   = index_post_handler,
    .user_ctx  = NULL,
};


int strpos(char *str,int strlen) 
{
	int i=0;
	for(i=0;i<strlen;i++) 
	{
		if(str[i] == 0xe9)	
		{
				if(str[i+1] == 0x06)	
				{
					return i;
				}
		}
	}
	return -1;
}

void datancpy(char *drc,char *src,int len)
{
    for(int i=0;i<len;i++)
    {
        drc[i] = src[i];
    }
}

//异常处理,连接http服务器失败等异常
static void __attribute__((noreturn))  task_fatal_error()
{
    ESP_LOGE("ota", "Exiting task due to fatal error...");
    
    xEventGroupSetBits(tcp_mqtt_ntp_event_group,TASK_BIT_2);
    // if((xEventGroupGetBits(tcp_mqtt_ntp_event_group) & 0x01))
    // {
    //     led_mode_int = Led_mode_normal;//切换LED灯状态
    // }
    // else
    // {
    //     led_mode_int = Led_mode_network_fail;//切换LED灯状态
    // }
    sys_sta.sys_ota_update_flag=0;
}

static void infinite_loop(void)
{
    int i = 0;
    ESP_LOGI("ota", "When a new firmware is available on the server, press the reset button to download it");
    while(1) {
        ESP_LOGI("ota", "Waiting for a new firmware ... %d", ++i);
        vTaskDelay(2000 / portTICK_PERIOD_MS);
    }
}

/* An HTTP POST handler */
static esp_err_t update_post_handler(httpd_req_t *req)
{
    char buf[1024];
    int ret, remaining = req->content_len;     
    int start_recv=0;
    bool recv_head=0;
    char * fir_addr;
    int i=0; 

    esp_err_t err;
    /* update handle : set by esp_ota_begin(), must be freed via esp_ota_end() */
    esp_ota_handle_t update_handle = 0;
    const esp_partition_t *update_partition = NULL;
    int binary_file_length = 0;
    bool image_header_was_checked = false;    
    ESP_LOGI("ota", "Starting OTA example");
    unsigned int par_addr=0;

    while (remaining > 0) {
        if(start_recv==0)
        {
            if ((ret = httpd_req_recv(req, buf, MIN(remaining, 149) )) <= 0) {
                if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
                    /* Retry receiving if timeout occurred */
                    continue;
                }
                return ESP_FAIL;
            }
            if(((fir_addr=strstr(buf,"name="))!=NULL) && ((fir_addr=strstr(buf,"filename="))!=NULL)  )
            {
                start_recv=1;
                // ESP_LOGI(TAG, "=========== RECEIVED DATA =1=========\n");
                // for(i=0;i<ret;i++)
                // {
                //     printf("%02x ",buf[i]);
                // }
                // ESP_LOGI(TAG, "====================================\n");
            }
            remaining -= ret;
        }
        else if(start_recv==1)  //开始接收固件
        {
            const esp_partition_t *configured = esp_ota_get_boot_partition();
            const esp_partition_t *running = esp_ota_get_running_partition();

            if (configured != running) {
                ESP_LOGI("ota", "Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",
                        configured->address, running->address);
            }
            ESP_LOGI("ota", "Running partition type %d subtype %d (offset 0x%08x)",running->type, running->subtype, running->address);

            update_partition = esp_ota_get_next_update_partition(NULL);
            assert(update_partition != NULL);

            while(remaining > 0)
            {
                if ((ret = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)) )) <= 0) {
                    if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
                        /* Retry receiving if timeout occurred */
                        continue;
                    }
                    return ESP_FAIL;
                }
                sys_sta.sys_ota_update_flag=1;
                remaining -= ret;
                // ESP_LOGI(TAG, "=========== RECEIVED DATA =2====addr=%05X=====\n",par_addr);
                // for(i=0;i<ret;i++)
                // {
                //     printf("%02x ",buf[i]);
                // }
                // ESP_LOGI(TAG, "====================================\n");

                if(recv_head == 0)  //还未收到固件头
                {
                    int recv_head_addr = strpos(buf,ret);  //查找固件头首位置
                    if(recv_head_addr < 0)
                    {
                        httpd_resp_send_chunk(req, "升级失败  ", 13);
                        update_send(req);
                        return false;
                    }
                    else
                    {
                        char recv_head_buf[1024]={0};
                        datancpy(recv_head_buf,buf+recv_head_addr,(ret-recv_head_addr));               
                        recv_head=1;
                        memset(buf,0,1024);
                        datancpy(buf,recv_head_buf,(ret-recv_head_addr));
                        ret =ret-recv_head_addr  ;
                    }
                }
                int data_read = ret;
                
                if (data_read < 0) 
                {
                    ESP_LOGE("ota", "Error: SSL data read error");
                    task_fatal_error();
                } 
                else if (data_read > 0) 
                {
                    if (image_header_was_checked == false) 
                    {
                        esp_app_desc_t new_app_info;
                        if (data_read > sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t)) 
                        {
                            // check current version with downloading
                            memcpy(&new_app_info, &buf[sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t)], sizeof(esp_app_desc_t));
                            ESP_LOGI("ota", "New firmware version: %s", new_app_info.version);

                            esp_app_desc_t running_app_info;
                            if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) 
                            {
                                ESP_LOGI("ota", "Running firmware version: %s", running_app_info.version);
                            }

                            const esp_partition_t* last_invalid_app = esp_ota_get_last_invalid_partition();
                            esp_app_desc_t invalid_app_info;
                            if (esp_ota_get_partition_description(last_invalid_app, &invalid_app_info) == ESP_OK)
                            {
                                ESP_LOGI("ota", "Last invalid firmware version: %s", invalid_app_info.version);
                            }

                            // check current version with last invalid partition
                            if (last_invalid_app != NULL)
                            {
                                if (memcmp(invalid_app_info.version, new_app_info.version, sizeof(new_app_info.version)) == 0) 
                                {
                                    ESP_LOGI("ota", "New version is the same as invalid version.");
                                    ESP_LOGI("ota", "Previously, there was an attempt to launch the firmware with %s version, but it failed.", invalid_app_info.version);
                                    ESP_LOGI("ota", "The firmware has been rolled back to the previous version.");
                                    infinite_loop();
                                }
                            }
                            image_header_was_checked = true;
                            err = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
                            if (err != ESP_OK) 
                            {
                                ESP_LOGE("ota", "esp_ota_begin failed (%s)", esp_err_to_name(err));
                                esp_ota_abort(update_handle);
                                task_fatal_error();
                            }
                        }
                        else 
                        {
                            ESP_LOGE("ota", "received package is not fit len");
                            esp_ota_abort(update_handle);
                            task_fatal_error();
                        }
                    }
                    debug_print("esp_ota_write\r\n");
                    err = esp_ota_write( update_handle, (const void *)buf, data_read);
                    if (err != ESP_OK) {
                        esp_ota_abort(update_handle);
                        task_fatal_error();
                    }
                    binary_file_length += data_read;
                    ESP_LOGI("ota", "Written image length %d", binary_file_length);

                    
                }
                else if (data_read == 0) 
                {
                    if (errno == ECONNRESET || errno == ENOTCONN) {
                        ESP_LOGE("ota", "Connection closed, errno = %d", errno);
                        break;
                    }
                    if(remaining<=0)
                    {
                        debug_print("remaining =0 \n");
                    }
                }
            }
            ESP_LOGI("ota", "Total Write binary data length: %d", binary_file_length);

            err = esp_ota_end(update_handle);
            if (err != ESP_OK) {
                if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
                    ESP_LOGE("ota", "Image validation failed, image is corrupted");
                }
                ESP_LOGE("ota", "esp_ota_end failed (%s)!", esp_err_to_name(err));
                task_fatal_error();
            }

            err = esp_ota_set_boot_partition(update_partition);
            if (err != ESP_OK) {
                ESP_LOGE("ota", "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err));
                task_fatal_error();
            }
        //    ESP_LOGI("ota", "Prepare to restart system!");
            other_info.mode = NORMAL_MODE; //长按进入配置 模式
            other_info_write(); //写入flash  
            ss_delay_ms(1000);
            httpd_resp_send_chunk(req, "  升级 OK   ", 13);
            update_send(req);
            
            ss_delay_ms(10);
            esp_restart();
        }
        else
        {
            if ((ret = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)) )) <= 0) {
                if (ret == HTTPD_SOCK_ERR_TIMEOUT) {
                    /* Retry receiving if timeout occurred */
                    continue;
                }
                return ESP_FAIL;
            }
            ESP_LOGI(TAG, "=========== RECEIVED DATA =3=========\n");
            for(i=0;i<ret;i++)
            {
                printf("%02x ",buf[i]);
            }
            ESP_LOGI(TAG, "====================================\n");
            remaining -= ret;
        }       
    }
    start_recv=0;
    update_send(req);
    // End response
    httpd_resp_send_chunk(req, NULL, 0);
    return ESP_OK;
}



static const httpd_uri_t update_post = {
    .uri       = "/update",
    .method    = HTTP_POST,
    .handler   = update_post_handler,
    .user_ctx  = NULL,
};


esp_err_t http_404_error_handler(httpd_req_t *req, httpd_err_code_t err)
{
    if (strcmp("/", req->uri) == 0) {
        httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/hello URI is not available");
        /* Return ESP_OK to keep underlying socket open */
        return ESP_OK;
    } else if (strcmp("/index", req->uri) == 0) {
        httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/index URI is not available");
        /* Return ESP_FAIL to close underlying socket */
        return ESP_FAIL;
    }else if (strcmp("/update", req->uri) == 0) {
        httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "/update URI is not available");
        /* Return ESP_FAIL to close underlying socket */
        return ESP_FAIL;
    }
    /* For any other URI send 404 and close socket */
    httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "Some 404 error message");
    return ESP_FAIL;
}


#define HTTPD_BASE_CONFIG() {                        \
        .task_priority      = tskIDLE_PRIORITY+5,       \
        .stack_size         = 10240,                     \
        .core_id            = tskNO_AFFINITY,           \
        .server_port        = 80,                       \
        .ctrl_port          = 32768,                    \
        .max_open_sockets   = 7,                        \
        .max_uri_handlers   = 8,                        \
        .max_resp_headers   = 8,                        \
        .backlog_conn       = 5,                        \
        .lru_purge_enable   = false,                    \
        .recv_wait_timeout  = 5,                        \
        .send_wait_timeout  = 5,                        \
        .global_user_ctx = NULL,                        \
        .global_user_ctx_free_fn = NULL,                \
        .global_transport_ctx = NULL,                   \
        .global_transport_ctx_free_fn = NULL,           \
        .open_fn = NULL,                                \
        .close_fn = NULL,                               \
        .uri_match_fn = NULL                            \
}

static httpd_handle_t start_webserver(void)
{
    httpd_handle_t server = NULL;
    httpd_config_t config = HTTPD_BASE_CONFIG();
    config.lru_purge_enable = true;

    // Start the httpd server
    ESP_LOGI(TAG, "Starting server on port: '%d'", config.server_port);
    if (httpd_start(&server, &config) == ESP_OK) {
        // Set URI handlers
        ESP_LOGI(TAG, "Registering URI handlers");
        httpd_register_uri_handler(server, &hello);
        httpd_register_uri_handler(server, &index_post);
        httpd_register_uri_handler(server, &update_post);
        return server;
    }

    ESP_LOGI(TAG, "Error starting server!");
    return NULL;
}

static void stop_webserver(httpd_handle_t server)
{
    // Stop the httpd server
    httpd_stop(server);
}

static void disconnect_handler(void* arg, esp_event_base_t event_base,
                               int32_t event_id, void* event_data)
{
    httpd_handle_t* server = (httpd_handle_t*) arg;
    if (*server) {
        ESP_LOGI(TAG, "Stopping webserver");
        stop_webserver(*server);
        *server = NULL;
    }
}

static void connect_handler(void* arg, esp_event_base_t event_base,
                            int32_t event_id, void* event_data)
{
    httpd_handle_t* server = (httpd_handle_t*) arg;
    if (*server == NULL) {
        ESP_LOGI(TAG, "Starting webserver");
        *server = start_webserver();
    }
}


void init_webserver(void)
{
    static httpd_handle_t server = NULL;
    /* Register event handlers to stop the server when Wi-Fi or Ethernet is disconnected,
     * and re-start it upon connection.
     */
#ifdef CONFIG_EXAMPLE_CONNECT_WIFI
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &connect_handler, &server));
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_WIFI
#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &connect_handler, &server));
    ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_DISCONNECTED, &disconnect_handler, &server));
#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET

    /* Start the server for the first time */
    server = start_webserver();
}

二、创建web_server.h

#ifndef WEB_SERVICE_H
#define WEB_SERVICE_H

extern void init_webserver(void);

#endif /* WEB_SERVICE_H */

三、wifi,nvs函数调用

void nvs_data_init()
{
    //打印系统信息
    ESP_LOGI("ESP32","[APP] Startup..\n");
    ESP_LOGI("ESP32","[APP] Free memory: %d bytes\n", esp_get_free_heap_size());
    ESP_LOGI("ESP32","[APP] IDF version: %s\n", esp_get_idf_version());
    //初始化NVS,如果失败则先擦除再初始化
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        // NVS partition was truncated and needs to be erased
        // Retry nvs_flash_init
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }  
    ESP_ERROR_CHECK( err );
}



/*
 *  wifi_config.h
 *
 *  Created on: 2022年8月24日
 *  Author: wst
 */

#include "include.h"

#include "esp_wifi.h"
#include "lwip/sys.h"
//#include "WiFi.h"
/*
 *
 *  WIFI  AP  模式
 * 
 */

#define EXAMPLE_MAX_STA_CONN       4  //最大连接数量


static void wifi_event_handler(void* arg, esp_event_base_t event_base,
                                    int32_t event_id, void* event_data)
{
//    debug_print(" wifi ap event_id = %d \n",event_id);
    if (event_id == WIFI_EVENT_AP_STACONNECTED) 
    {
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI("wifi_AP", "station "MACSTR" join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    } 
    else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) 
    {
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI("wifi_AP", "station "MACSTR" leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
}
 
/*
 *  函数:开启wifi ap模式
 *  参数:
 *      ap_ssid:wifi 名
 *      ap_pwd :wifi 密码
 *      ap_channel: wifi通道  1-13
 */


void wifi_init_softap(char *softap_ssid,char *ap_pwd,unsigned char ap_channel)
{
    esp_netif_ip_info_t netif_soft_ap_ip = {   //注意:ip和gw必须一致,否则会出现频繁掉线
            .ip = { .addr = ESP_IP4TOADDR(192,168,10,251) },
            .gw = { .addr = ESP_IP4TOADDR(192,168,10,251) },
            .netmask = { .addr = ESP_IP4TOADDR(255,255,255,0) },
    };

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    //create customized access point
    esp_netif_inherent_config_t esp_netif_config2 = ESP_NETIF_INHERENT_DEFAULT_WIFI_AP();
    esp_netif_config2.if_desc = "jala wifi ap";
    esp_netif_config2.route_prio = 10;
    esp_netif_config2.ip_info = &netif_soft_ap_ip;
    esp_netif_create_wifi(WIFI_IF_AP, &esp_netif_config2);

    esp_wifi_set_default_wifi_ap_handlers();

    wifi_init_config_t cfg2 = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg2));

    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,
                                                        &wifi_event_handler,NULL,NULL));
    wifi_config_t wifi_config = {
        .ap = {
//            .ssid = softap_ssid,
            .ssid_len = strlen(softap_ssid),
            .channel = ap_channel,
//            .password = ap_pwd,
            .max_connection = EXAMPLE_MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA2_PSK,
        },
    };
    strcpy((char*)wifi_config.ap.ssid,softap_ssid);
    strcpy((char*)wifi_config.ap.password,ap_pwd);
    if (strlen(ap_pwd) == 0) {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }
    
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI("ap", "wifi_init_softap finished. SSID:%s password:%s channel:%d",
             softap_ssid, ap_pwd, ap_channel);
}

void  wifi_start()
{
        wifi_init_softap("jala_wst",(char *)"",2);
}

四、main函数调用

void app_main(void)
{
    wifi_start();//启动wifi
    init_webserver();//开启http
    nvs_data_init();
    while(1)
    {
        vTaskDelay(1000/ portTICK_PERIOD_MS);
    }

}

总结

web_server.c 和web_server.h生成文件后,加载到工程中直接调用就可以了

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值