0

我正在尝试在 RTOS 中使用 FATFS 读取 SD 卡上的文件。该卡成功安装在 RTOS 中的单独源文件中,但是当我尝试在自己的源文件中使用 FatFs 操作时,我得到结果 FR_NOT_ENABLED。

这是一个有点奇怪的场景,需要一些背景知识:我是一名电子技术学生,承担了重新利用 MCU 及其专有 RTOS 的相当艰巨的任务。在 RTOS 中,已经有一个安装 SD 卡的源文件(我们称之为 sd.cpp)和另一个将传感器数据文件写入其中的文件(我们称之为 Sensors.cpp)。我已确保在我的源文件中包含所有相关的头文件(为了清楚起见,我们将其称为 myfile.cpp)。

我已经尝试了一些事情:第一个是直接在 myfile.cpp 中实现 f_mount 操作。这导致了 FR_DISK_ERR 结果,据我了解,这是因为它已经安装在另一个文件中,所以这显然不合适。从那里我尝试在 Sensors.cpp 中注释掉 SD 卡的所有实例,但这会打开一个真正的“蠕虫罐”,我宁愿保存它,直到用尽其他选项...

我相信归根结底是弄清楚如何将 SD 工作区从 sd.cpp 传递到 myfile.cpp。我试图研究 Sensors.cpp 以了解它是如何在那里完成的,但不幸的是,它的内容远远超出了我作为电子技术学生的理解范围。

这是一个使用 GNU-ARM 工具链和 OpenOCD 构建工具的 STM32L476RG。

代码都是非常标准的 FATFS 东西。SD.cpp中的SD挂载函数:

FATFS fs;
bool isMounted = false;

FRESULT fsMountSd(){
    FRESULT res = f_mount(&fs, "0:", 1);
    if( res == FR_OK) isMounted = true;
    if (isMounted = true){
    CLI_printMessage("SD Card mounted");
    }
    return res;
}

这将返回 FR_OK 并向 CLI 打印“SD Card Mounted”。

然后在myfile.cpp中有我自己的FatFs操作:

FIL config; //file object of  from the SD card


FRESULT fr;
FILINFO fno;

//check for config.txt file
fr = f_stat("0:config.txt", &fno);    //check for config.txt file

if (fr == FR_OK){
      CLI_printMessage("File found!");
}

这在我在 sd.cpp 模块中运行 f_stat 操作时有效,确认这是在 myfile.cpp 中找不到文件系统对象的问题。

我还尝试在 sd.cpp 挂载函数中使用指针:

FATFS *fs;

bool isMounted = false;

FRESULT fsMountSd(){
    FRESULT res = f_mount(fs, "0:", 1);
    if( res == FR_OK) isMounted = true;
    if (isMounted = true){
    CLI_printMessage("SD Card mounted");
    }
    return res;
}

当我尝试这个时,我还添加了“extern FATFS* fs;”行 到 sd.h 文件。不幸的是,这也没有成功。

值得补充的是,我已经阅读了信息丰富的Fatfs 支持页面上的所有文档。

简而言之:我希望从 myfile.cpp 中的 f_stat(检查文件)中获得 FR_OK,以便继续前进。我希望这足够详细,因为我最后一次在这里提出这个问题的尝试很快(并且可以理解)被否决了!

4

1 回答 1

0

您的 RTOS 似乎正在使用此处完整记录的 ELM FatFs 。

该卡成功安装在 RTOS 中的单独源文件中,但是当我尝试在自己的源文件中使用 FatFs 操作时,我得到结果 FR_NOT_ENABLED。[...] 在 RTOS 中,已经有一个安装 SD 卡的源文件

如果您的意思是文件系统已经挂载,并且您正在第二次挂载它,那么这是不必要的,并且如果挂载相同的卷可能会导致错误。该库为每个卷保存一个指向提供的 FATFS 实例的单个指针,当第一个正在使用时,您不应将其传递给不同的实例。也就是说,我认为应该对其进行检查,因此可能不是这里的问题。

不需要将 FATFS 对象设为全局或外部;它只需要在文件系统操作继续时存在。最好把它static放在 中fsMountSd(),例如:

FRESULT fsMountSd()
{
    static FATFS fs;
    static bool isMounted = false;
    FRESULT res = FR_OK ;

    if( !isMounted )
    {
        res = f_mount(&fs, "0:", 1);
        isMounted = (res == FR_OK) ;
    }

    if( isMounted )
    {
        CLI_printMessage("SD Card mounted");
    }

    return res;
}

我还尝试了路径名的每个配置:“config.txt”、“0:config.txt”、“0:\config.txt”、“0:/config.txt”等。

如果您只有一卷,则可以使用:

    res = f_mount(&fs, "", 1);

挂载默认(仅)卷。

如果您想显式卸载并重新安装,则可以通过将 NULL 传递给f_mount

    if( isMounted )
    {
        f_mount( NULL, "", 1);
    }

    res = f_mount(&fs, "", 1);
    isMounted = (res == FR_OK) ;

但这可能会导致其他线程访问文件系统时出现问题,如果它们当时打开了文件。

[...] 也许有人可以让我知道如何在我自己的函数中调用该指针。

我不确定“调用该指针”是什么意思,指向 FATFS 实例的指针由库内部保存。它不需要“传递”或对其他模块可见。

于 2019-03-30T00:18:26.190 回答