This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28075:向 USB 闪存盘写入数据的问题

Guru**** 2902940 points

Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/992560/tms320f28075-issue-of-writing-data-to-usb-flash-disk

器件型号:TMS320F28075
主题中讨论的其他器件:C2000WARE

您好、专家、

 

我的客户正在开发 F28027功能的 USB 以将数据存储在 USB 闪存盘中、我们似乎没有将数据写入 USB 闪存盘的示例、因此他们修改了 C2000ware 中的示例代码 USB_EX7_host_msc.c 来实现此功能。

 他们将读取 ADC 值、并使用一个数组来存储这些值、长度为32字节、对于每1ms、他们将使用 f_write 将这些32字节数据写入 USB 闪存盘、数据可以成功写入、 但他们面临的问题是、在运行代码数十秒后调用函数"USBHCPDPipeRead"所需的时间太长。 他们使用时间来记录时间,并发现调用此函数“USBHCPIPeRead”需要200ms~2s。 由于 RAM 中需要为每1ms 写入32个字节、因此需要写入 USB 闪存盘的缓冲数据将被覆盖的时间很长。

 他们调用的函数的顺序如下:

f_write àdisk â writeàUSBHMSCBlockWriteà USBHSCSIWrite10à USBHSCSISendCommandà USBHCDPipeWriteàUSBHCDPipeRead

 问题是、调用"USBHCPIPEREAD"函数需要很长时间? 附件是客户根据 USB_EX7_HOST_msc 示例进行修改的代码。

代码或示例将数据写入 USB 闪存盘是否有问题、我们已成功验证这些问题是否可以共享给客户?

e2e.ti.com/.../usb_5F00_ex7_5F00_host_5F00_msc.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、很强、

    查看代码、看看是否可以进行任何优化。

    我们没有任何其他示例。 'USB_EX7_host_msc.c'是唯一使用 FatFS 对 USB 大容量存储设备进行读/写操作的 USB 示例。

    此致

    Siddharth

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Siddharth、

    是否对此问题进行了更新? 另一个问题是、usbdma.c 中的许多函数为何为空? 它是否可用于 USB 功能的 DMA?

    //#############################################################################
    // FILE: usbdma.c
    // TITLE: USB Library DMA handling functions.
    //#############################################################################
    // $TI Release: F2807x Support Library v3.12.00.00 $
    // $Release Date: Fri Feb 12 19:00:22 IST 2021 $
    // $Copyright:
    // Copyright (C) 2014-2021 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without 
    // modification, are permitted provided that the following conditions 
    // are met:
    // 
    //   Redistributions of source code must retain the above copyright 
    //   notice, this list of conditions and the following disclaimer.
    // 
    //   Redistributions in binary form must reproduce the above copyright
    //   notice, this list of conditions and the following disclaimer in the 
    //   documentation and/or other materials provided with the   
    //   distribution.
    // 
    //   Neither the name of Texas Instruments Incorporated nor the names of
    //   its contributors may be used to endorse or promote products derived
    //   from this software without specific prior written permission.
    // 
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    // $
    //#############################################################################
    
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "debug.h"
    #include "interrupt.h"
    #include "usb.h"
    #include "include/usblib.h"
    #include "include/usblibpriv.h"
    
    //*****************************************************************************
    //
    //! \addtogroup usblib_dma_api Internal USB DMA functions
    //! @{
    //
    //*****************************************************************************
    
    static tUSBDMAInstance g_psUSBDMAInst[1];
    
    //*****************************************************************************
    //
    // Macros used to determine if a uDMA endpoint configuration is used for
    // receive or transmit.
    //
    //*****************************************************************************
    #define UDMAConfigIsRx(ui32Config)                                            \
            ((ui32Config & UDMA_SRC_INC_NONE) == UDMA_SRC_INC_NONE)
    #define UDMAConfigIsTx(ui32Config)                                            \
            ((ui32Config & UDMA_DEST_INC_NONE) == UDMA_DEST_INC_NONE)
    
    //*****************************************************************************
    //
    // USBLibDMAChannelStatus() for USB controllers that use the uDMA for DMA.
    //
    //*****************************************************************************
    static uint32_t
    uDMAUSBChannelStatus(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel)
    {
        uint32_t ui32Status;
    
        //
        // Initialize the current status to no events.
        //
        ui32Status = USBLIBSTATUS_DMA_IDLE;
    
    
        return(ui32Status);
    }
    
    //*****************************************************************************
    //
    // USBLibDMAIntStatus() for USB controllers that use uDMA.
    //
    //*****************************************************************************
    static uint32_t
    uDMAUSBIntStatus(tUSBDMAInstance *psUSBDMAInst)
    {
    
    	return(0);
    }
    
    //*****************************************************************************
    //
    // USBLibDMAIntStatusClear() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static void
    DMAUSBIntStatusClear(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Status)
    {
        //
        // Clear out the requested interrupts.  Since the USB interface does not
        // have a true interrupt clear, this clears the current completed
        // status for the requested channels.
        //
        psUSBDMAInst->ui32Complete &= ~ui32Status;
    
        return;
    }
    
    //*****************************************************************************
    //
    // USBLibDMAIntHandler() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static void
    DMAUSBIntHandler(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32DMAIntStatus)
    {
        uint32_t ui32Channel;
    
        if(ui32DMAIntStatus == 0)
        {
            return;
        }
    
        //
        // Determine if the uDMA is used or the USB DMA controller.
        //
        for(ui32Channel = 0; ui32Channel < USB_MAX_DMA_CHANNELS; ui32Channel++)
        {
            //
            // Mark any pending interrupts as completed.
            //
            if(ui32DMAIntStatus & 1)
            {
                psUSBDMAInst->ui32Pending &= ~((uint32_t)1 << ui32Channel);
                psUSBDMAInst->ui32Complete |= ((uint32_t)1 << ui32Channel);
            }
    
            //
            // Check the next channel.
            //
            ui32DMAIntStatus >>= 1;
    
            //
            // Break if there are no more pending DMA interrupts.
            //
            if(ui32DMAIntStatus == 0)
            {
                break;
            }
        }
    }
    
    //*****************************************************************************
    //
    // USBLibDMAChannelEnable() for USB controllers that use uDMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBChannelEnable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel)
    {
    
    }
    
    //*****************************************************************************
    //
    // USBLibDMAChannelDisable() for USB controllers that use uDMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBChannelDisable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel)
    {
    
    }
    
    //*****************************************************************************
    //
    // USBLibDMAChannelIntEnable() for USB controllers that use uDMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBChannelIntEnable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel)
    {
        //
        // There is no way to Enable channel interrupts when using uDMA.
        //
    }
    
    //*****************************************************************************
    //
    // USBLibDMAChannelIntDisable() for USB controllers that use uDMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBChannelIntDisable(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel)
    {
        //
        // There is no way to Disable channel interrupts when using uDMA.
        //
    }
    
    //*****************************************************************************
    //
    // USBLibDMATransfer() for USB controllers that use the uDMA controller.
    //
    //*****************************************************************************
    static uint32_t
    uDMAUSBTransfer(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel,
                    void *pvBuffer, uint32_t ui32Size)
    {
    
            return(0);
    
    }
    
    //*****************************************************************************
    //
    // USBLibDMAChannelAllocate() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static uint32_t
    uDMAUSBChannelAllocate(tUSBDMAInstance *psUSBDMAInst, uint8_t ui8Endpoint,
                           uint32_t ui32MaxPacketSize, uint32_t ui32Config)
    {
    
        return(0);
    }
    
    //*****************************************************************************
    //
    // USBLibDMAChannelRelease() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBChannelRelease(tUSBDMAInstance *psUSBDMAInst, uint8_t ui32Channel)
    {
    
    }
    
    //*****************************************************************************
    //
    // USBLibDMAUnitSizeSet() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBUnitSizeSet(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel,
                       uint32_t ui32BitSize)
    {
    
    }
    
    //*****************************************************************************
    //
    // USBLibDMAArbSizeSet() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static void
    uDMAUSBArbSizeSet(tUSBDMAInstance *psUSBDMAInst, uint32_t ui32Channel,
                      uint32_t ui32ArbSize)
    {
    
    }
    
    //*****************************************************************************
    //
    // USBLibDMAStatus() for USB controllers that use uDMA for DMA.
    //
    //*****************************************************************************
    static uint32_t
    DMAUSBStatus(tUSBDMAInstance *psUSBDMAInst)
    {
        return(0);
    }
    
    //*****************************************************************************
    //
    //! This function is used to initialize the DMA interface for a USB instance.
    //!
    //! \param ui32Index is the index of the USB controller for this instance.
    //!
    //! This function performs any initialization and configuration of the DMA
    //! portions of the USB controller.  This function returns a pointer that
    //! is used with the remaining USBLibDMA APIs or the function returns zero
    //! if the requested controller cannot support DMA.  If this function is called
    //! when already initialized it will not reinitialize the DMA controller and
    //! will instead return the previously initialized DMA instance.
    //!
    //! \return A pointer to use with USBLibDMA APIs.
    //
    //*****************************************************************************
    tUSBDMAInstance *
    USBLibDMAInit(uint32_t ui32Index)
    {
        uint32_t ui32Channel;
    
        ASSERT(ui32Index == USB_BASE);
    
        //
        // Save the base address of the USB controller.
        //
        g_psUSBDMAInst[0].ui32Base = ui32Index;
    
        //
        // Save the interrupt number for the USB controller.
        //
        g_psUSBDMAInst[0].ui32IntNum = INT_USB;
    
        //
        // Initialize the function pointers.
        //
        g_psUSBDMAInst[0].pfnArbSizeSet = uDMAUSBArbSizeSet;
        g_psUSBDMAInst[0].pfnChannelAllocate = uDMAUSBChannelAllocate;
        g_psUSBDMAInst[0].pfnChannelDisable = uDMAUSBChannelDisable;
        g_psUSBDMAInst[0].pfnChannelEnable = uDMAUSBChannelEnable;
        g_psUSBDMAInst[0].pfnChannelIntEnable = uDMAUSBChannelIntEnable;
        g_psUSBDMAInst[0].pfnChannelIntDisable = uDMAUSBChannelIntDisable;
        g_psUSBDMAInst[0].pfnChannelRelease = uDMAUSBChannelRelease;
        g_psUSBDMAInst[0].pfnChannelStatus = uDMAUSBChannelStatus;
        g_psUSBDMAInst[0].pfnIntHandler = DMAUSBIntHandler;
        g_psUSBDMAInst[0].pfnIntStatus = uDMAUSBIntStatus;
        g_psUSBDMAInst[0].pfnIntStatusClear = DMAUSBIntStatusClear;
        g_psUSBDMAInst[0].pfnStatus = DMAUSBStatus;
        g_psUSBDMAInst[0].pfnTransfer = uDMAUSBTransfer;
        g_psUSBDMAInst[0].pfnUnitSizeSet = uDMAUSBUnitSizeSet;
    
        //
        // Clear out the endpoint and the current configuration.
        //
        for(ui32Channel = 0; ui32Channel < USB_MAX_DMA_CHANNELS; ui32Channel++)
        {
            g_psUSBDMAInst[0].pui8Endpoint[ui32Channel] = 0;
            g_psUSBDMAInst[0].pui32Config[ui32Channel] = 0;
            g_psUSBDMAInst[0].ui32Pending = 0;
            g_psUSBDMAInst[0].ui32Complete = 0;
        }
        return(&g_psUSBDMAInst[0]);
    }
    
    //*****************************************************************************
    //
    // Close the Doxygen group.
    //! @}
    //
    //*****************************************************************************
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Strong,

    遗憾的是、由于 USB 触发 DMA 时出现硬件错误、因此无法使用 DMA。 当前为编译器启用的优化级别是多少?   

    此外、FatFS 不是针对速度构建的。  某些 FatFs 函数需要大量的执行时间。

    此致

    Siddharth

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Siddharth、

    客户已使用优化级别 2并将 opt_for_speed 设置为0、但结果相同、仍然存在问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Siddharth、

    对此问题有任何建议吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、很强、

    很遗憾、对于这个问题没有任何建议。  f_write 函数会转过多个函数调用来写入数据、 执行过程将花费大量时间。

    此致

    Siddharth