реклама на сайте
подробности

 
 
> FATfs и SD-карта, не хочет записываться вновь созданный файл..
Artem
сообщение May 3 2011, 05:29
Сообщение #1


Участник
*

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424



Доброго времени суток! Микроконтроллер STM32 работает с SD картой по SPI. Прицеплена FATfs. Необходимо открыть файл для записи, если файла нет, то создать его и в него записать строку. Но вот в чём проблема, если в файле уже есть хоть один символ, то запись проходит успешно, а если файл только что создали, т.е. его размер равен 0 , то запись не происходит, f_write возвращает FR_INT_ERR. Не могу понять в чём проблема... Помогите кто чем может.. Заранее спасибо.
Вот код:
CODE
void proba ()
{
volatile FRESULT res; // FatFs function common result code
UINT br, bw; // File read/write count
uint8_t str_cnt = 0;

// Register a work area for logical drive 0
f_mount(0, &fs);

// Открываем файл
res = f_open(&fdst, "test_cpy.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if(res)
{
res = res;
}


buffer[0] = 'A';
buffer[1] = 'B';
buffer[2] = 'C';
buffer[3] = 'D';
buffer[4] = 'E';

for(str_cnt = 0; str_cnt < 10; str_cnt++)
{
res = f_lseek(&fdst, fdst.fsize);
br = 5;
res = f_write(&fdst, buffer, br, &bw);
if(res)
{
res = res;
}

f_puts ("Proba \r\n", &fdst);
f_sync (&fdst);
}

f_close(&fdst);

// Unregister a work area before discard it
f_mount(0, NULL);
}


Добавлю:
Файл не пишется размером больше 4033 байт.


Сделал вот так:
CODE
void proba ()
{
volatile FRESULT res; // FatFs function common result code
UINT br, bw; // File read/write count
uint8_t str_cnt = 0;

// Register a work area for logical drive 0
f_mount(0, &fs);

// Открываем файл
res = f_open(&fdst, "test_cpy.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if(res)
{
res = res;
}


buffer[0] = 'A';
buffer[1] = 'B';
buffer[2] = 'C';
buffer[3] = 'D';
buffer[4] = 'E';

for(str_cnt = 0; str_cnt < 10; str_cnt++)
{
res = f_lseek(&fdst, fdst.fsize);
br = 5;
res = f_write(&fdst, buffer, br, &bw);
if(res)
{
res = res;
}

f_puts ("Proba \r\n", &fdst);
f_sync (&fdst);
}

//---------------------------------------------------------------------------------
// Вот этот блок добавил

for(str_cnt = 0; str_cnt < 10; str_cnt++)
{
res = f_lseek(&data_file, ((&data_file)->fsize));

f_puts ("Proba\r\n", &fdst);

f_sync (&data_file);
}
//---------------------------------------------------------------------------------

f_close(&fdst);

// Unregister a work area before discard it
f_mount(0, NULL);
}

и стало писаться с в только что созданный файл, и размер файла не ограничен.
Ничего не понимаю, в чём дело? Что за танцы с бубном?

Сообщение отредактировал IgorKossak - May 4 2011, 14:14
Причина редактирования: [codebox] !!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
*rust*
сообщение May 4 2011, 09:07
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 109
Регистрация: 19-01-11
Пользователь №: 62 335



Цитата
Файл не пишется размером больше 4033 байт.


Быть такого не может. Я использую ту же библиотеку что и Вы, все нормально


Вот пример использования FATfs от ATMEL надеюсь он Вам поможет.
CODE
#include <stdio.h>
#include <string.h>
#include <board.h>
#include <utility/trace.h>
#include <utility/assert.h>
#include <utility/math.h>
#include <memories/MEDSdcard.h>

#include "fatfs_config.h"
#if _FATFS_TINY != 1
#include <fatfs/src/ff.h>
#else
#include <fatfs/src/tff.h>
#endif
#include <fatfs/src/ff_util.h>

//------------------------------------------------------------------------------
// Local constants
//------------------------------------------------------------------------------

/// Maximum number of LUNs which can be defined.
/// (Logical drive = physical drive = medium number)
#define MAX_LUNS 1

/// Available medias.
Media medias[MAX_LUNS];

//------------------------------------------------------------------------------
// Local variables
//------------------------------------------------------------------------------

#define ID_DRV DRV_MMC

#if _FATFS_TINY == 0
#define STR_ROOT_DIRECTORY "0:"
#else
#define STR_ROOT_DIRECTORY ""
#endif

#if defined(at91cap9stk)
#define MCI_ID 1 //no connector for MCIO/SPI0
#else
#define MCI_ID 0
#endif

const char* FileName = STR_ROOT_DIRECTORY "Basic.bin";

#if 0
//Bigger than this value will cause SD HC error now.
//#define DATA_SIZE (7*1024 + 512)
#define DATA_SIZE (9*1024)
//unsigned char data[DATA_SIZE];
unsigned char * data = (unsigned char*)0x60000400;
#else
#define DATA_SIZE 2064 // size of the file to write/read
// !!!minimum size 512 for erase operation !!!

unsigned char data[DATA_SIZE];
#endif

//------------------------------------------------------------------------------
// Local functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// Do file system tests
/// \return test result, 1: success.
//------------------------------------------------------------------------------
static unsigned char RunFsTest(void)
{
unsigned int i;
unsigned int ByteToRead;
unsigned int ByteRead;
#if _FATFS_TINY == 0
unsigned int ByteWritten;
char key;
#endif

FRESULT res;
DIR dirs;
FATFS fs; // File system object
FIL FileObject;

// Init Disk
printf("-I- Please connect a SD card ...\n\r");
while(!MEDSdcard_Detect(&medias[ID_DRV], MCI_ID));
printf("-I- SD card connection detected\n\r");

printf("-I- Init media Sdcard\n\r");
if (!MEDSdcard_Initialize(&medias[ID_DRV], MCI_ID)) {
printf("-E- SD Init fail\n\r");
return 0;
}
numMedias = 1;

// Mount disk
printf("-I- Mount disk %d\n\r", ID_DRV);
memset(&fs, 0, sizeof(FATFS)); // Clear file system object
res = f_mount(ID_DRV, &fs);
if( res != FR_OK ) {
printf("-E- f_mount pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}

// Test if the disk is formated
res = f_opendir (&dirs,STR_ROOT_DIRECTORY);
if(res == FR_OK ){

// erase sdcard to re-format it ?
printf("-I- The disk is already formated.\n\r");

// Display the file tree
printf("-I- Display files contained on the SDcard :\n\r");
FF_ScanDir(STR_ROOT_DIRECTORY);

#if _FATFS_TINY == 0
printf("-I- Do you want to erase the sdcard to re-format disk ? (y/n)!\n\r");

key = DBGU_GetChar();
if( (key == 'y') || (key == 'Y'))
{
for(i=0;i<100;i++) {
MEDSdcard_EraseBlock(&medias[ID_DRV], i);
}
printf("-I- Erase the first 100 blocks complete !\n\r");
res = FR_NO_FILESYSTEM;
}
#endif
}

if( res == FR_NO_FILESYSTEM ) {

#if _FATFS_TINY == 0
//printf("-I- Press 'y' to start format:\n\r");
//if (DBGU_GetChar() != 'y') return 0;
// Format disk
printf("-I- Format disk %d\n\r", ID_DRV);
printf("-I- Please wait a moment during formating...\n\r");
res = f_mkfs(ID_DRV, // Drv
0, // FDISK partition
512); // AllocSize
printf("-I- Format disk finished !\n\r");
if( res != FR_OK ) {
printf("-E- f_mkfs pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}
#else
printf("-I- Please run Full version FAT FS test first\n\r");
return 0;
#endif
}

#if _FATFS_TINY == 0
// Create a new file
printf("-I- Create a file : \"%s\"\n\r", FileName);
res = f_open(&FileObject, FileName, FA_CREATE_ALWAYS|FA_WRITE);
if( res != FR_OK ) {
printf("-E- f_open create pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}

// Write a checkerboard pattern in the buffer
for (i=0; i < sizeof(data); i++) {
if ((i & 1) == 0) {
data[i] = (i & 0x55);
}
else {
data[i] = (i & 0xAA);
}
}
printf("-I- Write file\n\r");
res = f_write(&FileObject, data, DATA_SIZE, &ByteWritten);
printf("-I- ByteWritten=%d\n\r", (int)ByteWritten);
if( res != FR_OK ) {
printf("-E- f_write pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}
else {
printf("-I- f_write ok: ByteWritten=%d\n\r", (int)ByteWritten);
}

// Close the file
printf("-I- Close file\n\r");
res = f_close(&FileObject);
if( res != FR_OK ) {
printf("-E- f_close pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}
#endif

// Open the file
printf("-I- Open the same file : \"%s\"\n\r", FileName);
res = f_open(&FileObject, FileName, FA_OPEN_EXISTING|FA_READ);
if( res != FR_OK ) {
printf("-E- f_open read pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}
ASSERT( FileObject.fsize == DATA_SIZE, "File size value not expected!\n\r");

// Read file
printf("-I- Read file\n\r");
memset(data, 0, DATA_SIZE);
ByteToRead = FileObject.fsize;
res = f_read(&FileObject, data, ByteToRead, &ByteRead);
if(res != FR_OK) {
printf("-E- f_read pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}

// Close the file
printf("-I- Close file\n\r");
res = f_close(&FileObject);
if( res != FR_OK ) {
printf("-E- f_close pb: 0x%X (%s)\n\r", res, FF_GetStrResult(res));
return 0;
}

// compare read data with the expected data
for (i=0; i < sizeof(data); i++) {
ASSERT((((i & 1) == 0) && (data[i] == (i & 0x55)))
|| (data[i] == (i & 0xAA)),
"Invalid data at data[%u] (expected 0x%02X, read 0x%02X)\n\r",
i, ((i & 1) == 0) ? (i & 0x55) : (i & 0xAA), data[i]);
}
printf("-I- File data Ok !\n\r");

return 1;
}

//------------------------------------------------------------------------------
// Global functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/// main
/// FatFs Full version
//------------------------------------------------------------------------------
int main( void )
{
TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
printf("-- Basic FatFS Full Version with SDCard Project %s --\n\r",
SOFTPACK_VERSION);
printf("-- %s\n\r", BOARD_NAME);
printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);

while(1) {
if (RunFsTest()) {
printf("-I- Test passed !\n\r");
}
else {
printf("-F- Test Failed !\n\r");
}
SD_Stop(MEDSdcard_GetDriver(MCI_ID),
MEDSdcard_GetDriver(MCI_ID)->pSdDriver);

printf("\n\r** any key to start test again **\n\r");
DBGU_GetChar();
}

return 0;
}


Сообщение отредактировал IgorKossak - May 4 2011, 14:15
Причина редактирования: [codebox] !!!
Go to the top of the page
 
+Quote Post
Artem
сообщение May 5 2011, 03:59
Сообщение #3


Участник
*

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424



Сделал вот так:
CODE


static FATFS fs; // Work area (file system object) for logical drives
static FIL fdst, data_file; // file objects

void proba ()
{
volatile FRESULT res; // FatFs function common result code
UINT br, bw; // File read/write count
uint8_t str_cnt = 0;

// Register a work area for logical drive 0
f_mount(0, &fs);

// Открываем файл
res = f_open(&data_file, "test_cpy.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if(res)
{
res = res;
}


buffer[0] = 'A';
buffer[1] = 'B';
buffer[2] = 'C';
buffer[3] = 'D';
buffer[4] = 'E';

for(str_cnt = 0; str_cnt < 10; str_cnt++)
{
res = f_lseek(&data_file, data_file.fsize);
br = 5;
res = f_write(&data_file, buffer, br, &bw);
if(res)
{
res = res;
}

f_puts ("Proba \r\n", &data_file);
f_sync (&data_file);
}

//---------------------------------------------------------------------------------
// Вот этот блок добавил

fdst = fdst;
//---------------------------------------------------------------------------------

f_close(&data_file);

// Unregister a work area before discard it
f_mount(0, NULL);
}


Вот только не понятно, почему если оставить неиспользуемый fdst , то всё работает, если его закомментировать, то опять с начала файла не пишет, и размер файла не больше 4033 байт. (забыл сказать , компилятор IAR ARM, FreeRTOS) размер стека увеличивал, не помогает...
что такое может быть?
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 5 2011, 06:28
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Учитывая, что сам FatFS пользуют, неверное, миллионы программистов и она работает, проблема, скорее всего, в той части, которую вы сами к этой библиотеке "прикрутили" - функции физического чтения/записи сектора. Ва бы их внимательно проверили и отладили до FatFS.


Во-вторых, может вы можете свой тест запустить не под FreeDOS? Тогда тоже многое может проясниться.
Go to the top of the page
 
+Quote Post
Artem
сообщение May 5 2011, 07:31
Сообщение #5


Участник
*

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424



Так вот если файл не нулевого размера, эти функции работают же. Файл пишется. Поэтому на них вроде и не думаю. Понятно, что ошибка где то у меня, не понятно только где..
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 5 2011, 10:56
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



На мой взгляд, должно быть что-то типа:


CODE
void proba ()
{
volatile FRESULT res; // FatFs function common result code
UINT br, bw; // File read/write count
uint8_t str_cnt = 0;
static FATFS fs; // Work area (file system object) for logical drives
static FIL fdst, data_file; // file objects

// Register a work area for logical drive 0
f_mount(0, &fs);

res = f_open(&data_file, "test_cpy.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE);
if(res != FR_OK)
{
printf("ERR : %d\n", res);
f_close(&data_file);
return;
}


buffer[0] = 'A';
buffer[1] = 'B';
buffer[2] = 'C';
buffer[3] = 'D';
buffer[4] = 'E';

if(data_file.fsize)
res = f_lseek(&data_file, data_file.fsize); // goto to the end of file only,
// if file exist

if(res != FR_OK)
{
printf("ERR : %d\n", res);
f_close(&data_file);
return;
}

for(str_cnt = 0; str_cnt < 10; str_cnt++)
{
res = f_write(&data_file, buffer, 5, &bw);
if(res != FR_OK)
{
printf("ERR : %d\n", res);
f_close(&data_file);
return;
}

f_puts("Proba \r\n", &data_file);
}


f_close(&data_file);

// Unregister a work area before discard it
f_mount(0, NULL);
}


Сообщение отредактировал IgorKossak - May 5 2011, 12:19
Причина редактирования: [codebox] !!!
Go to the top of the page
 
+Quote Post
Artem
сообщение May 6 2011, 06:38
Сообщение #7


Участник
*

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424



Спасибо, Ваш пример работает. Переработал свой код по образу и подобию, тоже заработало. Спасибо!
Go to the top of the page
 
+Quote Post
dimasusl
сообщение Jun 23 2011, 13:26
Сообщение #8





Группа: Новичок
Сообщений: 4
Регистрация: 1-12-08
Пользователь №: 42 111



Цитата(Artem @ May 6 2011, 09:38) *
Спасибо, Ваш пример работает. Переработал свой код по образу и подобию, тоже заработало. Спасибо!

Artem, добрый день. У меня аналогичный набор (stm32+fatfs+freertos) и абсолютно та же проблема. При этом я ранее реализовывал эту связку на более старшем проце, только там был SDIO, а не SPI как здесь. Вроде делаю все как у вас заработало - у меня эффект ноль. Можете скинуть ваши исходники относительно Fatfs (ff.c diskio.c и т.п.) на мыло dimasusl@gmail.com?

Цитата(dimasusl @ Jun 23 2011, 16:00) *
Artem, добрый день. У меня аналогичный набор (stm32+fatfs+freertos) и абсолютно та же проблема. При этом я ранее реализовывал эту связку на более старшем проце, только там был SDIO, а не SPI как здесь. Вроде делаю все как у вас заработало - у меня эффект ноль. Можете скинуть ваши исходники относительно Fatfs (ff.c diskio.c и т.п.) на мыло dimasusl@gmail.com?

Блин, занятное дело...

Был код
Код
res = f_mount(0, &fs);
res = f_open(&fsrc, "spi1.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE );
if (fsrc.fsize) res = f_lseek(&fsrc, fsrc.fsize);
res = f_write(&fsrc, usb_buffer, sizeof(usb_buffer), &br);
res = f_close(&fsrc);
res = f_mount(0, NULL);

Файл создавался, но данные в него не писались (если сделать ненулевой размер файла то все Ок).
Подсмотрел тут что еще юзаете для своих целей f_puts(...)
Код
res = f_mount(0, &fs);
res = f_open(&fsrc, "spi1.txt", FA_OPEN_ALWAYS | FA_READ | FA_WRITE );
if (fsrc.fsize) res = f_lseek(&fsrc, fsrc.fsize);
res = f_puts("",&fsrc); // Пустая строка, чтобы не "ломать" формат файла
res = f_write(&fsrc, usb_buffer, sizeof(usb_buffer), &br);
res = f_close(&fsrc);
res = f_mount(0, NULL);

и стало все Ок и при нулевом размере файла. Откуда ноги растут так и не ясно

Go to the top of the page
 
+Quote Post
Artem
сообщение Jun 24 2011, 06:02
Сообщение #9


Участник
*

Группа: Свой
Сообщений: 72
Регистрация: 4-02-05
Пользователь №: 2 424



Добрый день. У меня проблема была с файлом sdc_diskio.c (низкоуровневые функции работы с SD). А если ещё точнее, то проблема была с функцией Receive_DataBlock. Получалось, что я при чтении вылезал за область памяти прёмного буфера, и при этом портил структуру fs. После устранения, проблемы исчезли.

PS. Письмо отправил
Go to the top of the page
 
+Quote Post
dimasusl
сообщение Jun 24 2011, 06:35
Сообщение #10





Группа: Новичок
Сообщений: 4
Регистрация: 1-12-08
Пользователь №: 42 111



Цитата(Artem @ Jun 24 2011, 09:02) *
Добрый день. У меня проблема была с файлом sdc_diskio.c (низкоуровневые функции работы с SD). А если ещё точнее, то проблема была с функцией Receive_DataBlock. Получалось, что я при чтении вылезал за область памяти прёмного буфера, и при этом портил структуру fs. После устранения, проблемы исчезли.

PS. Письмо отправил


Ответил на мыло, но напишу и тут, вдруг кому будет полезно

Код
static
BOOL Receive_DataBlock(
    BYTE *buff,            /* Data buffer to store received data */
    UINT btr            /* Byte count (must be multiple of 4) */
)
{
    BYTE token;
    MMC_SELECT(); // !!!!!!!!!! ДОБАВИЛ ЭТО !!!!!!!!!!!!!!!!
    Timer1 = 10;
    do {                            /* Wait for data packet in timeout of 100ms */
        token = SPI_ReadWrite_Byte(0xff);
    } while ((token == 0xFF) && Timer1);
    if(token != 0xFE) return FALSE;    /* If not valid data token, retutn with error */

    btr--;  //!!!!!!!!!! И ДОБАВИЛ ЭТО !!!!!!!!!!
    do {                            /* Receive the data block into buffer */
        *buff++ = SPI_ReadWrite_Byte(0xff);
    } while (btr--);
    SPI_ReadWrite_Byte(0xff);        /* Discard CRC */
    SPI_ReadWrite_Byte(0xff);

    return TRUE;                    /* Return with success */
}
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01483 секунд с 7
ELECTRONIX ©2004-2016