llb126yx 发表于 2013-12-7 11:07:44

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************/

llb126yx 发表于 2013-12-7 18:21:56

没有人遇到过吗,帮顶一下啊

llb126yx 发表于 2013-12-21 11:02:32

我自己解决了,是四字节对齐的问题,只要将收发的数组改成这样就可以了
uint8_t Buffer_MultiBlock_Tx __attribute__((at(0X20000200))),
                                Buffer_MultiBlock_Rx __attribute__((at(0X20005200)));

lusson 发表于 2013-12-23 22:18:38

50整除不了4
60和100都可以。

llb126yx 发表于 2013-12-24 22:01:28

lusson 发表于 2013-12-23 22:18
50整除不了4
60和100都可以。

但是这是个治标不治本的问题啊,这个我之前确实是试过了,60和100可以。

meirenai 发表于 2013-12-24 22:27:13

本帖最后由 meirenai 于 2013-12-24 22:28 编辑

llb126yx 发表于 2013-12-21 11:02
我自己解决了,是四字节对齐的问题,只要将收发的数组改成这样就可以了
uint8_t Buffer_MultiBlock_Tx

你这种问题是不是只有使用 4bit 驱动时才会出现啊?、


在什么情况下可以出现这样的问题,没想明白呢。

llb126yx 发表于 2013-12-30 17:00:48

meirenai 发表于 2013-12-24 22:27
你这种问题是不是只有使用 4bit 驱动时才会出现啊?、




使用SDIO驱动当然会选择四线驱动了。我也没怎么看SD的协议,就是移植的官方的例程,整个驱动有2000多行,搞懂了再写很费功夫,也没时间去搞它的。
页: [1]
查看完整版本: STM32F4 M4 SDIO FAFS困惑