【无标题】cubmax h743之lwip+freertos+fatfs制作ftp服务器调试心得

文章描述了在STM32H743开发板上使用FreeRTOS、FatFS和LwIP进行文件系统和网络功能调试遇到的问题及解决方案。问题包括FatFS的挂载失败、HardFault异常、D_CACHE引起的读取错误,以及FTP服务器的数据socket内存分配和浏览器访问文件列表的兼容性问题。解决方案涉及到修改SD卡初始化、任务执行上下文、MPU配置和堆大小调整等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境

开发板:正点原子stm32h743
Fatfs版本:0.12c
Lwip版本:2.1.2

FreeRtos+Fatfs调试

问题一、无法挂载文件系统,f_mount()失败
解决:将bsp_driver_sd.c中初始化BSP_SD_Init()函数中HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B)修改为
HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_1B)
如下图所示在这里插入图片描述
问题二、能够挂载文件系统了,但是执行测试代码时,进入void HardFault_Handler(void)。
解决:由于使用了freertos,测试函数需要在任务中执行。

问题三、在对文件系统进行读操作时,报错FR_INT_ERR.
解决:这个问题是一个大坑,因为使能了D_CACHE,需要将sd_diskio.c中的两个宏定义打开
在这里插入图片描述
但是打开后,必须要将这里改为32字节对齐
在这里插入图片描述
至此freertos+fatfs文件系统能够正常运行,测试代码在网上抄的,如下
BYTE work[512];
void fatfs_test(void)
{
printf(“\r\n******This is FatFs Example ******\r\n\r\n”);
f_res = f_mount(&SDFatFS, SDPath, 1);

if(f_res == FR_NO_FILESYSTEM)
{
    printf("sd not exsit file system\r\n");
    f_res = f_mkfs(SDPath, FM_FAT32, 0,work,sizeof(work));
    if(f_res == FR_OK)
    {
        printf("create file system successed\r\n");
        //FATFS_UnLinkDriver("0:");
        f_res = f_mount(NULL, SDPath, 1);
        printf("f_mount cancel state %d\r\n", f_res);
        f_res = f_mount(&SDFatFS, SDPath, 1);//re

        printf("f_mount state %d\r\n", f_res);
    }
    else
    {
        printf("init error\n");
        return;
    }
}
else if(f_res != FR_OK)
{
    printf(" f_mount error : %d \r\n", f_res);
    //while(1);
    return;
}
else
{
    printf(" f_mount sucess!!! \r\n");
}
f_res = f_open(&file, "0:CUBE.txt", FA_CREATE_ALWAYS | FA_WRITE);
if(f_res == FR_OK)
{
    printf(" open file sucess!!! \r\n");

    f_res = f_write(&file, WriteBuffer, sizeof(WriteBuffer), &fnum);
    if(f_res == FR_OK)
    {
        printf(" write file sucess!!! file len = %d\n", fnum);
        printf(" write Data = %s\r\n", WriteBuffer);
    }
    else
    {
        printf(" write file error : %d\r\n", f_res);
    }
    f_close(&file);
}
else
{
    printf(" open file error : %d\r\n", f_res);
}

//读取文件
f_res = f_open(&file, "0:CUBE.txt", FA_OPEN_EXISTING | FA_READ);
if(f_res == FR_OK)
{
    printf(" open file sucess!!! \r\n");
    f_res = f_read(&file, ReadBuffer, sizeof(ReadBuffer), &fnum);
    if(f_res == FR_OK)
    {
        printf("read sucess!!! file len = %d\r\n", fnum);
        printf("read Data : %s\r\n", ReadBuffer);
    }
    else
    {
        printf(" read error!!! %d\r\n", f_res);
    }
}
else
{
    printf(" open file error : %d\r\n", f_res);
}
f_close(&file);//关闭文件
f_mount(NULL, SDPath, 1);//取消挂载

}

FreeRtos+lwip调试

问题一、从cubmax上生成的代码直接进入HardFault_Handler(void),
解决:需要修改两个地方
①:将freeRtos的StartDefaultTask任务堆栈加大,我直接弄了1k.
②:配置内存管理,配置如下,在网上抄的某个大佬的,空了再去找一个大佬的博客,到时候贴上来
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};

/* Disables the MPU /
HAL_MPU_Disable();
/
* Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x30040000;
MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;

HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x30044000;
MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;

HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

特别注意:phy芯片的复位引脚需要正确配置。我用的正点原子的开发板,就直接抄了他的代码了。

Freertos + lwip + fatfs + ftp服务器

问题一、在启用ftp服务器后,数据socket无法申请内存,由于我在网上找的这个ftp服务器代码用的是malloc,所以在启动文件中,将堆的大小增加到0x1000,估计这个值很大了,实际应该用不了这么大,但是目前是调试,就不关心了,其实我觉得最好的方法应该是用freertos或者用lwip的内存管理来申请都比这个好。哈哈,个人愚见

问题二、通过360浏览器访问服务器时,无法成功获取的文件列表。经过排查,抄的这个服务器在被动模式下工作不稳定。问题还没有找到,但是在主动模式下是可以正常工作的,于是将360浏览器配置为主动模式,配置流程如下 “工具” ——>“internet选项”–> "高级” 然后将红色框处点击取消
在这里插入图片描述
最终通过ftp:// 填写自己的IP地址 eg: ftp://192.168.0.223回车进行访问,访问结果如下
在这里插入图片描述
将鼠标放在上方,点击右键->选择“复制链接文字”便能实现文件的下载。

工程源码:

<think>好的,用户想了解如何在FreeRTOS中实现或使用FTP功能。首先,我需要回忆一下FreeRTOS的基本特性,它是一个实时操作系统,常用于嵌入式系统。接下来,FTP功能需要网络协议栈的支持,所以应该考虑使用LWIP这样的轻量级TCP/IP协议栈。结合之前用户提供的引用,比如引用1提到STM32F4结合FreeRTOSFATFSLWIP实现FTP服务器,这说明可能需要这几个组件的配合。 然后,用户的问题可能涉及具体步骤,比如如何配置FreeRTOS任务,如何集成FTP服务器,以及如何处理文件系统。需要分步骤来解答,确保结构清晰。同时,用户可能关心代码示例或者配置要点,比如网络初始化和任务创建。还要注意引用中的其他项目,比如引用2提到ESP32使用FreeRTOS进行环境监测,并集成FTP服务器,这可能涉及到Wi-Fi连接和任务并发处理。引用3则涉及IAP和HTTP,虽然主要是TCP/UDP,但说明网络配置的重要性。需要确保回答覆盖硬件准备、软件组件、配置步骤、代码结构以及常见问题。可能用户会遇到网络不稳定或者内存不足的问题,需要给出解决建议。最后,生成相关问题,帮助用户深入理解,比如性能优化或安全机制。</think>### FreeRTOS中实现FTP功能的步骤与方法 #### 一、系统架构组成 在FreeRTOS中实现FTP功能需要以下核心组件的协同工作: 1. **FreeRTOS**:提供多任务调度机制,支持FTP服务器作为独立任务运行。 2. **LWIP协议栈**:实现TCP/IP网络通信,FTP协议基于此构建。 3. **FATFS文件系统**:管理本地存储设备(如SD卡)的读写操作[^1]。 4. **硬件平台**:如STM32F4或ESP32,需具备网络接口(以太网或Wi-Fi)和存储介质。 #### 二、实现步骤 1. **硬件初始化**: - 配置网络接口(如以太网PHY芯片或Wi-Fi模块)。 - 初始化存储设备(SD卡或Flash),挂载FATFS文件系统。 2. **软件组件集成**: ```c // FreeRTOS任务创建示例 void create_ftp_task(void) { xTaskCreate(ftp_server_task, "FTP", 4096, NULL, 2, NULL); } ``` - **LWIP配置**:在`lwipopts.h`中启用FTP所需的TCP并发连接和缓冲区设置。 - **FTP服务器实现**:使用开源库如`ftpd`或自定义实现,需处理`PORT/PASV`模式、文件传输命令(`STOR/RETR`)。 3. **关键代码结构**: ```c // FTP服务器任务示例(基于ESP32) void ftp_server_task(void *pvParameters) { ftp_init(21); // 监听端口21 while (1) { ftp_process(); // 处理客户端请求 vTaskDelay(pdMS_TO_TICKS(10)); } } ``` 4. **网络与文件系统对接**: - 将LWIP的`socket`操作映射到FreeRTOS任务中。 - 通过FATFS接口实现文件路径解析,例如`f_open()`和`f_write()`的调用[^1][^2]。 #### 三、性能优化与调试 1. **内存管理**: - 调整FreeRTOS堆大小(`configTOTAL_HEAP_SIZE`),确保FTP任务和网络缓冲区的内存需求。 - 使用LWIP的`MEM_SIZE`优化数据包缓存。 2. **并发控制**: - 通过FreeRTOS信号量(Semaphore)保护共享资源(如文件句柄)。 - 限制同时活跃的FTP连接数,避免任务阻塞。 3. **典型问题解决**: - **连接不稳定**:检查网络驱动中断优先级是否与FreeRTOS兼容。 - **传输速度低**:优化DMA传输或增大TCP窗口大小(`TCP_WND`)。 #### 四、应用场景示例 - **工业设备远程升级**:通过FTP传输固件文件,结合IAP实现现场更新[^3]。 - **数据采集系统**:将传感器数据保存到SD卡,并通过FTP远程导出[^2]。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值