Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: CycloneII и NAND Flash
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
torik
Всем привет.
Итак, на плате с CycloneII имеется NAND Flash (от микрона, хотя это не суть важно, т.к. интерфейс один у всех).

Для начала пробую работать с этой памятью с помощью Nios через PIO.

Первая же простейшая операция чтения ID явно происходит неверно. 5 байт вместо ID кода получаю 0xfe,0x00,0x00,0x00,0xbc.
Выкладываю код подпрограммы чтения ID и картинку, по которой я это делаю.

Код
void flash_r_id (unsigned char* res) {
    unsigned int i;
    
    IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_F_DQ_BASE, 1); //данные на выход
    
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_ALE_BASE,0);    //ALE = 0
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_CE1_N_BASE,0);    //CE = 0
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_CLE_BASE,1);    //CLE = 1
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_WE_N_BASE,0);    //WE = 0
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_RE_N_BASE,1);    //RE = 1
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_DQ_BASE,0x90);    //
    flash_delay();

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_WE_N_BASE,1);    //WE = 1
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_CLE_BASE,0);    //CLE = 0
    flash_delay();
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_ALE_BASE,1);    //ALE = 1
    flash_delay();

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_WE_N_BASE,0);    //WE = 0
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_DQ_BASE,0x00);    //
    flash_delay();
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_WE_N_BASE,1);    //WE = 1
    flash_delay();
    flash_delay();
    flash_delay();
    flash_delay();
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_ALE_BASE,0);    //ALE = 0
    flash_delay();
    flash_delay();
    flash_delay();

    IOWR_ALTERA_AVALON_PIO_DIRECTION(PIO_F_DQ_BASE, 0); //данные на вход
    for (i = 0; i < 5; i++) {
        IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_RE_N_BASE,0);    //RE = 0
        flash_delay();
        flash_delay();
        *res = IORD_ALTERA_AVALON_PIO_DATA(PIO_F_DQ_BASE);
        IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_RE_N_BASE,1);    //RE = 1
    }

    IOWR_ALTERA_AVALON_PIO_DATA(PIO_F_CE1_N_BASE,1);    //CE = 0



}

void flash_delay() {
    unsigned char i;
    for(i = 0; i < 100; i++){};
}


Вот, поглядите, может что забыл или вовсе не то делаю?
torik
Вобщем-то в приведенном куске кода две глупых ошибки. Они исправлены, уже попробовал записать и прочитать флешку... Но непонятности и трудности возникнут. Удручает то, что, похоже, мало кто запаривается с этими нандами...
torik
Вот еще вопрос появился.
в каждой странице памяти 2192 байта, их можно использовать все или с адреса 2048 есть какие-то ограничения?
Просто не хочу файловую систему организовывать и контроль ошибок, хочу просто использовать дополнительное место для служебных данных...
Alex11
Использовать можно, но помните о возможности возникновения bad-блоков на лету. Лучше использовать это место для индикации занятости/неисправности страницы. Дополнительно можно хранить и другие служебные данные.
И еще по теме, но не по вопросу - при разработке системы на будущее имейте ввиду, что со сременем все растет, а в этих флэшах растет в первую очередь размер страницы. Уже сейчас искать большие чипы с 2К страницей тяжело - делают 4К.
baken
Цитата(torik @ Aug 5 2009, 13:27) *
Вот еще вопрос появился.
в каждой странице памяти 2192 байта, их можно использовать все или с адреса 2048 есть какие-то ограничения?
Просто не хочу файловую систему организовывать и контроль ошибок, хочу просто использовать дополнительное место для служебных данных...

Дело не в файловой системе, "лишние" 144 байта это 36 дополнительных байт на каждую подстраничку из 512 байт.
В эти 36 байт пишется номер странички, адрес предыдущей и последующей страничек, контрольные суммы для восстановления.
В настоящее время в NAND упор делается как раз на восстановление данных. И Вы, уверен на 100%, поставите в свой проект
самый дешевый чип за 400 рублей. А они сделаны как раз по MLC технологии. Основное "достоинство" этой технологии в том,
что максимальное число записей не более 10 тысяч, и сыпятся данные в них с максимально возможной скоростью.
Если Вы не будете использовать процедуру восстановления данных, полноценно работать с NAND просто не сможете.
Данные будут постоянно теряться. Как вариант писать параллельно в несколько мест. Тогда можно не использовать
лишние несколько байт в странице. Потому что у Вас контрольная сумма в полный размер данныхsmile.gif
torik
Цитата
И еще по теме, но не по вопросу - при разработке системы на будущее имейте ввиду, что со сременем все растет, а в этих флэшах растет в первую очередь размер страницы. Уже сейчас искать большие чипы с 2К страницей тяжело - делают 4К.

Спасибо, учту.
Цитата
Использовать можно, но помните о возможности возникновения bad-блоков на лету. Лучше использовать это место для индикации занятости/неисправности страницы. Дополнительно можно хранить и другие служебные данные.


Цитата
Дело не в файловой системе, "лишние" 144 байта это 36 дополнительных байт на каждую подстраничку из 512 байт.
В эти 36 байт пишется номер странички, адрес предыдущей и последующей страничек, контрольные суммы для восстановления.
В настоящее время в NAND упор делается как раз на восстановление данных. И Вы, уверен на 100%, поставите в свой проект
самый дешевый чип за 400 рублей. А они сделаны как раз по MLC технологии. Основное "достоинство" этой технологии в том,
что максимальное число записей не более 10 тысяч, и сыпятся данные в них с максимально возможной скоростью.
Если Вы не будете использовать процедуру восстановления данных, полноценно работать с NAND просто не сможете.
Данные будут постоянно теряться. Как вариант писать параллельно в несколько мест. Тогда можно не использовать
лишние несколько байт в странице. Потому что у Вас контрольная сумма в полный размер данныхsmile.gif


Собственно, в качестве служебных данных я и хотел использовать данные о том, занята страница или нет, битый ли блок (насколько я понимаю, битый блок не означает, что его нельзы использовать?). Место под CRC обязательно оставлю на будущее.
Alex11
Все производители пишут, что битый блок не следует использовать целиком, а не только битые страницы. Мы в своей аппаратуре делам следующим образом. Если блок уже битый - не используем, если был целый, но не смогли записать страницу (образовался битый на лету), то уже записанные страницы оставляем, а неисправную пишем повторно в следующий свободный. После очередного стирания/форматирования весь блок помечается как битый и не используется в дальнейшем.
torik
Цитата
Все производители пишут, что битый блок не следует использовать целиком, а не только битые страницы. Мы в своей аппаратуре делам следующим образом. Если блок уже битый - не используем, если был целый, но не смогли записать страницу (образовался битый на лету), то уже записанные страницы оставляем, а неисправную пишем повторно в следующий свободный. После очередного стирания/форматирования весь блок помечается как битый и не используется в дальнейшем.


А нет ли какого-нибудь алгоритма, обзорной статьи, описания работы контроллера NAND Flash? С интерфейсом-то разобрался, пока интерфейс реализую программно в Nios непосредственно через PIO. Програмно - для отработки ПО и алгоритмов всвязи с нехваткой времени, позже заменю на "железный контроллер". Но пока незнаю на что опереться, где подглядеть реализацию как самого контроллера в железе, так и алгоритм хранения данных (в сомой же флешке и хранить данные о битых блоках (у меня нет больше ПЗУ? Или каждый раз при включении проверять блоки на занятость/исправность?)...
zverek
Сорри за оффтопик, (думал создавать ли новую тему здесь или в "новичках" smile.gif ) но вопрос тоже связан с флешью. Нужен простой способ прошить отдельно взятую m25p40 (то есть к ней никаких циклонов и стратиксов не подключено). Можно ли прошить m25p40 (EPCS4) собственным бинарником через USB BLASTER и QUARTUS? Поймет ли Quartus "левый" бинарник и опознает ли он m25p40 как EPCS4, если к ней ничего не подключено? Может быть вопрос и элементарный, но проверить пока нет возможности, а потом будет уже поздно. И нет ли где нибудь простого Verilog'а чтения m25p40 непосредственно из MAXII (без NIOS'ов)?
torik
Ну так чё, кто подскажет алгоритм работы?

Мне в памяти надо хранить кадры изображения (5 блоков каждый) и, наверное, доп. информацию о битых блоках и прочее.

Сперва форматируем память, в процессе чего определяем какие блоки неисправны, получаем таблицу из 4096 байт, каждый из которых говорит о состоянии конкретного блока.
Теперь хотелось бы записать эти данные на флеш, чтобы при последующем включении прочитать их. Модификация таблицы и запись будет происходить, по идее, каждый раз, когда появляется битый блок (как минимум), а может и после записи каждого кадра. Получается, что писать в один блок нельзя, надо несколько блоков под это дело выделить и писать поочередно (увеличить ресурс памяти).

Вообще как-то все запутано, может есть рекомендации/алгоритм или статься по FAT для Flash?
Самое главное - как обеспечить надежную запись служебной таблицы всвязи с довольно частой ее перезаписью?
awa
Можно покопаться в исходниках файловой системы YAFFS (http://ru.wikipedia.org/wiki/YAFFS/ http://www.yaffs.net/), если есть много свободного времени. wink.gif

В двух словах, надо разделить физический блок памяти (страницу NAND например) и логический.
В таком случае вся реализация контроля целостности, равномерности распределения перезаписей и т.п. будет реализовываться при работе с физическим блоком. Вот тут как раз и используются те самые дополнительные байты в каждой странице NAND.
Таким образом получается, что при работе с логическими блоками Вы уже не думаете о всех заморочках NAND, а просто используете "идеальные" блоки памяти, на которые можно хоть FAT положить. Но в Вашем случае можно вместо FAT и по проще самопальную "файловую систему" использовать.


Цитата(torik @ Aug 12 2009, 11:19) *
Самое главное - как обеспечить надежную запись служебной таблицы всвязи с довольно частой ее перезаписью?


При указанном подходе отпадает надобность в такой таблице. Для каждого физического блока все служебные данных хранятся в его же дополнительных байтах.

Если интересует, могу коротко рассказать суть. Когда то разрабатывал подобную FS (еще до появления YAFFS, вернее параллельно с ней по времени).
Единственно, что к FPGA это не имеет никакого отношения, чистое программирование.
Alex11
Если запись подряд, то можете слизать алгоритм с меня. Реализовано на циклоне третьем. Перед записью в блок производится считывание служебной области нулевой страницы блока и проверяется нулевой байт, если он 0xFF, то блок целый, можно писать. Затем пишутся страницы в блок и переход к следующему блоку. Если произошла ошибка записи, то проверяется следующий блок и, если он не плохой, то страница пишется повторно в него, в страницу с тем же номером относительно начала блока. Если блок плохой - пропускаем его и повторяем со следующим. При стирании или форматировании обнаруживаются недописанные блоки и помечаются как плохие. Это, конечно, по уставу не положено, но вполне работает, поскольку делается однократно. Здесь, конечно, нет никакой файловой системы, записи идут подряд, и стереть можно или все, или хвост.
zverek
Цитата(awa @ Aug 12 2009, 17:42) *
Единственно, что к FPGA это не имеет никакого отношения, чистое программирование.


Сорри, если вставлю свою пять копеек. Если нет "чрезвычайной" необходимости реализовывать "железную" FS для FLASH, лучше этого не делать. Даже для RT и прочих критических систем для этих целе есть OS. Через пару лет переписывать придется все заново.

Цитата(torik @ Aug 12 2009, 11:19) *
Ну так чё, кто подскажет алгоритм работы?

Мне в памяти надо хранить кадры изображения (5 блоков каждый) и, наверное, доп. информацию о битых блоках и прочее.

Сперва форматируем память, в процессе чего определяем какие блоки неисправны, получаем таблицу из 4096 байт, каждый из которых говорит о состоянии конкретного блока.
Теперь хотелось бы записать эти данные на флеш, чтобы при последующем включении прочитать их. Модификация таблицы и запись будет происходить, по идее, каждый раз, когда появляется битый блок (как минимум), а может и после записи каждого кадра. Получается, что писать в один блок нельзя, надо несколько блоков под это дело выделить и писать поочередно (увеличить ресурс памяти).

Вообще как-то все запутано, может есть рекомендации/алгоритм или статься по FAT для Flash?
Самое главное - как обеспечить надежную запись служебной таблицы всвязи с довольно частой ее перезаписью?


Если чем-то поможет могу привести ссылку http://www.ibm.com/developerworks/linux/li...sh-filesystems/
В свое время с этим делом заморачивался (но как драйвер для Linux), если вспомню интересные ссылки, могу привести.

Цитата(torik @ Aug 12 2009, 11:19) *
Ну так чё, кто подскажет алгоритм работы?
Самое главное - как обеспечить надежную запись служебной таблицы всвязи с довольно частой ее перезаписью?


А вот это уже точно "чистое программирование". Очень мощные алгоритмы есть, но они опять же не для FPGA.
torik
Цитата
Можно покопаться в исходниках файловой системы YAFFS (http://ru.wikipedia.org/wiki/YAFFS/ http://www.yaffs.net/), если есть много свободного времени. wink.gif

В двух словах, надо разделить физический блок памяти (страницу NAND например) и логический.
В таком случае вся реализация контроля целостности, равномерности распределения перезаписей и т.п. будет реализовываться при работе с физическим блоком. Вот тут как раз и используются те самые дополнительные байты в каждой странице NAND.
Таким образом получается, что при работе с логическими блоками Вы уже не думаете о всех заморочках NAND, а просто используете "идеальные" блоки памяти, на которые можно хоть FAT положить. Но в Вашем случае можно вместо FAT и по проще самопальную "файловую систему" использовать.


Цитата(torik @ Aug 12 2009, 11:19) *
Самое главное - как обеспечить надежную запись служебной таблицы всвязи с довольно частой ее перезаписью?


При указанном подходе отпадает надобность в такой таблице. Для каждого физического блока все служебные данных хранятся в его же дополнительных байтах.

Если интересует, могу коротко рассказать суть. Когда то разрабатывал подобную FS (еще до появления YAFFS, вернее параллельно с ней по времени).


Если бы чуть подробнее, было бы просто здорово!

Цитата
Единственно, что к FPGA это не имеет никакого отношения, чистое программирование.


Повторюсь, я работаю с помощью nios-процессора, т.е. чистое програмирование. Мне важен именно алгоритм.


Цитата
Для каждого физического блока все служебные данных хранятся в его же дополнительных байтах.

В том числе и о неисправности блока? Это первое.
Второе: кадр занимает 5 блоков. Если какой-то блок в процессе работы становится неисправным, кадр будет расположен не в блоках заподряд, а будет использовать свободные исправные. В этом случае первый блок не сможет содержать информацию о следующем, т.к. записан раньше.
Два этих случая наводят меня на мысль о необходимости таблицы со служебной информацией.

Вот и давайте обсудим. blush.gif



Цитата
Если чем-то поможет могу привести ссылку http://www.ibm.com/developerworks/linux/li...sh-filesystems/
В свое время с этим делом заморачивался (но как драйвер для Linux), если вспомню интересные ссылки, могу привести.

Спасибо, читал статейку, есть даже перевод на русском.

Цитата
При стирании или форматировании обнаруживаются недописанные блоки и помечаются как плохие.

Над этим вопросом я тоже задумывался. Предположим, блок дал сбой при записи или стирании. Необходимо считать его плохим и... пометить как вы говорите. Как пометить его, если он плохой и не подлежит записи? Только в служебную таблицу...
Alex11
Цитата
Над этим вопросом я тоже задумывался. Предположим, блок дал сбой при записи или стирании. Необходимо считать его плохим и... пометить как вы говорите. Как пометить его, если он плохой и не подлежит записи? Только в служебную таблицу...

Я уже отмечал, что это не очень честно, но работает. На практике битые блоки всегда позволяют записать хотя бы несколько нулевых битов в каждый байт. Этим и пользуемся. Маркер исправности - все 1.
По поводу разбиений блоков данных - у меня нет адреса следующего блока в предыдущем. Адрес следующего блока всегда +1 от предыдущего или плюс сколько-то, если появились bad'ы. Они отслеживаются при чтении по наличию неиспользованных страниц.
Это, глобально, не лучший способ, но поскольку нужно все было реализовывать в реальном времени и еще довольно жестком, то пришлось делать на автоматах и поэкономить на алгоритме.
torik
Цитата
По поводу разбиений блоков данных - у меня нет адреса следующего блока в предыдущем. Адрес следующего блока всегда +1 от предыдущего или плюс сколько-то, если появились bad'ы. Они отслеживаются при чтении по наличию неиспользованных страниц.

В этом случае возможно будет записывать определенное число кадров, а потом все их стирать для освобождения памяти. Нельзя будет удалить кадр в произвольном месте. Но думаю,для упрощения я так и поступлю...

Цитата
Я уже отмечал, что это не очень честно, но работает. На практике битые блоки всегда позволяют записать хотя бы несколько нулевых битов в каждый байт.

Этак для записи изображения и вообще можно использовать даже неисправные блоки. Будут битые пиксели и все. Вообще интересно, как ведут себя плохие блоки...
awa
Вот подробнее, но как то сумбурно получилось.


Для начала, несколько общих моментов.

1. Как дохнет NAND флеш.
В отличие от HDD, в которых портятся сразу участки данных, в NAND дохнут отдельные биты,
поэтому и алгоритм проверки и восстановления здесь расчитан на такое поведение. Тут расписано в картинках как он работает.
http://www.samsung.com/global/business/sem...algo_040624.pdf

2. Страницы могут быть четырех видов:
1) Чистые(стертые) - после команды стирания заполнены кодом 0xFF;
2) Записанные - в них хранится актуальная информация;
3) Устаревшие - в них хранится устаревшая информация. Они ждут своей очереди чтобы быть стертыми или перезаписанными.
4) Сбойные - в них выявлены сбойные биты. Для работы они не используются.


3. Добавочные байты (заголовок) каждой страницы как и сами данные защищается ECC.
(Я реализовывал свою FFS для размера страницы 512+16 байт и использовал 2 массива по 3 байта под два ECC для 256 байт каждый
и 12 бит под ECC первых 8 байт из добавочных 16, остальные 8 - сами ECC и есть)

В заголовке я так же хранил:
- количество перезаписей данной страницы (16 бит)
- номер записи для контроля дублей при записи. (2 бита)
- признак битости данной страницы. (6 бит)
- признак устаревшей страницы (4 бита)

А так же:
- номер файла, в который входит эта страница
- ссылка на следующую старницу данного файла или ссылка на себя же для индикации конца цепочки.

Это было сделано чтобы избежать организации отдельного FAT. В общем случае тут можно хранить номер логического
"идеального блока" памяти.


При старте системы происходит монтирование флешки, то есть считываются заголовки всех страниц и в памяти
стоится таблица, в которой указано, что в какой физической странице лежит.
Заодно проводится проверка на некорректное завершение последней работы с флешкой и устраняются ошибки.


Запись логического блока происходит след. образом.
1) в таблице в памяти находим в какой физической странице лежит послений актуальный вариант этого блока,
если его еще небыло записано, то переходим к п.3.
2) считываем заголовок страницы старого блока, увеличиваем 2-хбитный счетчик дублей и копируем в заголовок нового
3) находим чистую страницу, и пишем в нее или перезаписываем какую-нибудь устаревшую если чистых больше нет.
4) Пишем в старую страницу признак "устаревшая".

Благодаря 2-хбитному счетчику дублей решается проблема определения актуальных данных в случае пропадания питания
между 3 и 4 пунктами. Эта проверка проводится при монтировании системы.

Для стирания блока просто пишем признак "устаревшая".


При выборе страницы для записи можно выбирать с минимальным кол-вом перезаписей.
Правда в моем случае было ограничение на суммарное количество записей в банк, после которого необходимо было
перезаписать все страницы в этом банке.


Есть еще такое понятие "сборка мусора". Это когда используется возможность быстро стереть сразу все страницы в
блоке. Это делают, когда почти не остается чистых страниц, но много устаревших.
В этом случае выбирается блок с минимальным числом актуальных (или максимальным числом устаревших) страниц,
которые переписывются в другие блоки, а этот блок стирается. У себя я это не использовал.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.