0

我正在研究 TI 为其 MSP530 LaunchPad 微控制器开发套件提供的 SD 卡应用代码示例。似乎该示例将目录数和文件数限制为每个 10 个(总共 100 个文件),这对于 32GB SD 卡来说似乎过于严格。当前代码编译为使用不到一半的程序空间和不到一半的可用 RAM。我想知道我是否误解了代码,或者代码是否受到其他原因的限制,例如内存中可用的堆栈大小。以下是代码和我的评论。

有几个层:SDCardLogMode、sdcard(SDCardLib)和ff(HAL层)。我已经减少了下面的代码来说明结构但不能运行 - 如果我理解正确并且我的增加允许文件和目录数量的解决方案有缺陷,我会更感兴趣。

SDCardLogMode.c 这里有两个有趣的地方。首先是 char dirs[10][MAX_DIR_LEN] 和 files[10][MAX_FILE_LEN] 的声明。MAX LEN 分别为 8 和 12,是名称的最大允许长度。

/*******************************************************************************
     *
     * SDCardLogMode.c
     * ******************************************************************************/

    #include "stdlib.h"
    #include "string.h"
    #include "SDCardLogMode.h"
    #include "driverlib.h"
    #include "sdcard.h"
    #include "HAL_SDCard.h"

    #pragma PERSISTENT(numLogFiles)
    uint8_t numLogFiles = 0;


    SDCardLib sdCardLib;
    char dirs[10][MAX_DIR_LEN];
    char files[10][MAX_FILE_LEN]; //10 file names. MAX_FILE_LEN =10
    uint8_t dirNum = 0;
    uint8_t fileNum = 0;

    #define MAX_BUF_SIZE 32
    char buffer[MAX_BUF_SIZE];

    // FatFs Static Variables
    static FIL fil;        /* File object */
    static char filename[31];
    static FRESULT rc;

    //....

稍后在同一个 SDCardLogMode.c 文件中是以下函数(为了便于阅读也减少了)。这里有趣的是,代码调用了 SDCardLib_getDirectory(&sdCardLib, "data_log", dirs, &dirNum, files, &fileNum),它使用 "data_log" 路径并生成 dir,并更新 &dirNum、files 和 &fileNum。我不相信 &sdCardLib(它拥有 FATFS 的句柄和一个接口指针)在这个函数中使用。至少我不能说。

令人费解的是调用 SDCardLib_getDirectory() 然后不使用它产生的任何东西有什么意义?我没有发现 dirs 和 files char 数组的任何下游使用。我也没有发现 dirNum 和 fileNum 的任何用途。

在代码片段中,我展示了 SDCardLib_getDirectory() 的代码。我找不到 SDCardLib 参数的使用位置。如前所述,我发现没有使用 files 和 dirs 数组。我可以看到文件和目录计数可用于生成新名称的位置,但已经有静态变量来保存文件计数。谁能看到调用 SDCard_getDirectory() 的原因?

    /*
     * Store TimeStamp from PC when logging starts to SDCard
     */
    void storeTimeStampSDCard()
    {
        int i = 0;
        uint16_t bw = 0;
        unsigned long long epoch;

    //  FRESULT rc;

        // Increment log file number
        numLogFiles++;
,
        //Detect SD card
        SDCardLib_Status st = SDCardLib_detectCard(&sdCardLib);
        if (st == SDCARDLIB_STATUS_NOT_PRESENT) {
            SDCardLib_unInit(&sdCardLib);
            mode = '0';
            noSDCard = 1; //jn added
            return;
        }

    // Read directory and file
        rc = SDCardLib_getDirectory(&sdCardLib, "data_log", dirs, &dirNum, files, &fileNum);

        //Create the directory under the root directory
        rc = SDCardLib_createDirectory(&sdCardLib, "data_log");
        if (rc != FR_OK && rc != FR_EXIST) {
            SDCardLib_unInit(&sdCardLib);
            mode = '0';
            return;
        }

    //........

    }

现在跳转到 sdcard.c(SDCardLib 层)查看 SDCardLib_getDirectory() 很有趣。它将数组指针分配给一维数组(例如 char (*fileList)[MAX_FILE_LEN] 并在每次写入文件名时对其进行索引)。这段代码看起来很脆弱,因为 SDCardLib_createDirectory() 只返回 f_mkdir(directoryName),它不检查已经存在多少文件。也许 TI 假设应该在 SDCardLogMode 之上的应用层进行这种检查......

void SDCardLib_unInit(SDCardLib * lib)
{
    /* Unregister work area prior to discard it */
    f_mount(0, NULL);
}

FRESULT SDCardLib_getDirectory(SDCardLib * lib,
                            char * directoryName, 
                            char (*dirList)[MAX_DIR_LEN], uint8_t *dirNum,
                            char (*fileList)[MAX_FILE_LEN], uint8_t *fileNum)
{
    FRESULT rc;                                            /* Result code */
    DIRS dir;                                               /* Directory object */
    FILINFO fno;                                           /* File information object */
    uint8_t dirCnt = 0;                /* track current directory count */
    uint8_t fileCnt = 0;                /* track current directory count */

    rc = f_opendir(&dir, directoryName);

    for (;;)
    {
        rc = f_readdir(&dir, &fno);                        // Read a directory item
        if (rc || !fno.fname[0]) break;                    // Error or end of dir
        if (fno.fattrib & AM_DIR)                          //this is a directory
        {
            strcat(*dirList, fno.fname);                      //add this to our list of names
            dirCnt++;
            dirList++;
        }
        else                                               //this is a file
        {
            strcat(*fileList, fno.fname);                      //add this to our list of names
            fileCnt++;
            fileList++;
        }
    }

    *dirNum = dirCnt;
    *fileNum = fileCnt;

    return rc;
}

下面是 SDCardLib_createDirectory(SDCardLib *lib, char *directoryName)。它只是创建一个目录,它不检查现有的文件数量。

FRESULT SDCardLib_createDirectory(SDCardLib * lib, char * directoryName)
{
    return f_mkdir(directoryName);
}

所以回到我的问题:

  1. 我是否正确理解了这段代码,它真的将目录和文件的数量限制为 10 个吗?

  2. 如果是这样,为什么文件和目录的数量会如此有限?此示例代码附带的特定 MSP430 具有 256KB 的程序空间和 8KB 的 RAM。编译后的代码消耗不到一半的可用资源(68KB 的程序空间和大约 2.5KB 的 RAM)。是因为任何更大的都会溢出堆栈段吗?

  3. 我想增加可以存储的文件数量。如果我查看底层 FATFS 代码,它不会对文件或目录的数量施加限制(至少直到 sd 卡已满)。如果我从不打算在 MSP430 上显示或搜索目录的内容,我的想法是删除 SDCard_getDirectory() 和两个字符数组(文件和目录)。这会是一个坏主意吗?

4

1 回答 1

0

还有其他内存较少的微控制器。

SDCardLib_getDirectory()函数将其dirListfileList参数视为简单字符串,即,它调用相同strcat()的指针。这意味着它可以读取适合 10*8 或 10*12 字节的名称。

并且在不添加分隔符的情况下调用strcat()意味着不可能从字符串中获取各个名称。

此代码演示了可以使用 FatFs 库,以及需要按什么顺序调用它的函数,但这不一定是如何做到这一点的好例子。我建议您编写自己的代码。

于 2019-03-04T07:22:17.353 回答