STMF4 и USB OTG с использованием FATfs

Я использую STM32F407 Discovery Board для взаимодействия USB OTG FS, я использую CubeMx and Keil для развития.

Первым делом я включил PC0 - USB_Power(для платы обнаружения), и для правильной работы USB установлено состояние RESET.
Я включил PA9 - VBUS как вход GPIO.
Моя система работает на 168 МГц.
Использовали MAX_SS(максимальный размер сектора) - 4096(эта опция доступна в Cube Mx).
Включил USB в качестве хоста и использовал FATFS, предоставляемые CubeMX.
Enbaled MSC (класс хранения).

КОД:

#include "main.h"
#include "stm32f4xx_hal.h"
#include "fatfs.h"
#include "usb_host.h"

#define GREEN_High          HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_SET)
#define GREEN_Low               HAL_GPIO_WritePin(GREEN_GPIO_Port,GREEN_Pin,GPIO_PIN_RESET)

#define ORANGE_High         HAL_GPIO_WritePin(ORANGE_GPIO_Port,ORANGE_Pin,GPIO_PIN_SET)
#define ORANGE_Low          HAL_GPIO_WritePin(ORANGE_GPIO_Port,ORANGE_Pin,GPIO_PIN_RESET)

extern USBH_HandleTypeDef hUsbHostFS;
extern ApplicationTypeDef Appli_state;
FATFS USBDISKFatFs;
FIL MyFile;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
void MX_USB_HOST_Process(void);

void Green_Blink(uint16_t ms);
void Orange_Blink(uint16_t ms);
void USB_Write_Demo(char* fileName);

int main(void)
{
  HAL_Init();
    SystemClock_Config();
  MX_GPIO_Init();
  MX_USB_HOST_Init();
  MX_FATFS_Init();
    Green_Blink(100);
    Orange_Blink(100);
  while (1)
  {
    MX_USB_HOST_Process();
        if (Appli_state == APPLICATION_START)
        {
            USB_Write_Demo("myCSV.csv");

        }
 *THIS IS THE AREA OF PROBLEM*
//      else if (Appli_state == APPLICATION_IDLE)
//      {
//          GREEN_High;
//          ORANGE_High;
//          HAL_Delay(100);
//          GREEN_Low;
//          ORANGE_Low;
//          HAL_Delay(100);
//      }
  }
}

void USB_Write_Demo(char *fileName)
{
    FRESULT fres;
    uint32_t bytesWritten;
    uint8_t w_text[] = {"Hello, I, AM, STM32, Discovery\r\n"};
    if (f_mount(&USBDISKFatFs,(TCHAR const*)USBHPath,0) != FR_OK)
    {
        Orange_Blink(1000);
        Error_Handler();
    }
    else
    {
        Green_Blink(100);
        if (open_append(&MyFile,fileName) != FR_OK)
        {
            Orange_Blink(100);
            Error_Handler();
        }
        else
        {
            Green_Blink(100);
            fres = f_write(&MyFile,w_text,sizeof(w_text),(void*)bytesWritten);
            if (bytesWritten == 0 || fres != FR_OK)
            {
                Orange_Blink(100);
                Error_Handler();
            }
            else
            {
                f_close(&MyFile);
                Green_Blink(100);
            }
        }
    }
}

void Green_Blink(uint16_t ms)
{
    GREEN_High;
    HAL_Delay(ms);
    GREEN_Low;
    HAL_Delay(ms);
}

void Orange_Blink(uint16_t ms)
{
    ORANGE_High;
    HAL_Delay(ms);
    ORANGE_Low;
    HAL_Delay(ms);
}

Итак, что здесь происходит, я создаю файл CSV и с каждым циклом добавляю в него новые данные. И я действительно успешен в этом. Я создал очень длинный (500 КБ не так долго) CSV-файл, используя этот конкретный код.

Но я обнаружил здесь ненормальность, которую не могу понять.

Когда я добавляю эту часть в код, файл не создается, и на каждой итерации элемент управления достигает этой функции.

    else if (Appli_state == APPLICATION_IDLE)
    {
        GREEN_High;
        ORANGE_High;
        HAL_Delay(100);
        GREEN_Low;
        ORANGE_Low;
        HAL_Delay(100);
    }

Я не могу понять, как эта функция влияет на рабочий код. я уверен, что APPLICATION_START а также APPLICATION_IDLE две разные вещи. Когда я комментирую эту часть кода, все в порядке, я могу создавать файлы, пока мое хранилище не заканчивается.

Мне потребовалось несколько часов (например, 2 дня), чтобы понять, в чем проблема.
Я попытался увеличить минимальный размер кучи - 0x2000 и минимальный размер стека - 0x4000 (эта опция доступна при настройке компоновщика в cubeMx. При создании файла указывается место, где вы даете имя проекта, местоположение и все, что там есть)

Любые предложения будут полезны, поскольку у меня нет идей.

2 ответа

Я нашел способ справиться с этой проблемой без использования RTOS. Поскольку я никогда не пробовал RTOS раньше, было трудно завершить проект за несколько дней.

Идея проста. Это нам нужно подождать до MX_USB_HOST_Process() не возвращается Appli_state в простое.

Я не беру кредит.

Вы можете проверить эту ССЫЛКУ

поэтому я добавил новую функцию в usb_host.c который возвращается Appli_state

uint8_t IsUSB_Busy(void)
{
    return Appli_state;
}

И в main.c я ждал, пока он не вернет ничего, кроме 0. Как APPLICATION_IDLE=0

typedef enum {
  APPLICATION_IDLE = 0,
  APPLICATION_START,
  APPLICATION_READY,
  APPLICATION_DISCONNECT
}ApplicationTypeDef;

Добавил этот бит кода в основной файл и все работает как положено

while (!IsUSB_Busy())
{
    MX_USB_HOST_Process();
}

Я надеюсь, что кто-то найдет это полезным.

И спасибо за вашу помощь.

Вы можете создать две задачи (FreeRTOS) с CubeMX, отделить USB-компоненты от светодиодных. taskLED() и taskUSB()

Другие вопросы по тегам