搜索
bottom↓
回复: 6

STM32F4 M4 SDIO FAFS困惑

[复制链接]

出0入0汤圆

发表于 2013-12-7 11:07:44 | 显示全部楼层 |阅读模式
小弟最近使用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[BLOCK_SIZE], Buffer_Block_Rx[BLOCK_SIZE];
uint8_t readbuff[BLOCK_SIZE];
uint8_t Buffer_MultiBlock_Tx[MULTI_BUFFER_SIZE], Buffer_MultiBlock_Rx[MULTI_BUFFER_SIZE];
uint8_t cpath[num]={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[50];  就是这个数组惹得祸

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] = 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;
        }
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: 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************/

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2013-12-7 18:21:56 | 显示全部楼层
没有人遇到过吗,帮顶一下啊

出0入0汤圆

 楼主| 发表于 2013-12-21 11:02:32 | 显示全部楼层
我自己解决了,是四字节对齐的问题,只要将收发的数组改成这样就可以了
uint8_t Buffer_MultiBlock_Tx[MULTI_BUFFER_SIZE] __attribute__((at(0X20000200))),
                                Buffer_MultiBlock_Rx[MULTI_BUFFER_SIZE] __attribute__((at(0X20005200)));

出0入54汤圆

发表于 2013-12-23 22:18:38 | 显示全部楼层
50整除不了4
60和100都可以。

出0入0汤圆

 楼主| 发表于 2013-12-24 22:01:28 | 显示全部楼层
lusson 发表于 2013-12-23 22:18
50整除不了4
60和100都可以。

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

出0入0汤圆

发表于 2013-12-24 22:27:13 | 显示全部楼层
本帖最后由 meirenai 于 2013-12-24 22:28 编辑
llb126yx 发表于 2013-12-21 11:02
我自己解决了,是四字节对齐的问题,只要将收发的数组改成这样就可以了
uint8_t Buffer_MultiBlock_Tx[MULT ...


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


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

出0入0汤圆

 楼主| 发表于 2013-12-30 17:00:48 | 显示全部楼层
meirenai 发表于 2013-12-24 22:27
你这种问题是不是只有使用 4bit 驱动时才会出现啊?、

使用SDIO驱动当然会选择四线驱动了。我也没怎么看SD的协议,就是移植的官方的例程,整个驱动有2000多行,搞懂了再写很费功夫,也没时间去搞它的。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 01:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表