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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> stm32f373 + flash(at25df081) + fatFs
vasilijvs
сообщение Feb 17 2016, 14:15
Сообщение #1





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Добрый день, прошу помочь всех знатоков.
Хочу смонтировать раздел с помощью fatfs, возвращает FR_NO_FILESYSTEM, получается флеш не отформатирована под Fat.
Расскажите, каким образом её отформатировать или как добиться успешного выполнения f_mount()?
Вот здесь fResult получает это значение.
Код
FATFS fatFs;
FRESULT fResult;
      
fResult = f_mount(&fatFs, "0", 1);


Сообщение отредактировал vasilijvs - Feb 17 2016, 14:15
Go to the top of the page
 
+Quote Post
skripach
сообщение Feb 18 2016, 03:56
Сообщение #2


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Цитата(vasilijvs @ Feb 17 2016, 17:15) *
получается флеш не отформатирована под Fat.
Расскажите, каким образом её отформатировать или как добиться успешного выполнения f_mount()?

А документацию на сайте разработчика глянуть не судьба?
...там элементарно ведь все.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
vasilijvs
сообщение Feb 18 2016, 09:45
Сообщение #3





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Цитата(skripach @ Feb 18 2016, 06:56) *
А документацию на сайте разработчика глянуть не судьба?
...там элементарно ведь все.

А можете ткнуть,куда именно глядеть?
Я отчаялся уже

Цитата(vasilijvs @ Feb 18 2016, 12:01) *
А можете ткнуть,куда именно глядеть?
Я отчаялся уже

Разобрался f_mkfs()
Go to the top of the page
 
+Quote Post
vasilijvs
сообщение Feb 19 2016, 09:52
Сообщение #4





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Появился следующий вопрос.
У меня флешка на 1 Мбайт, имеет 16 секторов по 64 Кбайта.
В функции f_mkfs, есть следующий код, который возвращает FR_DISK_ERR и не дает успешно завершить это функцию.

Код
/* Create a partition in this function */
if (disk_ioctl(pdrv, GET_SECTOR_COUNT, &n_vol) != RES_OK || n_vol < 128)
    return FR_DISK_ERR;


Как раз не проходит по второму условию, т.к. количество секторов на моей флешке 16.
Как быть?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 19 2016, 09:58
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(vasilijvs @ Feb 19 2016, 11:52) *
Как быть?
Использовать разбиение вашей флешки на блоки размером 4 К. Получится 256 блоков. Разбиение на сектора в вашей флешке используется только для защиты от записи, а для файловой системы сектор - это единица одновременно стираемой памяти. Ваша память позволяет стирать блок размером 4 К. Этот блок и надо делать сектором файловой системы.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
vasilijvs
сообщение Feb 19 2016, 10:48
Сообщение #6





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Цитата(Сергей Борщ @ Feb 19 2016, 12:58) *
Использовать разбиение вашей флешки на блоки размером 4 К. Получится 256 блоков. Разбиение на сектора в вашей флешке используется только для защиты от записи, а для файловой системы сектор - это единица одновременно стираемой памяти. Ваша память позволяет стирать блок размером 4 К. Этот блок и надо делать сектором файловой системы.

Да,спасибо,сейчас проходит этот момент,но на функции f_open в HardFault падает(

Цитата(vasilijvs @ Feb 19 2016, 13:25) *
Да,спасибо,сейчас проходит этот момент,но на функции f_open в HardFault падает(

Вот в этом куске кода падает, условие не проходит, хотя внутри disk_read всё выполняется и возвращается RES_OK, а обратно управление не возвращается
Код
if (disk_read(fs->drv, fs->win.d8, sector, 1))
    return FR_DISK_ERR;

Что это может быть?
Go to the top of the page
 
+Quote Post
hd44780
сообщение Feb 19 2016, 18:05
Сообщение #7


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



Проверьте FаtFs на предмет размера сектора. Может он где-то считает, что у Вас 512 байт по стандарту.

по поводу disk_read. disk_read(fs->drv, fs->win.d8, sector, 1)) - что такое fs->win.d8?

как я понимаю, это вот это:

Код
................
    DWORD    database;        /* Data start sector */
    DWORD    winsect;        /* Current sector appearing in the win[] */
    BYTE    win[_MAX_SS];    /* Disk access window for Directory, FAT (and Data on tiny cfg) */
} FATFS;


где тут d8? И чему равен _MAX_SS? По дефолту он равен 512. Если Вы сделали сектор в 4К, то и сюда пишите 4096.
И если у Вас disk_read даже не возвращается, а улетает в космос под названием HardFault - то cкорее всего Вы где-то внутри этой функции портите память, в частности, стек, где хранися адрес возврата.
При возврате проц пытается перейти по адресу из стека, но там явно какая-то чепуха. Оно это дело просекает и уходит в HardFault, дабы уберечь систему от непредсказуемости.

Я так думаю sm.gif .


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
KRS
сообщение Feb 19 2016, 19:42
Сообщение #8


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



ЕМНИП в fatfs размер сектора может быть только 512 байт

для файловой системы FTA на stm32 с этой флешкой много возни будет.
надо учитывать что стирается она по 4к, но писать можно по 256 байт...
плюс еще надо бы wear leveling организовать...
Go to the top of the page
 
+Quote Post
skripach
сообщение Feb 19 2016, 21:04
Сообщение #9


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Я бы прослоечку сделал для записи/чтения по 512 байт.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Feb 20 2016, 09:41
Сообщение #10


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

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Цитата(KRS @ Feb 19 2016, 22:42) *
ЕМНИП в fatfs размер сектора может быть только 512 байт


http://elm-chan.org/fsw/ff/en/appnote.html
Limits
FAT sub-types: FAT12, FAT16 and FAT32.
Number of open files: Unlimited. (depends on available memory)
Number of volumes: Upto 10.
File size: Upto 4G-1 bytes. (by FAT specs.)
Volume size: Upto 2T bytes at 512 bytes/sector. (by FAT specs.)
Cluster size: Upto 64K bytes at 512 bytes/sector. (by FAT specs.)
Sector size: 512, 1024, 2048 and 4096 bytes. (by FAT specs.)


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
vasilijvs
сообщение Feb 25 2016, 13:50
Сообщение #11





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Спасибо,за мнения.

Увеличил _MAX_SS, в HardFault уже не падает.
Следующая функция check_fs() вызывается в find_volume() и возвращает значение 2 из-за которого в функции f_open() возвращается FR_NO_FILESYSTEM.
Что ещё можно сделать?
Все функции чтения, записи реализованы, что может быть не так?
Код
static
BYTE check_fs (    /* 0:FAT boor sector, 1:Valid boor sector but not FAT, 2:Not a boot sector, 3:Disk error */
    FATFS* fs,    /* File system object */
    DWORD sect    /* Sector# (lba) to check if it is an FAT boot record or not */
)
{
    fs->wflag = 0; fs->winsect = 0xFFFFFFFF;    /* Invaidate window */
    if (move_window(fs, sect) != FR_OK)            /* Load boot record */
        return 3;

    if (LD_WORD(&fs->win.d8[BS_55AA]) != 0xAA55)    /* Check boot record signature (always placed at offset 510 even if the sector size is >512) */
        return 2;

    if ((LD_DWORD(&fs->win.d8[BS_FilSysType]) & 0xFFFFFF) == 0x544146)        /* Check "FAT" string */
        return 0;
    if ((LD_DWORD(&fs->win.d8[BS_FilSysType32]) & 0xFFFFFF) == 0x544146)    /* Check "FAT" string */
        return 0;

    return 1;
}


Сообщение отредактировал vasilijvs - Feb 25 2016, 13:50
Go to the top of the page
 
+Quote Post
hd44780
сообщение Feb 25 2016, 16:17
Сообщение #12


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

Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980



if (LD_WORD(&fs->win.d8[BS_55AA]) != 0xAA55) /* Check boot record signature (always placed at offset 510 even if the sector size is >512) */
return 2;

Т.е. оно не может найти сигнатуру MBR/бут сектора (тот самый 0xAA55). Убедитесь в её наличии.
При необходимости отформатируйте её функцией mkfs (если правильно название вспомнил).

Если честно, я бы пошёл по пути, предложенному skripach - напишите прослойку для эмуляции 512 байтовых секторов.
Может и сложновато будет, зато не придётся перепахивать весь FatFs в поисках очередного капкана.
Да и потом обновлять версии FatFs проще ...


--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса.
(с) Мария Эдуарда
Go to the top of the page
 
+Quote Post
vasilijvs
сообщение Mar 1 2016, 12:34
Сообщение #13





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Всем спасибо за советы, сделал по 512 сектор.
И действительно, получилось смонтировать систему и создать файл.
Но записывать данные в файл всё равно упорно не хочет sad.gif
Заходя в функцию f_write(), в первой строке пытается выбрать новый кластер, а следом вылетает из функции.
Код
fp->sclust = clst = create_chain(fp->fs, 0);    /* Create a new cluster chain */

if (clst == 0) break;        /* Could not allocate a new cluster (disk full) */

Есть идеи как можно полечить?
Почему он не может найти свободный кластер?

Сообщение отредактировал vasilijvs - Mar 1 2016, 12:35
Go to the top of the page
 
+Quote Post
skripach
сообщение Mar 1 2016, 18:19
Сообщение #14


■ ■ ■ ■
*****

Группа: Свой
Сообщений: 1 100
Регистрация: 9-08-06
Пользователь №: 19 443



Отложите fatfs, напишите простенький тест для нижнего уровня (чтение\запись по 512) и найдите там все косяки, их там есть.


--------------------
Делай что должен и будь что будет.
Go to the top of the page
 
+Quote Post
vasilijvs
сообщение Mar 3 2016, 09:42
Сообщение #15





Группа: Участник
Сообщений: 13
Регистрация: 17-02-16
Пользователь №: 90 493



Цитата(skripach @ Mar 1 2016, 21:19) *
Отложите fatfs, напишите простенький тест для нижнего уровня (чтение\запись по 512) и найдите там все косяки, их там есть.

Написал, попробывал, читаю/пишу, всё корректно, но та же проблема.

Привожу полный код diskio.cpp
CODE
#include "diskio.h"
#include "ff_gen_drv.h"
#include "flash.h"
#include "spi.h"

extern Disk_drvTypeDef disk;
extern Spi spi(GPIO_PIN_10, GPIO_PIN_11, GPIO_PIN_12, GPIO_PIN_2);
extern Flash flash(spi);

/**
* @brief Initializes a Drive
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS disk_initialize(BYTE pdrv)
{
DSTATUS stat = RES_OK;

if(disk.is_initialized[pdrv] == 0)
{
disk.is_initialized[pdrv] = 1;
stat = disk.drv[pdrv]->disk_initialize();
}
return stat;
}

/**
* @brief Gets Disk Status
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS disk_status(BYTE pdrv)
{
DSTATUS stat;

stat = disk.drv[pdrv]->disk_status();
return stat;
}

/**
* @brief Reads Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data buffer to store read data
* @param sector: Sector address (LBA)
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, BYTE count)
{
DWORD realSector = sector * 512;

flash.readArray(realSector, count * 512, buff);

return RES_OK;
}

/**
* @brief Writes Sector(s)
* @param pdrv: Physical drive number (0..)
* @param *buff: Data to be written
* @param sector: Sector address (LBA)
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, BYTE count)
{
DWORD realSector = sector * 512;

for (int i = 0; i < count; ++i)
{
flash.eraseBlock512(realSector + i * 512);
}

for(int i = 0; i < (count * 2); ++i)
{
uint8_t temp[256];
for(int j = 0; j < sizeof(temp); ++j)
{
temp[j] = buff[i * 256 + j];
}
flash.writeData(realSector + i * 256, sizeof(temp), temp);
}

return RES_OK;
}
#endif /* _USE_WRITE == 1 */

/**
* @brief I/O control operation
* @param pdrv: Physical drive number (0..)
* @param cmd: Control code
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
{
DRESULT res = RES_ERROR;

switch (cmd)
{
case CTRL_SYNC:
res = RES_OK;
break;

case GET_SECTOR_COUNT:
*(DWORD*)buff = 2048;
res = RES_OK;
break;

case GET_SECTOR_SIZE:
*(DWORD*)buff = 512;
res = RES_OK;
break;

case GET_BLOCK_SIZE:
*(DWORD*)buff = 512;
res = RES_OK;
break;
}

return res;
}
#endif /* _USE_IOCTL == 1 */

/**
* @brief Gets Time from RTC
* @param None
* @retval Time in DWORD
*/
DWORD get_fattime (void)
{
return 0;
}


Сообщение отредактировал IgorKossak - Mar 4 2016, 13:24
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 26th June 2025 - 08:23
Рейтинг@Mail.ru


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