STM32F4 M4 SDIO FAFS困惑
小弟最近使用M4的SDIO驱动SD卡,移植FAFSR 0.10已经成功,测试程序非常简单,读写完全正常。可是最近发现一个问题,当我向主程序中定义一个全局的数据后,数组大小为50个字节。这个数据并没有使用,但当我向SD卡中写入数据时,前两个字节的数据就全部是0,从第三个节字节开始才是我想要写入的第一个数据,当我修改那个数组的大小,讲50变为60或者100后写入就正常了。程序再复杂些的时候,再定义的个别数组还会引起读出数据错误,同样也是前两个字节不对,小弟已经反复试验过好几次,都是这样,只要修改了数组大小,就可以解决问题,但这个令我困惑不已,M4的内存也不小了,我定义的数组也就那么点,而且还没有引用,怎么会导致这个问题,无论如何也不会想到是那个数组的问题,小弟认为还有其他我不知道的原因,还望大家赐教。顺便说一声,小弟用的编译器是MDK4.72的。现附上主程序:/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
#include "sdio_sdcard.h"
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include "integer.h"
#include "ff.h"
#include "diskio.h"
/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
/* Private define ------------------------------------------------------------*/
#define BLOCK_SIZE 512 /* Block Size in Bytes */
#define NUMBER_OF_BLOCKS 32/* For Multi Blocks operation (Read/Write) */
#define MULTI_BUFFER_SIZE (BLOCK_SIZE * NUMBER_OF_BLOCKS) //缓冲区大小
#define num 60
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t Buffer_Block_Tx, Buffer_Block_Rx;
uint8_t readbuff;
uint8_t Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx;
uint8_t cpath={0};
volatile TestStatus EraseStatus = FAILED, TransferStatus1 = FAILED, TransferStatus2 = FAILED;
SD_Error Status = SD_OK;
extern SD_CardInfo SDCardInfo;
int i;
__IO uint32_t TimeDelay;
/* Private function prototypes -----------------------------------------------*/
void SD_EraseTest(void);
void SD_SingleBlockTest(void);
void SD_MultiBlockTest(void);
void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset);
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength);
TestStatus eBuffercmp(uint8_t* pBuffer, uint32_t BufferLength);
char cpath;就是这个数组惹得祸
void WriteReadFileTest(void);
uint8_t checkFRESULT(FRESULT res);
/* Private functions ---------------------------------------------------------*/
FATFS fs; // Work area (file system object) for logical drive
FIL fsrc, fdst; // file objects
FRESULT res; // FatFs function common result code
UINT br, bw; // File R/W count
int main(void)
{
NVIC_Conf();
USART_Conf();
/*------------------------------ SD Init ---------------------------------- */
Status = SD_Init();
printf( "\r\n 这是一个MicroSD卡实验(没有跑文件系统).........\r\n " );
if(Status == SD_OK) //检测初始化是否成功
{
printf( " \r\n SD_Init 初始化成功 \r\n " );
}
else
{
printf("\r\n SD_Init 初始化失败 \r\n" );
printf("\r\n 返回的Status的值为: %d \r\n",Status );
}
WriteReadFileTest();
res = f_open(&fsrc, "t3.txt", FA_OPEN_EXISTING | FA_READ);
if ( checkFRESULT ( res ) == 0 )
{
printf("\r\n打开文件(读操作)失败 \r\n");
}
else
{
br=1;
printf("\r\n打开文件(读操作)成功。。。\r\n");
printf("\r\n\t开始读取文件。。。\r\n");
res = f_read(&fsrc, Buffer_MultiBlock_Rx, sizeof(Buffer_MultiBlock_Rx), &br);
if ( checkFRESULT ( res ) == 0 )
{
printf("\r\n\t\t读文件失败 \r\n");
}
else
{
printf("\r\n\t\t读文件成功 \r\n");
printf("%s", Buffer_MultiBlock_Rx);
}
f_close(&fsrc);
}
while (1)
{}
}
/*
* 函数名:Buffercmp
* 描述:比较两个缓冲区中的数据是否相等
* 输入:-pBuffer1, -pBuffer2 : 要比较的缓冲区的指针
* -BufferLength 缓冲区长度
* 输出:-PASSED 相等
* -FAILED 不等
*/
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength)
{
while (BufferLength--)
{
if (*pBuffer1 != *pBuffer2)
{
return FAILED;
}
pBuffer1++;
pBuffer2++;
}
return PASSED;
}
/*
* 函数名:Fill_Buffer
* 描述:在缓冲区中填写数据
* 输入:-pBuffer 要填充的缓冲区
* -BufferLength 要填充的大小
* -Offset 填在缓冲区的第一个值
* 输出:无
*/
void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)
{
uint16_t index = 0;
/* Put in global buffer same values */
for (index = 0; index < BufferLength; index++ )
{
pBuffer = index + Offset;
}
}
/*
* 函数名:eBuffercmp
* 描述:检查缓冲区的数据是否为0
* 输入:-pBuffer 要比较的缓冲区
* -BufferLength 缓冲区长度
* 输出:PASSED 缓冲区的数据全为0
* FAILED 缓冲区的数据至少有一个不为0
*/
TestStatus eBuffercmp(uint8_t* pBuffer, uint32_t BufferLength)
{
while (BufferLength--)
{
/* In some SD Cards the erased state is 0xFF, in others it's 0x00 */
if ((*pBuffer != 0xFF) && (*pBuffer != 0x00))//擦除后是0xff或0x00
{
return FAILED;
}
pBuffer++;
}
return PASSED;
}
void WriteReadFileTest(void)
{
// FRESULT res = FR_OK; /* File function return code (FRESULT) */
// FILINFO finfo; /* File status structure */
// DIR dirs; /* Directory object structure */
// char path[]={"0:/bigbigbig"};
// char name[]={"bigdata.txt"};
Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 6);
disk_initialize(0);
f_mount(&fs,"0",1);
f_mkdir("0:/big17");
res = f_open(&fdst, "0:/big17/bigdata.txt", FA_CREATE_ALWAYS | FA_WRITE );
// if ( res == FR_EXIST )
// {
// printf("\r\n文件已存在!\r\n");
// res = f_open(&fdst, "0:/bigbigbig/bigdata.txt", FA_WRITE );
// }
// else
// {
// res = f_open(&fdst, "0:/bigbigbig/bigdata.txt", FA_CREATE_NEW | FA_WRITE );
// }
if( checkFRESULT ( res ) == 0 )
{
printf("\r\n 打开文件(写操作)失败 \r\n");
return;
}
else
{
br=1;
printf("\r\n打开文件(写操作)成功。。。\r\n");
printf("\r\n\t开始写入文件。。。\r\n");
res = f_write(&fdst, Buffer_MultiBlock_Tx, sizeof(Buffer_MultiBlock_Tx), &br);
if (checkFRESULT ( res ) == 0 )
{
printf("\r\n\t\t写文件失败 \r\n");
return;
}
else
{
printf("\r\n\t\t写文件成功 \r\n");
}
f_close(&fdst);
}
br=1;
res = f_open(&fsrc, "0:/big17/bigdata.txt", FA_OPEN_EXISTING | FA_READ);
if ( checkFRESULT ( res ) == 0 )
{
printf("\r\n打开文件(读操作)失败 \r\n");
return;
}
else
{
br=1;
printf("\r\n打开文件(读操作)成功。。。\r\n");
printf("\r\n\t开始读取文件。。。\r\n");
res = f_read(&fsrc, Buffer_MultiBlock_Rx, sizeof(Buffer_MultiBlock_Rx), &br);
if ( checkFRESULT ( res ) == 0 )
{
printf("\r\n\t\t读文件失败 \r\n");
return;
}
else
{
printf("\r\n\t\t读文件成功 \r\n");
// printf("%s", Buffer_MultiBlock_Rx);
}
f_close(&fsrc);
}
if ( Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE))
{
printf("\r\n文件读写测试正确\r\n");
return;
}
else
{
printf("\r\n文件读写测试错误\r\n");
return;
}
}
uint8_t checkFRESULT(FRESULT res)
{
if (res == FR_OK)
{
printf("\r\nsucceed!\r\n");
return 1;
}
else if (res == FR_DISK_ERR)
{
printf("\r\nA hard error occurred in the low level disk I/O layer!\r\n");
return 0;
}
else if (res == FR_INT_ERR)
{
printf("\r\nAssertion failed!\r\n");
return 0;
}
else if (res == FR_NOT_READY)
{
printf("\r\nThe physical drive cannot work!\r\n");
return 0;
}
else if (res == FR_NO_FILE)
{
printf("\r\nCould not find the file!\r\n");
return 0;
}
else if (res == FR_NO_PATH)
{
printf("\r\nCould not find the path!\r\n");
return 0;
}
else if (res == FR_INVALID_NAME)
{
printf("\r\nThe path name format is invalid!\r\n");
return 0;
}
else if (res == FR_DENIED)
{
printf("\r\nAccess denied due to prohibited access or directory full!\r\n");
return 0;
}
else if (res == FR_EXIST)
{
printf("\r\nAccess denied due to prohibited access!\r\n");
return 0;
}
else if (res == FR_INVALID_OBJECT)
{
printf("\r\nThe file/directory object is invalid!\r\n");
return 0;
}
else if (res == FR_WRITE_PROTECTED)
{
printf("\r\nThe physical drive is write protected!\r\n");
return 0;
}
else if (res == FR_INVALID_DRIVE)
{
printf("\r\nThe logical drive number is invalid!\r\n");
return 0;
}
else if (res == FR_NOT_ENABLED)
{
printf("\r\nThe volume has no work area!\r\n");
return 0;
}
else if (res == FR_NO_FILESYSTEM)
{
printf("\r\nThere is no valid FAT volume\r\n");
return 0;
}
else if (res == FR_MKFS_ABORTED)
{
printf("\r\nThe f_mkfs() aborted due to any parameter error!\r\n");
return 0;
}
else if (res == FR_TIMEOUT)
{
printf("\r\nCould not get a grant to access the volume within defined period!\r\n");
return 0;
}
// else if (res == FR_NOT_ENOUGH_CORE)
// {
// printf("\r\nLFN working buffer could not be allocated!\r\n");
// }
// else if (res == FR_LOCKED)
// {
// printf("\r\nThe operation is rejected according to the file sharing policy!\r\n");
// }
// else if (res == FR_TOO_MANY_OPEN_FILES)
// {
// printf("\r\nNumber of open files > _FS_SHARE!\r\n");
// }
// else if (res == FR_INVALID_PARAMETER)
// {
// printf("\r\nGiven parameter is invalid!\r\n");
// }
else
{
return 0;
}
}
#ifdefUSE_FULL_ASSERT
/**
* @briefReports the name of the source file and the source line number
* where the assert_param error has occurred.
* @paramfile: pointer to the source file name
* @paramline: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
printf("\r\n Wrong parameters value: file %s on line %d \r\n", file, line);
while (1)
{}
}
#endif
/******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/
没有人遇到过吗,帮顶一下啊 我自己解决了,是四字节对齐的问题,只要将收发的数组改成这样就可以了
uint8_t Buffer_MultiBlock_Tx __attribute__((at(0X20000200))),
Buffer_MultiBlock_Rx __attribute__((at(0X20005200)));
50整除不了4
60和100都可以。 lusson 发表于 2013-12-23 22:18
50整除不了4
60和100都可以。
但是这是个治标不治本的问题啊,这个我之前确实是试过了,60和100可以。 本帖最后由 meirenai 于 2013-12-24 22:28 编辑
llb126yx 发表于 2013-12-21 11:02
我自己解决了,是四字节对齐的问题,只要将收发的数组改成这样就可以了
uint8_t Buffer_MultiBlock_Tx
你这种问题是不是只有使用 4bit 驱动时才会出现啊?、
在什么情况下可以出现这样的问题,没想明白呢。
meirenai 发表于 2013-12-24 22:27
你这种问题是不是只有使用 4bit 驱动时才会出现啊?、
使用SDIO驱动当然会选择四线驱动了。我也没怎么看SD的协议,就是移植的官方的例程,整个驱动有2000多行,搞懂了再写很费功夫,也没时间去搞它的。
页:
[1]