环境
开发板:正点原子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回车进行访问,访问结果如下
将鼠标放在上方,点击右键->选择“复制链接文字”便能实现文件的下载。
工程源码: