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.

[参考译文] TM4C129ENCPDT:TI-RTOS USB 示例。 未释放内存

Guru**** 2380860 points
Other Parts Discussed in Thread: EK-TM4C1294XL
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/989281/tm4c129encpdt-ti-rtos-usb-example-memory-is-not-released

器件型号:TM4C129ENCPDT
Thread 中讨论的其他器件:EK-TM4C1294XL

您好!

在下面的代码示例中、我打开 USB 记忆棒、检查它是否已连接、然后再次将其关闭。

但是每次执行函数 USBCopy ()时、HeapMemory 的20个字节将不再被释放。

在一个任务内调用 USBCopy 函数。 此任务的堆栈大小为2048字节

我有 EK-TM4C1294XL Launch Pad 并使用 TI-RTOS 版本:TI-RTOS 2.16.1.14。

此代码来自 TI 示例项目。  如果在 TI USB 示例项目中删除了 BIOS_exit (0)并且插入了等待循环、您还可以看到缺少20个字节。

原因可能是什么? 我请求帮助

void usbCopy(void)
{
    // Variables for the CIO functions
	USBMSCHFatFs_Handle usbmschfatfsHandle;
	USBMSCHFatFs_Params usbmschfatfsParams;


    // Mount and register the USB Drive
    USBMSCHFatFs_Params_init(&usbmschfatfsParams);
    usbmschfatfsParams.serviceTaskStackPtr = usbServiceTaskStack;
    usbmschfatfsParams.serviceTaskStackSize = sizeof(usbServiceTaskStack);
    usbmschfatfsHandle = USBMSCHFatFs_open(0, USB_DRIVE_NUM, &usbmschfatfsParams);
    if (usbmschfatfsHandle == NULL) {
        //System_abort("Error starting the USB Drive\n");
    }
    else {
        System_printf("Drive %u is mounted\n", USB_DRIVE_NUM); System_flush();
    }


    // Need to block until a USB Drive has been enumerated
    if (!USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 10000)) {
        System_printf("No USB drive present, aborting...\n");System_flush();
        return;
    }

    System_printf("usb close\n"); System_flush();


    USBMSCHFatFs_close(usbmschfatfsHandle);

}

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

    您好!

     我会将您的问题转交给我们的 USB 专家。 请期待一些延迟。 同时 、您能否确认您是否按原样运行了 TI-RTOS fatsdusbcopy 示例、是否发现任何问题?

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

    您好!

    [引用 userid="311439" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/989281/tm4c129encpdt-ti-rtos-usb-example-memory-is-not-released "]

    但是每次执行函数 USBCopy ()时、HeapMemory 的20个字节将不再被释放。

    在一个任务内调用 USBCopy 函数。 此任务的堆栈大小为2048字节

    [/报价]

     我不擅长文件系统以及 SYS/BIOS 如何处理堆。 但是、查看您的代码、我不确定您要执行的操作。 您创建 USBCopy 任务、在此任务中、您只尝试安装 USB 记忆棒驱动器、然后立即将其关闭? 代码中的另一个问题是,您为什么删除了如 fatsdusbcopy 示例中所示的 System_abort()。 如果未能安装驱动器或枚举、则应调用 System_abort、以便 SYS/BIOS 可以启动一些内部清理。 您是否通过 了 USBMSCHFatFs_open 和 USBMSCHFatFs_waitForConnect?

    system_abort()—当应用程序需要异常中止并返回错误消息时,可以调用此函数。 此函数使您能够返回一个描述所发生错误的字符串。 调用此函数时、系统将进入系统门、调用 SupportProxy 的 abort 函数、然后调用 System.abortFxn。 不会调用通过 System_atexit()绑定的 EXIT 函数或 ANSI C 标准库 atexit()函数。

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

    您好!
    感谢您的回答。

    我继续使用示例项目进行测试、并认为我发现了问题。


    我有一个示例项目"fatsdusbcopy_EK_TM4C129EXL_TI_TivaTM4C129ENCPDT"
    已更改、以便在 USB 记忆棒上创建一个文件、并将阵列的内容写入此文件。

    此过程每3秒重复一次。
    如果我停止程序并查看使用的堆存储器的大小、存储器将再次完全释放。 一切正常。

    如果我现在将这两行添加到 xxx.cfg 文件中:


    VAR Global = xdc.useModule ("ti.ndk.config.Global");
    Global.autoOpenCloseFD = true;


    每次运行"copyArrayToUsb ()"函数后、不会再次释放20个字节。

    在我的实际项目中、设置了 Global.autoOpenCloseFD = true。 这就是为什么这20个字节总是从我的堆中消失的原因。

    我如何解决这个问题?

    /*
     * Copyright (c) 2015, Texas Instruments Incorporated
     * All rights reserved.
     *
     * 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.
     */
    
    /*
     *  ======== fatsdusbcopy.c ========
     */
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/USBMSCHFatFs.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    /* Buffer size used for the file copy process */
    #define CPY_BUFF_SIZE       2048
    
    /* String conversion macro */
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    /* Drive number used for FatFs */
    #define SD_DRIVE_NUM           0
    #define USB_DRIVE_NUM          1
    
    #define TASKSTACKSIZE          1024
    /*
     * Static task stack for the USBMSCHFatFs USB driver
     * This allows the application to reduce the required system Heap.
     */
    static uint8_t usbServiceTaskStack[1024];
    
    const char outputfileusb[] = "fat:"STR(USB_DRIVE_NUM)":output.txt";
    
    const char textarray[] = \
    "***********************************************************************\n"
    "0         1         2         3         4         5         6         7\n"
    "01234567890123456789012345678901234567890123456789012345678901234567890\n"
    "This is some text to be inserted into the inputfile if there isn't\n"
    "already an existing file located on the media.\n"
    "If an inputfile already exists, or if the file was already once\n"
    "generated, then the inputfile will NOT be modified.\n"
    "***********************************************************************\n";
    
    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];
    
    unsigned char cpy_buff[CPY_BUFF_SIZE];
    
    /*
     *  ======== taskFxn ========
     *  Task to perform a file copy
     *
     *  Task tries to open an existing file inputfile[]. If the file doesn't
     *  exist, create one and write some known content into it.
     *  The contents of the inputfile[] are then copied to an output file
     *  outputfile[]. Once completed, the contents of the output file are
     *  printed onto the system console (stdout).
     *
     *  Task for this function is created statically. See the project's .cfg file.
     */
    
    Void copyArrayToUsb(Void)
    {
        USBMSCHFatFs_Handle usbmschfatfsHandle;
        USBMSCHFatFs_Params usbmschfatfsParams;
    
        /* Variables for the CIO functions */
        FILE *dst;
    
        /* Variables to keep track of the file copy progress */
        unsigned int bytesRead = 0;
        unsigned int bytesWritten = 0;
        unsigned int filesize;
        unsigned int totalBytesCopied = 0;
    
        /* Mount and register the USB Drive */
        USBMSCHFatFs_Params_init(&usbmschfatfsParams);
        usbmschfatfsParams.serviceTaskStackPtr = usbServiceTaskStack;
        usbmschfatfsParams.serviceTaskStackSize = sizeof(usbServiceTaskStack);
        usbmschfatfsHandle = USBMSCHFatFs_open(Board_USBMSCHFatFs0,
                                               USB_DRIVE_NUM,
                                              &usbmschfatfsParams);
        if (usbmschfatfsHandle == NULL) {
            System_abort("Error starting the USB Drive\n");
        }
        else {
            System_printf("Drive %u is mounted\n", USB_DRIVE_NUM);
        }
    
        /* Need to block until a USB Drive has been enumerated */
        if (!USBMSCHFatFs_waitForConnect(usbmschfatfsHandle, 10000)) {
            System_abort("No USB drive present, aborting...\n");
        }
    
    
        /* Create a new file object for the file copy */
        dst = fopen(outputfileusb, "w");
        if (!dst) {
            System_printf("Error opening \"%s\"\n", outputfileusb);
            System_abort("Aborting...\n");
        }
        else {
            System_printf("Starting file copy\n");
        }
    
        filesize = sizeof(textarray);
    
    
    
        /*  Copy the contents from the src to the dst */
        while (true)
        {
            /*  Write to dst file */
            bytesWritten = fwrite(textarray, 1, filesize, dst);
            if (bytesWritten < bytesRead) {
                System_printf("Disk Full\n");
                break; /* Error or Disk Full */
            }
    
            /*  Update the total number of bytes copied */
            totalBytesCopied += bytesWritten;
    
            if(totalBytesCopied >= filesize){
            	break;
            }
        }
    
        fflush(dst);
    
    
        /* Close both inputfile[] and outputfile[] */
        fclose(dst);
    
    
        /* Now output the outputfile[] contents onto the console */
        dst = fopen(outputfileusb, "r");
        if (!dst) {
            System_printf("Error opening \"%s\"\n", outputfileusb);
            System_abort("Aborting...\n");
        }
    
        /* Print file contents */
        while (true) {
            /* Read from output file */
            bytesRead = fread(cpy_buff, 1, CPY_BUFF_SIZE, dst);
            if (bytesRead == 0) {
                break; /* Error or EOF */
            }
            /* Write output */
            System_printf("%s", cpy_buff);
            System_flush();
        }
    
        /* Close the file */
        fclose(dst);
    
    
    
        /* Stopping the USB Drive */
        USBMSCHFatFs_close(usbmschfatfsHandle);
        System_printf("Drive %u unmounted\n", USB_DRIVE_NUM);
        System_flush();
    
    }
    
    
    Void taskFxn(UArg arg0, UArg arg1)
    {
    
        while(1)
        {
        	Task_sleep(3000);
    
        	copyArrayToUsb();
        }
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Task_Params taskParams;
    
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initUSBMSCHFatFs();
    
        /* Construct file copy Task thread */
        Task_Params_init(&taskParams);
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task0Stack;
        taskParams.instance->name = "fatsdUSBCopyTask";
        Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);
    
    
    
        System_printf("Starting the FatSD USB Copy example\n");
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

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

    您好!

     请参阅以下 Global.autoOpenCloseFD 的用法。 您可以在 NDK API 用户指南中找到更多详细信息。  我认为问题是,您将 copyArrayToUsb()调用为任务(taskFxn)中的函数,而不是从正在运行的任务中动态创建的任务。 因此,尝试从  taskFxn()任务内部为 copyArrayToUsb()创建一个任务,我希望这可以解决问题。 阅读用户指南、了解  支持 autopentloseFD 的条件。  

    3.1.2.2自动初始化文件描述符环境
    对于使用 XGCONF 或*。cfg 配置文件配置其应用程序的 TI-RTOS 内核用户
    对 fdOpenSession 和 fdCloseSession 的调用可配置为自动调用。 这是实现的
    通过设置以下配置参数:


    VAR Global = xdc.useModule('ti.ndk.config.Global.xdc');
    Global.autoOpenCloseFD = true;


    将此参数设置为 true 会导致调用 fdOpenSession 和 fdCloseSession
    在 TI-RTOS 内核任务模块中自动创建挂钩函数和退出挂钩函数、
    两个示例。


    请注意、Global.autoOpenCloseFD 参数仅支持动态创建的任务
    从任务上下文(即、从另一个正在运行的任务函数内)创建。 任务已创建
    在配置中静态地或者在 main()或者一个 Hwi 或 Swi 线程中动态地不支持这个特性。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="311439" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/989281/tm4c129encpdt-ti-rtos-usb-example-memory-is-not-released/3654937 #3654937">在我的实际项目中,设置了 Global.autoOpenCloseFD = true。 这就是为什么这20个字节总是从我的堆中消失的原因。[/quot]

    我重复了 tirtos_tivac_2_16_01_14问题。

     当 Global.autoOpenCloseFD 设置为 true 时、这会导致 NDK:

    • 安装任务创建挂钩,该挂钩调用 fdOpenSession()
    • 安装一个任务退出挂钩,该挂钩调用 fdCloseSession()

     使用 USBMSCHFatFs 函数时、这会导致动态创建任务:

    1. 对 USBMSCHFatFs_open()的调用最终会调用 Task_construct()以动态创建 USBMSCHFatFsTiva_serviceUSBHost()任务,并将任务句柄存储在 taskHCDMain 中。
    2.  USBMSCHFatFsTiva_serviceUSBHost()任务位于 tirtos_tivac_2_16_01_14/products/tidrivers_tivac_2_16_01_13/packages/ti/drivers/usbmschFatfs/USBMSCHfsTiva.c 中、并 处理 USB 堆栈的 statemachine。 此任务包含一个 while (true)循环、即任务本身不会退出。
    3. 对 USBMSCHFatFs_Close()的调用最终会在  taskHCDMain 句柄上调用 Task_析 构函数()。

    内存泄漏的原因似乎是当 USBMSCHFatFs_open()创建任务,然后 NDK 任务创建挂钩调用 fdOpenSession(),该调用会分配一些内存。 但是,当 USBMSCHFatFs_Close()调用 Task_析 构函数以删除任务 fdCloseSession()时,不调用该函数。 这是因为 NDK 会安装任务退出挂钩、而不是任务删除挂钩。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="311439" URL"~/support/microcontrollers/other/f/other-microcontrollers-forum/989281/tm4c129encpdt-ti-rtos-usb-example-memory-is-not-released/3654937 #3654937"]如何解决此问题?

    根据我之前的帖子,发现在 任务 HCDMain 支持任务上调用 Task_析 构函数()时发生内存泄漏。 由于 NDK 不安装任务删除挂钩、在不修改 TI-RTOS 源代码的情况下、我发现一个变通方法是修改用户项目以安装删除挂钩。

    在.cfg 文件中添加了以下内容:

    Task.addHookSet({
       deleteFxn: '&ti_ndk_config_global_taskDeleteHook',
    });
    

    在 fatsdusbcopy.c 中添加了以下内容:

    #include <ti/ndk/inc/usertype.h>
    #include <ti/ndk/inc/socketndk.h> /* For fdCloseSession() */
    
    Void ti_ndk_config_global_taskDeleteHook(ti_sysbios_knl_Task_Handle h)
    {
        if (h != ti_sysbios_knl_Task_getIdleTask()) {
            /* close FD table session for the user.  Don't call if idle task */
            fdCloseSession(h);
        }
    }
    

    其中 ti_ndk_config_global_taskDeleteHook ()的内容基于  tirtos_tivac_2_16_01_14/products/ndk_2_25_00_09/packages/ti/ndk/config/Global. xdt 中的 ti_ndk_config_global_taskExitHook ()

    我已经在附加的项目中测试了修改、并使用 RTOS 对象查看器-> HeapMem ->详细视图来检查 totalFreeSize 现在在每次调用 copyArrayToUsb()后都保持相同的值

    不确定 TI 是否认为内存泄漏是一个应该纠正的错误。

    e2e.ti.com/.../fatsdusbcopy_5F00_EK_5F00_TM4C1294XL_5F00_TI.zip