|
|
  |
Помогите подобрать файловую систему для microsd |
|
|
|
Nov 21 2008, 16:41
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
Цитата(Зверюга @ Nov 21 2008, 18:32)  Ну, продолжите. Я так понимаю, скорость чтения зависит от частоты SPI и от скорости обработки данных контроллером. Поменяв контроллер мы частично решим обе задачи. Дальше оптимизация программы, читающей файловую систему. Что еще входит в упомянутый Вами комплекс? Какой скорости считывания можно добиться на ARM7? возьмите скорость SPI в 1/4 скорости контроллера, получите битрейт 5 мбит/с. При чтении данных блоками (скажем, секторами по 512 байт, если будете использовать FAT16) потери на служебную информацию невелики, и скорости 600кбайт/с теоретически можно достигнуть (если нет, можно попробовать разогнать SPI до 10 МГц). А поддержка FAT реализуется достаточно просто (делала на меге8), особенно если не нужно учитывать фрагментацию и длинные имена файлов.
Сообщение отредактировал Paulina - Nov 21 2008, 16:58
|
|
|
|
|
Nov 21 2008, 17:25
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
Цитата(Зверюга @ Nov 21 2008, 20:23)  Ну у на ARM7 - где 60 МГц?. Можно ведь разогнеать SPI до 30 МГц? Ведь на PC - как-то читается до 8 МБ в секунду? ИЛи выход - SD режим? В библиотеке EFSL есть папки atmega_spi и atmega_sd - так вот последняя почему-то пуста... Зачем забивать гвозди микроскопом? Вам ведь просто нужно читать файлы? AVR хватит с головой для этого.
Сообщение отредактировал Paulina - Nov 21 2008, 17:32
|
|
|
|
|
Nov 21 2008, 17:55
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
Цитата(Зверюга @ Nov 21 2008, 20:50)  Я просто пытаюсь понять, от чего зависит скорость чтения.
Мне нужно (я пересчитал) - 1,5 Мбайт в секунду. Да и еще по ходу их наверное обрабатывать. а, ну тогда понятно. либо с ARM в SPI либо попробовать на AVR в режиме SD.
|
|
|
|
|
Nov 21 2008, 17:58
|
Местный
  
Группа: Свой
Сообщений: 413
Регистрация: 15-12-06
Пользователь №: 23 563

|
но ведь пишут же Цитата SD режим - это 4 бита? Только потеряете в быстродействии на AVR по сравнению с SPI.
|
|
|
|
|
Nov 24 2008, 15:10
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
Цитата(Зверюга @ Nov 24 2008, 14:34)  Хм... а если содержимое файла перед работой переписывать на ту же флешку куда-нибудь в конец и потом читать просто как поток информации - будет быстрее? я правильно поняла, что вам еще надо по этому же каналу spi отправлять данные дальше? как вариант можно дождаться начала блока данных и выставить сигнал #CS для принимающего устройства, чтобы оно уже принимало только эти данные (после окончания блока, естественно, снять #CS). но при данной скорости контроллера получите в лучшем случае чуть меньше 10 МБит/с.
Сообщение отредактировал Paulina - Nov 24 2008, 15:14
|
|
|
|
|
Nov 24 2008, 15:35
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
только этот момент подачи #CS надо хорошенько продумать. скорость spi будет равна половине скорости контроллера, а обновление портов происходит через 1 такт после записи в порт, можно и не успеть до прихода следующего фронта CLK. поиграйтесь с настройками CPOL, CPHA, авось получится. код для работы с FAT16 могу выложить, если надо.
Сообщение отредактировал Paulina - Nov 24 2008, 15:37
|
|
|
|
|
Nov 24 2008, 17:21
|
Участник

Группа: Участник
Сообщений: 35
Регистрация: 18-05-08
Пользователь №: 37 607

|
Цитата(Dog Pawlowa @ Nov 24 2008, 19:39)  Пробовать то можно, но существующие порт efsl (например) для SD интерфейса ARM7 NXP не использует DMA. В отличие от SPI, между прочим. Что касается SPI AVR, то что толку разогнать сам SPI? нужно же еще флаг готовности анализировать, адрес инкрементировать, проверять адрес на соответствие диапазону. Без DMA+IRQ сделать это с высокой скоростью нереально. Это так, но если данные идут непрерывно, без дефрагментации то можно просто установить размер блока данных, скажем 64 кБ и принимать их непрерывно, а потом уже делать проверки и прочая. мне лично больше 256кбит/с не было нужно, поэтому не пробовала. вот например часть кода из рабочей программы с функциями установки длины блока, считывания блока а также инициализацией карты, чтением FAT и т.д: Код unsigned char sec_per_clust, data[512]; unsigned int j, j2; unsigned long fat_base, cluster_base, addr; flash unsigned char cmd0[6] = {0x40, 0x00, 0x00, 0x00, 0x00, 0x95}, cmd1[6] = {0x41, 0x00, 0x00, 0x00, 0x00, 0x01}, blck_ln_200[6] = {0x50, 0x00, 0x00, 0x02, 0x00, 0x01}; //элементы 2-5 задают размер блока, в данном случае 512 байт ... void set_block_len(void) { spi(0xff); for(i=0; i<6; i++) spi(blck_ln_200[i]); while(spi(0xff)==0xff); spi(0xff); } ... void read_single_block(unsigned long daddr) { //k=255; //убрать комментарии если не хотите зависания при отсутствии карты do { spi(0xff); spi(0x51); spi(daddr>>24); spi(daddr>>16); spi(daddr>>8); spi(daddr); spi(0x01); while(spi(0xff)==0xff); //--k; } while((SPDR!=0x00));//&&(k>0)); while(spi(0xff)!=0xfe); for(j2=0; j2<512; j2++) data[j2]=spi(0xff); //разумеется, количество итераций зависит от размера считываемого блока spi(0xff); spi(0xff); spi(0xff); } ... //далее функция преобразования четырех байтов в одно 32-битное число (ну не нашла я готовых функций) void uchar_to_ulong(unsigned long *p, unsigned int offset, unsigned int count) { *p=0; for(; count>0; count--) { *p|=*(data+offset+count-1); if(count>1) *p<<=8; } } ... //=======инициализация карты=========== for (i=0; i<10; i++) spi(0xff); delay_ms(1); //========сброс карты=============== card_cs=0; do { spi(0xff); for(i=0; i<6; i++) spi(cmd0[i]); for(i=0; i<8; i++) if(spi(0xff)!=0xff) break; } while(SPDR!=0x01); //ждем ответа 0x01 - спящий режим //spi(0xff); //CS=1; //=======инициализация режима spi карты======= //CS=0; do { spi(0xff); for(i=0; i<6; i++) spi(cmd1[i]); for(i=0; i<8; i++) if(spi(0xff)!=0xff) break; } while(SPDR!=0x00); //spi(0xff); set_block_len();//0x100); read_single_block(0); //чтение master boot record card_cs=1; uchar_to_ulong(&addr, 0x1c6, 4); //позиция partition boot record в секторах card_cs=0; read_single_block(addr<<9); //чтение pbr card_cs=1; //================вычисление root base======================= uchar_to_ulong(&root_base, 0x0e , 2); //зарезервированных секторов root_base+=addr; //fat base в секторах fat_base=root_base<<9; //fat base в байтах uchar_to_ulong(&addr, 0x16, 2); //секторов на fat addr<<=1; //удвоение из-за того что 2 таблицы fat root_base+=addr; //root base в секторах root_base<<=9; //в байтах //================вычисление cluster base==================== sec_per_clust=data[0x0d]; //секторов на кластер addr=data[0x0d]; addr<<=10; //байтов на 2 фиктивных кластера cluster_base=root_base-addr; uchar_to_ulong(&addr, 0x11, 2); //число записей в корневом каталоге addr<<=5; //размер корневого каталога в байтах cluster_base+=addr; //cluster base в байтах card_cs=0; read_single_block(root_base); //чтение корневого каталога код читается плохо, согласна (написано полностью с нуля), но разобраться можно. спрашивайте, если что.
Сообщение отредактировал Paulina - Nov 24 2008, 17:22
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|