http_server: The example adds a new function about file saving to SDcard

pull/5682/merge
Cao Sen Miao 2020-07-28 18:38:21 +08:00
rodzic 60fb1a6ef3
commit 4065872a88
4 zmienionych plików z 188 dodań i 2 usunięć

Wyświetl plik

@ -2,6 +2,8 @@
(See the README.md file in the upper level 'examples' directory for more information about examples.)
If the SD card option is enabled, you can access files in the SD card by the path `/sdcard`
HTTP file server example demonstrates file serving with both upload and download capability, using the `esp_http_server` component of ESP-IDF. The following URIs are provided by the server:
| URI | Method | Description |
@ -38,6 +40,12 @@ File server implementation can be found under `main/file_server.c` which uses SP
2. download the uploaded copy back : `curl 192.168.43.130:80/path/on/device/myfile_copy.html > myfile_copy.html`
3. compare the copy with the original using `cmp myfile.html myfile_copy.html`
* To write to SD card, you need to:
1. Select the `Mount the SD card to the filesystem` in the configuration menu (by calling `idf.py menuconfig` and select the `EXAMPLE_MOUNT_SD_CARD` option.
2. If you need to format the card while the card fails to be mounted, enable the config option `The card will be formatted if mount has failed` (`EXAMPLE_FORMAT_SDCARD_IF_MOUNT_FAILED`). Be careful, all the data in the card will disappear.
Note: You will have to access the SD card by SPI bus with sdspi driver, if you are using ESP32S2.
## Note
Browsers often send large header fields when an HTML form is submit. Therefore, for the purpose of this example, `HTTPD_MAX_REQ_HDR_LEN` has been increased to 1024 in `sdkconfig.defaults`. User can adjust this value as per their requirement, keeping in mind the memory constraint of the hardware in use.

Wyświetl plik

@ -0,0 +1,24 @@
menu "Http_File_Serving Example menu"
config EXAMPLE_MOUNT_SD_CARD
bool "Mount the SD card to the filesystem"
default n
help
If this config item is set, the file you upload to server can be chosen to save in the SDcard.
config EXAMPLE_FORMAT_IF_MOUNT_SDCARD_FAILED
bool "The card will be formatted if mount has failed."
default n
depends on EXAMPLE_MOUNT_SD_CARD
help
If this config item is set, the card will be formatted if mount has failed.
config EXAMPLE_USE_SDMMC_HOST
bool "Use SDMMC host"
default y
depends on EXAMPLE_MOUNT_SD_CARD && IDF_TARGET_ESP32
help
If this config item is set, SDMMC is used to mount the SDcard.
Otherwise, will use SPI host to access and mount the SDcard.
endmenu

Wyświetl plik

@ -7,22 +7,67 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <sys/param.h>
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_spiffs.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_err.h"
#include "esp_vfs_fat.h"
#include "nvs_flash.h"
#include "protocol_examples_common.h"
#include "sdkconfig.h"
#include "driver/sdspi_host.h"
#include "driver/spi_common.h"
#include "sdmmc_cmd.h"
#include "soc/soc_caps.h"
#if SOC_SDMMC_HOST_SUPPORTED
#include "driver/sdmmc_host.h"
#endif
/* This example demonstrates how to create file server
* using esp_http_server. This file has only startup code.
* Look in file_server.c for the implementation */
#define MOUNT_POINT "/sdcard"
static const char *TAG="example";
/* ESP32-S2 doesn't have an SD Host peripheral, always use SPI,
* ESP32 can choose SPI or SDMMC Host, SPI is used by default: */
#ifndef CONFIG_EXAMPLE_USE_SDMMC_HOST
#define USE_SPI_MODE
#endif
// on ESP32-S2, DMA channel must be the same as host id
#ifdef CONFIG_IDF_TARGET_ESP32S2
#define SPI_DMA_CHAN host.slot
#endif //CONFIG_IDF_TARGET_ESP32S2
// DMA channel to be used by the SPI peripheral
#ifdef CONFIG_IDF_TARGET_ESP32
#define SPI_DMA_CHAN 1
#endif //SPI_DMA_CHAN
// When testing SD and SPI modes, keep in mind that once the card has been
// initialized in SPI mode, it can not be reinitialized in SD mode without
// toggling power to the card.
#ifdef CONFIG_EXAMPLE_MOUNT_SD_CARD
static sdmmc_card_t* mount_card = NULL;
static char * mount_base_path = MOUNT_POINT;
#endif
#ifdef USE_SPI_MODE
// Pin mapping when using SPI mode.
// With this mapping, SD card can be used both in SPI and 1-line SD mode.
// Note that a pull-up on CS line is required in SD mode.
#define PIN_NUM_MISO 2
#define PIN_NUM_MOSI 15
#define PIN_NUM_CLK 14
#define PIN_NUM_CS 13
#endif //USE_SPI_MODE
/* Function to initialize SPIFFS */
static esp_err_t init_spiffs(void)
@ -63,9 +108,110 @@ static esp_err_t init_spiffs(void)
* Implementation of this function is to be found in
* file_server.c */
esp_err_t start_file_server(const char *base_path);
#ifdef CONFIG_EXAMPLE_MOUNT_SD_CARD
void sdcard_mount(void)
{
/*sd_card part code*/
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_EXAMPLE_FORMAT_IF_MOUNT_FAILED
.format_if_mount_failed = true,
#else
.format_if_mount_failed = false,
#endif // EXAMPLE_FORMAT_IF_MOUNT_FAILED
.max_files = 5,
.allocation_unit_size = 16 * 1024
};
sdmmc_card_t* card;
const char mount_point[] = MOUNT_POINT;
ESP_LOGI(TAG, "Initializing SD card");
#ifndef USE_SPI_MODE
ESP_LOGI(TAG, "Using SDMMC peripheral");
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// To use 1-line SD mode, uncomment the following line:
// slot_config.width = 1;
// GPIOs 15, 2, 4, 12, 13 should have external 10k pull-ups.
// Internal pull-ups are not sufficient. However, enabling internal pull-ups
// does make a difference some boards, so we do that here.
gpio_set_pull_mode(15, GPIO_PULLUP_ONLY); // CMD, needed in 4- and 1- line modes
gpio_set_pull_mode(2, GPIO_PULLUP_ONLY); // D0, needed in 4- and 1-line modes
gpio_set_pull_mode(4, GPIO_PULLUP_ONLY); // D1, needed in 4-line mode only
gpio_set_pull_mode(12, GPIO_PULLUP_ONLY); // D2, needed in 4-line mode only
gpio_set_pull_mode(13, GPIO_PULLUP_ONLY); // D3, needed in 4- and 1-line modes
esp_err_t ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config, &card);
#else
ESP_LOGI(TAG, "Using SPI peripheral");
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
spi_bus_config_t bus_cfg = {
.mosi_io_num = PIN_NUM_MOSI,
.miso_io_num = PIN_NUM_MISO,
.sclk_io_num = PIN_NUM_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
esp_err_t ret = spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize bus.");
ESP_ERROR_CHECK(ret);
}
// This initializes the slot without card detect (CD) and write protect (WP) signals.
// Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = PIN_NUM_CS;
slot_config.host_id = host.slot;
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
mount_card = card;
#endif //USE_SPI_MODE
if(ret != ESP_OK){
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
} else {
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
}
ESP_ERROR_CHECK(ret);
}
sdmmc_card_print_info(stdout, card);
}
#endif
static esp_err_t unmount_card(const char* base_path, sdmmc_card_t* card)
{
#ifdef USE_SPI_MODE
esp_err_t err = esp_vfs_fat_sdcard_unmount(base_path, card);
#else
esp_err_t err = esp_vfs_fat_sdmmc_unmount();
#endif
ESP_ERROR_CHECK(err);
#ifdef USE_SPI_MODE
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
err = spi_bus_free(host.slot);
#endif
ESP_ERROR_CHECK(err);
return err;
}
void app_main(void)
{
/*Mount the SDcard first if needed.*/
#ifdef CONFIG_EXAMPLE_MOUNT_SD_CARD
sdcard_mount();
#endif
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
@ -81,4 +227,9 @@ void app_main(void)
/* Start the file server */
ESP_ERROR_CHECK(start_file_server("/spiffs"));
#ifdef CONFIG_EXAMPLE_MOUNT_SD_CARD
//deinitialize the bus after all devices are removed
ESP_ERROR_CHECK(unmount_card(mount_base_path, mount_card));
#endif
}

Wyświetl plik

@ -0,0 +1,3 @@
CONFIG_EXAMPLE_MOUNT_SD_CARD=y
CONFIG_EXAMPLE_FORMAT_IF_MOUNT_SDCARD_FAILED=y
CONFIG_EXAMPLE_USE_SDMMC_HOST=y