vasilijvs 0 17 февраля, 2016 Опубликовано 17 февраля, 2016 (изменено) · Жалоба Добрый день, прошу помочь всех знатоков. Хочу смонтировать раздел с помощью fatfs, возвращает FR_NO_FILESYSTEM, получается флеш не отформатирована под Fat. Расскажите, каким образом её отформатировать или как добиться успешного выполнения f_mount()? Вот здесь fResult получает это значение. FATFS fatFs; FRESULT fResult; fResult = f_mount(&fatFs, "0", 1); Изменено 17 февраля, 2016 пользователем vasilijvs Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 5 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба получается флеш не отформатирована под Fat. Расскажите, каким образом её отформатировать или как добиться успешного выполнения f_mount()? А документацию на сайте разработчика глянуть не судьба? ...там элементарно ведь все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilijvs 0 18 февраля, 2016 Опубликовано 18 февраля, 2016 · Жалоба А документацию на сайте разработчика глянуть не судьба? ...там элементарно ведь все. А можете ткнуть,куда именно глядеть? Я отчаялся уже А можете ткнуть,куда именно глядеть? Я отчаялся уже Разобрался f_mkfs() Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilijvs 0 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба Появился следующий вопрос. У меня флешка на 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. Как быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба Как быть?Использовать разбиение вашей флешки на блоки размером 4 К. Получится 256 блоков. Разбиение на сектора в вашей флешке используется только для защиты от записи, а для файловой системы сектор - это единица одновременно стираемой памяти. Ваша память позволяет стирать блок размером 4 К. Этот блок и надо делать сектором файловой системы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilijvs 0 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба Использовать разбиение вашей флешки на блоки размером 4 К. Получится 256 блоков. Разбиение на сектора в вашей флешке используется только для защиты от записи, а для файловой системы сектор - это единица одновременно стираемой памяти. Ваша память позволяет стирать блок размером 4 К. Этот блок и надо делать сектором файловой системы. Да,спасибо,сейчас проходит этот момент,но на функции f_open в HardFault падает( Да,спасибо,сейчас проходит этот момент,но на функции f_open в HardFault падает( Вот в этом куске кода падает, условие не проходит, хотя внутри disk_read всё выполняется и возвращается RES_OK, а обратно управление не возвращается if (disk_read(fs->drv, fs->win.d8, sector, 1)) return FR_DISK_ERR; Что это может быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба Проверьте 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, дабы уберечь систему от непредсказуемости. Я так думаю :) . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 0 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба ЕМНИП в fatfs размер сектора может быть только 512 байт для файловой системы FTA на stm32 с этой флешкой много возни будет. надо учитывать что стирается она по 4к, но писать можно по 256 байт... плюс еще надо бы wear leveling организовать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 5 19 февраля, 2016 Опубликовано 19 февраля, 2016 · Жалоба Я бы прослоечку сделал для записи/чтения по 512 байт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 5 20 февраля, 2016 Опубликовано 20 февраля, 2016 · Жалоба ЕМНИП в 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.) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilijvs 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 (изменено) · Жалоба Спасибо,за мнения. Увеличил _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; } Изменено 25 февраля, 2016 пользователем vasilijvs Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
hd44780 0 25 февраля, 2016 Опубликовано 25 февраля, 2016 · Жалоба 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 проще ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilijvs 0 1 марта, 2016 Опубликовано 1 марта, 2016 (изменено) · Жалоба Всем спасибо за советы, сделал по 512 сектор. И действительно, получилось смонтировать систему и создать файл. Но записывать данные в файл всё равно упорно не хочет :( Заходя в функцию 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) */ Есть идеи как можно полечить? Почему он не может найти свободный кластер? Изменено 1 марта, 2016 пользователем vasilijvs Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
skripach 5 1 марта, 2016 Опубликовано 1 марта, 2016 · Жалоба Отложите fatfs, напишите простенький тест для нижнего уровня (чтение\запись по 512) и найдите там все косяки, их там есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vasilijvs 0 3 марта, 2016 Опубликовано 3 марта, 2016 (изменено) · Жалоба Отложите fatfs, напишите простенький тест для нижнего уровня (чтение\запись по 512) и найдите там все косяки, их там есть. Написал, попробывал, читаю/пишу, всё корректно, но та же проблема. Привожу полный код diskio.cpp #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; } Изменено 4 марта, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться