Skocz do zawartości

esp32s3 zabezpieczenie zapisu pamięci USB pendrive


Pomocna odpowiedź

Ja bym zapisywał do dwóch plików na przemian i po udanym zapisie kasował stary plik (albo i nie kasował, jak dwa nie przeszkadzają).
Wtedy jest pewność, że zginie co najwyżej ostatni zapis.

A w sumie najlepsze by było jakieś mechaniczne zabezpieczenie. Jakaś klapka, co jak jej nie podniesiessz to nie wyjmiesz pena, a jak podniesiesz to daje sygnał do mcu że zaraz ktoś będzie pena wyjmował i trzeba szybko kończyć zapis i nie próbować następnego.

 

Na pewno jakiś dodatkowy system zabezpieczeń będę musiał zrobić. I tak jakiś minimalny interfejs musi powstać no bo w jaki sposób w takim urządzeniu ustawić aktualny czas? Na pewno na płycie znajdzie się RTC z podtrzymaniem, do nastaw czasu wykorzystam BT aby po sparowaniu pobrał aktualną godzinę i datę to takie minimum. Przy okazji zabaw z pendrive chyba spróbuję też zrobić funkcję aktualizacji firmware z niego, mam na to pomysł. Póki co zaczynam działać z zapisem logów w wersji podstawowej - buforowanej tak jak @ethanak podpowiedział

(edytowany)
5 minut temu, ethanak napisał:

A jaki problem ustawić?

Żaden, nie pisałem o problemach. Wspomniałem że trzeba to jakoś zrobić przy minimalnym nakładzie czasu pracy
 

 

31 minut temu, _LM_ napisał:

Na pewno na płycie znajdzie się RTC z podtrzymaniem, do nastaw czasu wykorzystam BT aby po sparowaniu pobrał aktualną godzinę i datę to takie minimum

 

Edytowano przez _LM_
(edytowany)

Testowo zostawiłem logger włączony na noc, zebrał około 1MiB danych wstępnie każdy odczyt od razu ląduje na pendrive. Co sekundę otwieram plik dodaję dane i zamykam. 

Edytowano przez _LM_
(edytowany)

Domyślnie będzie tak jak w postach wyżej pisaliśmy. To tylko testy, później zrobię buforowanie do ram, z resztą teraz i tak zbiera tylko temperaturę z mcu, także nie jest tego wiele 

Edytowano przez _LM_

Jasne - ważne że działa. Ja bym testowo jeszcze nie zamykał pliku tylko dał flush (o ile to możliwe) i sprawdził co się wtedy stanie jak wyjmiesz pena (szczerze mówiąc sam jestem ciekaw).

(edytowany)

Dokładnie. Jak zareaguje apka na esp i co się znajdzie na penie.

Ogólnie najlepiej by było żeby wyjąć pena w trakcie zapisu, ale to chyba niewykonalne...

Edytowano przez ethanak

Można zrobić sztuczkę: dowalić jakiś wielki bufor, ładować go cyklicznie na pena i curug z pamięcią. Przetestuję w wolnych chwilach 

(edytowany)

Ok dzisiaj trochę potestowałem wrzucanie całego bufora do pendriva. Do tego celu dostosowałem przykład os espressif, wrzucam cały kod z maina bo niema tego dużo.

/*
 * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <dirent.h>
#include <inttypes.h>
#include "esp_private/freertos_idf_additions_priv.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_timer.h"
#include "esp_err.h"
#include "esp_log.h"
#include "usb/usb_host.h"
#include "usb/msc_host.h"
#include "usb/msc_host_vfs.h"
#include "ffconf.h"
#include "errno.h"
#include "driver/gpio.h"
#include "esp_mac.h"
#include "driver/temperature_sensor.h"

static const char *TAG = "example";
#define MNT_PATH         "/usb"     // Path in the Virtual File System, where the USB flash drive is going to be mounted
#define APP_QUIT_PIN     GPIO_NUM_0 // BOOT button on most boards
#define BUFFER_SIZE      4096 * 4      // The read/write performance can be improved with larger buffer for the cost of RAM, 4kB is enough for most usecases


char makeSpecyficDir[32];
char filePathBuf[128];

TaskHandle_t logTask;
time_t now;
struct tm timeinfo;



const char LoremIpsum[] = 
{
	"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium\
	, totam rem aperiam eaque ipsa,\
	 quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.\
	  Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit,\
	   sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt,\
	    neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur,\
	     adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem.\
	      Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,\
	       nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit,\
	        qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat,\
	         quo voluptas nulla pariatur? [33] At vero eos et accusamus et iusto odio dignissimos ducimus, \
	         qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, \
	         obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, \
	         id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio.\
	          Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id,\
	           quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.\
	            Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet,\
	             ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus,\
	              ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.\n"
};



static esp_err_t createFilePath(char * buf)
{
	
	int len = 0;
	if(buf == NULL)
	{
		
		return ESP_FAIL;
	}
	
	uint8_t chipid[6];
   	esp_efuse_mac_get_default(chipid);
	char strftime_buf[64];
	strftime(strftime_buf, sizeof(strftime_buf), "%d%m%Y_%H%M%S", &timeinfo);
	len = sprintf(buf,"%s/LOG_%02X%02X%02X%02X%02X%02X_%s.txt",makeSpecyficDir,chipid[0], chipid[1], chipid[2], chipid[3], chipid[4], chipid[5],strftime_buf);
	
	ESP_LOGW(TAG,"len:  %d", len);
	
	return ESP_OK;
}



static void logtask(void * arg)
{


	
temperature_sensor_handle_t temp_handle = NULL;
temperature_sensor_config_t temp_sensor_config = TEMPERATURE_SENSOR_CONFIG_DEFAULT(20, 50);
ESP_ERROR_CHECK(temperature_sensor_install(&temp_sensor_config, &temp_handle));	
// Enable temperature sensor
ESP_ERROR_CHECK(temperature_sensor_enable(temp_handle));	
	
	

int bufCount = 0;


char strftime_buf[64];
	
	
	while(1)
	{
time(&now);
// Set timezone to China Standard Time
setenv("TZ", "CST+0", 1);		
tzset();		
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%d%m%Y_%H%M", &timeinfo);
//strftime(strftime_buf, sizeof(strftime_buf), "%x_%I:%M%p", &timeinfo);


// Get converted sensor data
//float tsens_out;
//temperature_sensor_get_celsius(temp_handle, &tsens_out);

//ESP_LOGW(TAG, "Czas: %s temp: %2.0f°C", strftime_buf,tsens_out);

 FILE *f = fopen(filePathBuf, "a");
       
        if (f == NULL) {
            ESP_LOGE(TAG, "Failed to open file for writing");
            //return;
        }else{
        
//        char dBuf[128] = {0};
//        
//        sprintf(dBuf,"Czas: %s temp: %2.0f°C\n", strftime_buf,tsens_out);
        ESP_LOGW(TAG,"Start written No: %d\n", bufCount);
        fprintf(f, "%d.\n	%s",bufCount, LoremIpsum);
        vTaskDelay(500);
        fclose(f);
    bufCount++;
		}
		vTaskDelay(10);
	}
}



/**
 * @brief Application Queue and its messages ID
 */
static QueueHandle_t app_queue;
typedef struct {
    enum {
        APP_QUIT,                // Signals request to exit the application
        APP_DEVICE_CONNECTED,    // USB device connect event
        APP_DEVICE_DISCONNECTED, // USB device disconnect event
    } id;
    union {
        uint8_t new_dev_address; // Address of new USB device for APP_DEVICE_CONNECTED event if
    } data;
} app_message_t;

/**
 * @brief BOOT button pressed callback
 *
 * Signal application to exit the main task
 *
 * @param[in] arg Unused
 */
static void gpio_cb(void *arg)
{
    BaseType_t xTaskWoken = pdFALSE;
    app_message_t message = {
        .id = APP_QUIT,
    };

    if (app_queue) {
        xQueueSendFromISR(app_queue, &message, &xTaskWoken);
    }

    if (xTaskWoken == pdTRUE) {
        portYIELD_FROM_ISR();
    }
}

/**
 * @brief MSC driver callback
 *
 * Signal device connection/disconnection to the main task
 *
 * @param[in] event MSC event
 * @param[in] arg   MSC event data
 */
static void msc_event_cb(const msc_host_event_t *event, void *arg)
{
    if (event->event == MSC_DEVICE_CONNECTED) {
        ESP_LOGI(TAG, "MSC device connected");
        app_message_t message = {
            .id = APP_DEVICE_CONNECTED,
            .data.new_dev_address = event->device.address,
        };
        xQueueSend(app_queue, &message, portMAX_DELAY);
    } else if (event->event == MSC_DEVICE_DISCONNECTED) {
        ESP_LOGI(TAG, "MSC device disconnected");
        app_message_t message = {
            .id = APP_DEVICE_DISCONNECTED,
        };
        xQueueSend(app_queue, &message, portMAX_DELAY);
    }
}



static void file_operations(void)
{

    struct stat s = {0};


bool  directory_exists = stat(makeSpecyficDir, &s)==0;
    
    if (!directory_exists) {
        if (mkdir(makeSpecyficDir, 0775) != 0) {
            ESP_LOGE(TAG, "mkdir failed with errno: %s", strerror(errno));
        }
    }
    
           
        createFilePath(filePathBuf);
        
        printf("%s\n",filePathBuf);
    // Create /usb/esp/test.txt file, if it doesn't exist
    if (stat(filePathBuf, &s) != 0) {
        ESP_LOGW(TAG, "Creating file");

     if(logTask == NULL){   
        xTaskCreate(logtask, "logTask", 4096, NULL,2, &logTask);
        }else{
		vTaskResume(logTask);
		}	

    }
}



/**
 * @brief USB task
 *
 * Install USB Host Library and MSC driver.
 * Handle USB Host Library events
 *
 * @param[in] args Unused
 */
static void usb_task(void *args)
{
    const usb_host_config_t host_config = { .intr_flags = ESP_INTR_FLAG_LEVEL1 };
    ESP_ERROR_CHECK(usb_host_install(&host_config));

    const msc_host_driver_config_t msc_config = {
        .create_backround_task = true,
        .task_priority = 5,
        .stack_size = 4096,
      //  .stack_size = 4096 * 4,
        .callback = msc_event_cb,
    };
    ESP_ERROR_CHECK(msc_host_install(&msc_config));

    bool has_clients = true;
    while (true) {
        uint32_t event_flags;
        usb_host_lib_handle_events(portMAX_DELAY, &event_flags);

        // Release devices once all clients has deregistered
        if (event_flags & USB_HOST_LIB_EVENT_FLAGS_NO_CLIENTS) {
            has_clients = false;
            if (usb_host_device_free_all() == ESP_OK) {
                break;
            };
        }
        if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE && !has_clients) {
            break;
        }
    }

    vTaskDelay(10); // Give clients some time to uninstall
    ESP_LOGI(TAG, "Deinitializing USB");
    ESP_ERROR_CHECK(usb_host_uninstall());
    vTaskDelete(NULL);
}

void app_main(void)
{
    // Create FreeRTOS primitives
     
   uint8_t chipid[6];
   esp_efuse_mac_get_default(chipid);

    sprintf(makeSpecyficDir,"/usb/LOGGER_%02X%02X%02X%02X%02X%02X",chipid[0], chipid[1], chipid[2], chipid[3], chipid[4], chipid[5]);
    
    app_queue = xQueueCreate(5, sizeof(app_message_t));
    assert(app_queue);

    BaseType_t task_created = xTaskCreate(usb_task, "usb_task", 4096, NULL, 2, NULL);
    assert(task_created);

    // Init BOOT button: Pressing the button simulates app request to exit
    // It will disconnect the USB device and uninstall the MSC driver and USB Host Lib
    const gpio_config_t input_pin = {
        .pin_bit_mask = BIT64(APP_QUIT_PIN),
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = GPIO_PULLUP_ENABLE,
        .intr_type = GPIO_INTR_NEGEDGE,
    };
    ESP_ERROR_CHECK(gpio_config(&input_pin));
    ESP_ERROR_CHECK(gpio_install_isr_service(ESP_INTR_FLAG_LEVEL1));
    ESP_ERROR_CHECK(gpio_isr_handler_add(APP_QUIT_PIN, gpio_cb, NULL));

    ESP_LOGI(TAG, "Waiting for USB flash drive to be connected");
    msc_host_device_handle_t msc_device = NULL;
    msc_host_vfs_handle_t vfs_handle = NULL;


// Disable the temperature sensor if it is not needed and save the power
//ESP_ERROR_CHECK(temperature_sensor_disable(temp_handle));



    // Perform all example operations in a loop to allow USB reconnections
    while (1) {
        app_message_t msg;
        xQueueReceive(app_queue, &msg, portMAX_DELAY);

        if (msg.id == APP_DEVICE_CONNECTED) {
            // 1. MSC flash drive connected. Open it and map it to Virtual File System
            ESP_ERROR_CHECK(msc_host_install_device(msg.data.new_dev_address, &msc_device));
            const esp_vfs_fat_mount_config_t mount_config = {
                .format_if_mount_failed = false,
                .max_files = 3,
                .allocation_unit_size = 8192,
            };
            ESP_ERROR_CHECK(msc_host_vfs_register(msc_device, MNT_PATH, &mount_config, &vfs_handle));

            // 2. Print information about the connected disk
      /*
            msc_host_device_info_t info;
            ESP_ERROR_CHECK(msc_host_get_device_info(msc_device, &info));
            msc_host_print_descriptors(msc_device);
            print_device_info(&info);
		*/
            // 3. List all the files in root directory
            ESP_LOGI(TAG, "ls command output:");
            struct dirent *d;
            DIR *dh = opendir(MNT_PATH);
            assert(dh);
            while ((d = readdir(dh)) != NULL) {
                printf("DIR %s\n", d->d_name);
            }
            closedir(dh);

            // 4. The disk is mounted to Virtual File System, perform some basic demo file operation
            file_operations();
            // 5. Perform speed test
       //     speed_test();

            ESP_LOGI(TAG, "Example finished, you can disconnect the USB flash drive");
        }
        
        /* ********  */
        
        if ((msg.id == APP_DEVICE_DISCONNECTED) || (msg.id == APP_QUIT)) {
            
           	ESP_LOGE(TAG, "Disconnect?");
            vTaskSuspend(logTask);
            if (vfs_handle) {
                ESP_ERROR_CHECK(msc_host_vfs_unregister(vfs_handle));
                vfs_handle = NULL;
            }
            if (msc_device) {
                ESP_ERROR_CHECK(msc_host_uninstall_device(msc_device));
                msc_device = NULL;
            }
            if (msg.id == APP_QUIT) {
                // This will cause the usb_task to exit
                ESP_ERROR_CHECK(msc_host_uninstall());
                break;
            }
        }
    }

    ESP_LOGI(TAG, "Done");
    gpio_isr_handler_remove(APP_QUIT_PIN);
    vQueueDelete(app_queue);
}

Poniżej to co zapisało się na pendrive:

3.
	Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium	, totam rem aperiam eaque ipsa,	 quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.	  Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit,	   sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt,	    neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur,	     adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem.	      Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,	       nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit,	        qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat,	         quo voluptas nulla pariatur? [33] At vero eos et accusamus et iusto odio dignissimos ducimus, 	         qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, 	         obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, 	         id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio.	          Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id,	           quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.	            Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet,	             ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus,	              ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
4.
	Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium	, totam rem aperiam eaque ipsa,	 quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo.	  Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit,	   sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt,	    neque porro quisquam est, qui dolorem ipsum, quia dolor sit, amet, consectetur,	     adipisci velit, sed quia non numquam eius modi tempora incidunt, ut labore et dolore magnam aliquam quaerat voluptatem.	      Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,	       nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit,	        qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat,	         quo voluptas nulla pariatur? [33] At vero eos et accusamus et iusto odio dignissimos ducimus, 	         qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, 	         obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, 	         id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio.	          Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id,	           quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus.	            Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet,	             ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus,	              ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.

Nie kopiuję całości bo to bez sensu. Konkluzja jest taka że pliki zapisują się w pamięci po poleceniu fclose(f); Tak na prawdę powinno być 5 wpisów. Natomiast to co zdążyło się zapisać zostało w pamięci, plik nie został uszkodzony

Chciałem sprawdzić co się stanie kiedy wyjmę pena póki plik jest jeszcze otwarty.

        ESP_LOGW(TAG,"Start written No: %d\n", bufCount);
        fprintf(f, "%d.\n	%s",bufCount, LoremIpsum);
        vTaskDelay(500);

Od strony esp program nie wyłożył się ale zasygnalizował że coś poszło nietak:
 

DIR esp
DIR System Volume Information
DIR LOGGER_806599C7B524
W (155870) example: len:  61
/usb/LOGGER_806599C7B524/LOG_806599C7B524_01011970_000010.txt
W (155880) example: Creating file
I (155880) example: Example finished, you can disconnect the USB flash drive
W (155990) example: Start written No: 2
(27)[0m
W (161110) example: Start written No: 3
(27)[0m
W (166220) example: Start written No: 4
(27)[0m
W (171380) example: Start written No: 5
(27)[0m
E (171710) USBH: Device 1 gone
I (171710) example: MSC device disconnected

 

Edytowano przez _LM_

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...