【问题标题】:STMF4 and USB OTG using FATfs使用 FATfs 的 STMF4 和 USB OTG
【发布时间】:2018-08-21 11:53:46
【问题描述】:

我使用STM32F407 Discovery Board 连接USB OTG FS。我正在使用CubeMx and Keil 进行开发。

首先,我启用了 PC0 - USB_Power(用于探索板),状态为 RESET 以确保 USB 正常运行。
我已启用 PA9 - VBUS 作为 GPIO 输入。
我的系统以 168MHz 运行.
已使用 MAX_SS(Max Sector size) - 4096(此选项在 Cube Mx 中可用)。
启用 USB 作为主机并使用 CubeMX 提供的 FATFS。
启用 MSC(Mass Storage Class)。

代码:

#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 文件,并且在每个循环中我都在其中添加新数据。我真的很成功。我使用这个特定的代码创建了一个非常长(500KB 不太长)的 csv 文件。

但是我在这里发现了一个我无法理解的异常。

当我将此部分添加到代码中时,没有创建文件,并且每次迭代控件都会到达此函数。

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

我无法理解这个函数是如何影响工作代码的。我确信APPLICATION_STARTAPPLICATION_IDLE 是两个不同的东西。当我评论这部分代码时,一切都很好,只要我的存储没有结束,我就可以制作文件。

我花了几个小时(比如 2 天)才发现这是问题所在。
我尝试增加最小堆大小 - 0x2000 和最小堆栈大小 - 0x4000(此选项在 cubeMx 中的链接器设置中可用。生成文件时,您提供项目名称、位置和所有内容的位置)

任何建议都会有所帮助,因为我没有想法。

【问题讨论】:

  • 你能从这个sn-p中删除HAL_Delay()s并检查问题是否仍然存在吗?
  • 是的,它正在工作。但我必须在那部分做更多的工作,所以会有很多代码和延迟。
  • 删除HAL_Delay()的逻辑是什么,代码可以工作,但是如果我放置HAL_Delay(),代码就不能工作??
  • 阅读有关并发、并行编程和所有其他有关在单个 cpu 上运行两个作业的内容。您的 cpu 需要服务 USB 请求,但同时您请求它被卡住 100 毫秒。您需要创建两个线程,一个为 USB 提供服务,另一个为您的任务提供服务。函数MX_USB_HOST_Process() 的调用频率必须超过每 100 毫秒。 HAL_Delay 函数只是一个循环卡住检查 systick 计数器,每 1ms 被 systick 中断中断以增加计数器
  • 好吧,所以我现在所做的是在此呼叫 USB_Write_Demo("myCSV.csv") 之后放置一个 HAL_Dealy(),然后我在 else if 部分中闪烁了另一个 LED BLUE,我发现在一段时间内 Appli_state equals to APPLICATION_IDLE 和然后一切都回到现在。

标签: c stm32f4discovery stm32f4 usb-otg fatfs


【解决方案1】:

我找到了一种无需使用 RTOS 即可解决此问题的方法。由于我之前从未尝试过 RTOS,因此很难在几天内完成该项目。

这个想法很简单。我们需要等到MX_USB_HOST_Process() 没有将Appli_state 作为空闲返回。

我不相信。

你可以查看这个LINK

所以我在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();
}

我希望有人觉得它有帮助。

感谢您的帮助。

【讨论】:

    【解决方案2】:

    您可以使用 CubeMX 创建两个任务 (FreeRTOS),将 USB 的东西与 LED 的东西分开。 taskLED() 和 taskUSB()

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 2017-03-20
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2013-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多