USB host msc example gives errors after unplugging and pluggind
Posted: Fri Jul 08, 2022 8:49 am
Hello there,
I am using the example of USB host msc from espressif github. When I run it and plug in usb stick it works nice, but after I unplug it and plug it bag in it restarts for some reason.
It gives me this:
Thank you for the replies.
I am using the example of USB host msc from espressif github. When I run it and plug in usb stick it works nice, but after I unplug it and plug it bag in it restarts for some reason.
It gives me this:
Code: Select all
I (2892) ThermalChamber: Writing file
I (14932) ThermalChamber: Writing file
E (21992) USBH: Device 1 gone
I (21992) ThermalChamber: MSC device disconnected
I (24952) ThermalChamber: Waiting for USB stick to be connected
I (26292) ThermalChamber: MSC device connected
I (26292) ThermalChamber: connection...
E (27392) Transfer failed: Status 3
E (27392) USB_MSC: msc_bulk_transfer(533):
E (27392) USB_MSC_SCSI: bot_execute_command(292):
E (27392) diskio_usb: scsi_cmd_read10 failed (263)
ESP_ERROR_CHECK failed: esp_err_t 0x1701 (ERROR) at 0x40379004
0x40379004: _esp_error_check_failed at C:/Espressif/frameworks/esp-idf-v4.4.1/components/esp_system/esp_err.c:42
file: "../main/main.c" line 243
func: app_main
expression: msc_host_vfs_register(msc_device, "/usb", &mount_config, &vfs_handle)
abort() was called at PC 0x40379007 on core 0
0x40379007: _esp_error_check_failed at C:/Espressif/frameworks/esp-idf-v4.4.1/components/esp_system/esp_err.c:43
Backtrace:0x40375a12:0x3fcf3c500x40379011:0x3fcf3c70 0x4037f81e:0x3fcf3c90 0x40379007:0x3fcf3d00 0x42006634:0x3fcf3d20 0x4202d071:0x3fcf3e70 0x4037c075:0x3fcf3e90
0x40375a12: panic_abort at C:/Espressif/frameworks/esp-idf-v4.4.1/components/esp_system/panic.c:402
0x40379011: esp_system_abort at C:/Espressif/frameworks/esp-idf-v4.4.1/components/esp_system/esp_system.c:128
0x4037f81e: abort at C:/Espressif/frameworks/esp-idf-v4.4.1/components/newlib/abort.c:46
0x40379007: _esp_error_check_failed at C:/Espressif/frameworks/esp-idf-v4.4.1/components/esp_system/esp_err.c:43
0x42006634: app_main at C:\Users\david\OneDrive\Plocha\esp32\usb_msc\msc\build/../main/main.c:243 (discriminator 1)
0x4202d071: main_task at C:/Espressif/frameworks/esp-idf-v4.4.1/components/freertos/port/port_common.c:129 (discriminator 2)
0x4037c075: vPortTaskWrapper at C:/Espressif/frameworks/esp-idf-v4.4.1/components/freertos/port/xtensa/port.c:131
Code: Select all
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_err.h"
#include "esp_log.h"
#include "usb/usb_host.h"
#include "msc_host.h"
#include "msc_host_vfs.h"
#include "ffconf.h"
#include "ff.h"
#include "esp_vfs.h"
#include "errno.h"
#include "hal/usb_hal.h"
#include "driver/gpio.h"
#include "esp_vfs_dev.h"
static int size = 0;
#define USB_DISCONNECT_PIN GPIO_NUM_10
#define READY_TO_UNINSTALL (HOST_NO_CLIENT | HOST_ALL_FREE)
typedef enum {
HOST_NO_CLIENT = 0x1,
HOST_ALL_FREE = 0x2,
DEVICE_CONNECTED = 0x4,
DEVICE_DISCONNECTED = 0x8,
DEVICE_ADDRESS_MASK = 0xFF0,
} app_event_t;
static const char *TAG = "ThermalChamber";
static EventGroupHandle_t usb_flags;
int file_size(char pathToFile[FILENAME_MAX]) {
FILE *fp;
int size_f = 0;
fp = fopen(pathToFile, "r");
if (fp == NULL)
{
printf("\nFile unable to open...");
return 0;
}
fseek(fp, 0, 2); /* File pointer at the end of file */
size_f = ftell(fp); /* Take a position of file pointer in size variable */
fclose(fp);
return size_f;
}
void utilized_storage(const char directory[100]) {
DIR *d;
char tempDir[100];
strcpy(tempDir, directory);
struct dirent *dir;
d = opendir(directory);
if(d) {
while((dir = readdir(d)) != NULL) {
if((strcmp(dir->d_name, "SYSTEM~1") != 0) && (strcmp(dir->d_name, ".") != 0) && (strcmp(dir->d_name, "..") != 0)) {
if(dir->d_type == 2) {
//folder
strcat(tempDir, dir->d_name);
utilized_storage(tempDir);
strcpy(tempDir, directory);
}
else if(dir->d_type == 1){
//file
char tempDir2[100];
strcpy(tempDir2, tempDir);
if(strcmp(tempDir2, "/usb/") != 0) {
strcat(tempDir2, "/");
}
strcat(tempDir2, dir->d_name);
printf("%s\n", tempDir2);
size += file_size(tempDir2);
}
}
}
}
}
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");
// Obtained USB device address is placed after application events
xEventGroupSetBits(usb_flags, DEVICE_CONNECTED | (event->device.address << 4));
} else if (event->event == MSC_DEVICE_DISCONNECTED) {
xEventGroupSetBits(usb_flags, DEVICE_DISCONNECTED);
ESP_LOGI(TAG, "MSC device disconnected");
}
}
static void print_device_info(msc_host_device_info_t *info)
{
utilized_storage("/usb/");
uint64_t capacity = ((uint64_t)info->sector_size * info->sector_count);
uint64_t freeCapacity = capacity - (uint64_t)size;
printf("Device info:\n");
printf("\t Sector size: %u\n", info->sector_size);
printf("\t Sector count: %u\n", info->sector_count);
printf("\t PID: 0x%4X \n", info->idProduct);
printf("\t VID: 0x%4X \n", info->idVendor);
wprintf(L"\t iProduct: %S \n", info->iProduct);
wprintf(L"\t iManufacturer: %S \n", info->iManufacturer);
wprintf(L"\t iSerialNumber: %S \n", info->iSerialNumber);
printf("\t Storage: %llu B\n", capacity);
printf("\t Availible storage: %lld B\n", freeCapacity);
}
static void file_operations(void)
{
const char *directory = "/usb/esp";
const char *file_path = "/usb/esp/test.csv";
struct stat s = {0};
bool directory_exists = stat(directory, &s) == 0;
if (!directory_exists) {
if (mkdir(directory, 0775) != 0) {
ESP_LOGE(TAG, "mkdir failed with errno: %s\n", strerror(errno));
}
}
ESP_LOGI(TAG, "Writing file");
FILE *f = fopen(file_path, "a"); //a -> appending at the end of the existing file, if it doesn't exist, file is created
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "x\n");
fclose(f);
/*ESP_LOGI(TAG, "Reading file");
f = fopen(file_path, "r");
if (f == NULL) {
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
char line[64];
fgets(line, sizeof(line), f);
fclose(f);
char *pos = strchr(line, '\n');
if (pos) {
*pos = '\0';
}
ESP_LOGI(TAG, "Read from file: '%s'", line);*/
}
// Handles common USB host library events
static void handle_usb_events(void *args)
{
while (1) {
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) {
usb_host_device_free_all();
xEventGroupSetBits(usb_flags, HOST_NO_CLIENT);
}
// Give ready_to_uninstall_usb semaphore to indicate that USB Host library
// can be deinitialized, and terminate this task.
if (event_flags & USB_HOST_LIB_EVENT_FLAGS_ALL_FREE) {
xEventGroupSetBits(usb_flags, HOST_ALL_FREE);
}
}
vTaskDelete(NULL);
}
static uint8_t wait_for_msc_device(void)
{
EventBits_t event;
ESP_LOGI(TAG, "Waiting for USB stick to be connected");
event = xEventGroupWaitBits(usb_flags, DEVICE_CONNECTED | DEVICE_ADDRESS_MASK,
pdTRUE, pdFALSE, portMAX_DELAY);
ESP_LOGI(TAG, "connection...");
// Extract USB device address from event group bits
return (event & DEVICE_ADDRESS_MASK) >> 4;
}
static bool wait_for_event(EventBits_t event, TickType_t timeout)
{
return xEventGroupWaitBits(usb_flags, event, pdTRUE, pdTRUE, timeout) & event;
}
void app_main(void)
{
msc_host_device_handle_t msc_device;
msc_host_vfs_handle_t vfs_handle;
msc_host_device_info_t info;
BaseType_t task_created;
const gpio_config_t input_pin = {
.pin_bit_mask = (1 << USB_DISCONNECT_PIN),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
};
ESP_ERROR_CHECK( gpio_config(&input_pin) );
usb_flags = xEventGroupCreate();
assert(usb_flags);
const usb_host_config_t host_config = { .intr_flags = ESP_INTR_FLAG_LEVEL1 };
ESP_ERROR_CHECK( usb_host_install(&host_config) );
task_created = xTaskCreate(handle_usb_events, "usb_events", 2048, NULL, 2, NULL);
assert(task_created);
const msc_host_driver_config_t msc_config = {
.create_backround_task = true,
.task_priority = 5,
.stack_size = 2048,
.callback = msc_event_cb,
};
ESP_ERROR_CHECK( msc_host_install(&msc_config) );
do {
const esp_vfs_fat_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 1,
.allocation_unit_size = 1024,
};
uint8_t device_address = wait_for_msc_device();
ESP_ERROR_CHECK( msc_host_install_device(device_address, &msc_device) );
//msc_host_print_descriptors(msc_device);
ESP_ERROR_CHECK( msc_host_vfs_register(msc_device, "/usb", &mount_config, &vfs_handle) );
ESP_ERROR_CHECK( msc_host_get_device_info(msc_device, &info) );
print_device_info(&info);
while (!wait_for_event(DEVICE_DISCONNECTED, 200)) {
file_operations();
vTaskDelay(1000);
}
xEventGroupClearBits(usb_flags, READY_TO_UNINSTALL);
ESP_ERROR_CHECK( msc_host_vfs_unregister(vfs_handle) );
ESP_ERROR_CHECK( msc_host_uninstall_device(msc_device) );
}while(gpio_get_level(USB_DISCONNECT_PIN) != 0); //0(true) -> for writing again after removing; 1(false) -> for uninitializing USB
ESP_LOGI(TAG, "Uninitializing USB...");
ESP_ERROR_CHECK( msc_host_uninstall() );
wait_for_event(READY_TO_UNINSTALL, portMAX_DELAY);
ESP_ERROR_CHECK( usb_host_uninstall() );
ESP_LOGI(TAG, "Done");
}