Перейти к содержанию
    

Процессор F407, карта SD класс 10. Использую двойную буферизацию. Буфера заполняются в прерывании. Со включенным прерыванием больше 21К / сек не вытягивает. Если пишу с остановкой потока перед f_write, карта с успехом пишет 42К / сек поток. В чем может быть косяк?

Если писать поток выше 21К с без отключения прерываний, возникает ошибка записи диска низкого уровня 0х01. В прерывании небольшой кусок кода занимает 20 - 30 мкс. Либо я где - то накосячил.

 

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

37 minutes ago, Димон Безпарольный said:

Либо я где - то накосячил.

Адназначна!!!))))

По делу: карте по-барабану на прерывания, ей, главное, соблюсти протокол. Вы его точно соблюдаете? Логический анализатор есть?

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

Вполне возможно, что включенные прерывания нарушают либо времянки, либо атомарность доступа к какой-либо переменной.

40 minutes ago, Димон Безпарольный said:

сли писать поток выше 21К с без отключения

Кстати, а как можно писать намеренно с какой-то скоростью? Я так понимаю, карта сама позволит это.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 hours ago, haker_fox said:

Кстати, а как можно писать намеренно с какой-то скоростью?

У всех современных sd карт есть дополнительные уникальные команды управления, которые делятся на базовые по стандарту, и то что придумал производитель. Базовые определяются переключением стандарта, это требует полной смены алгоритма общения с картой. То-есть недостаточно просто повысить скорость интерфейса и использовать те-же функции - нужно читать поддержку стандарта конкретной sd, и перенаправлять функции чтения/записи/проверки. Стандартный драйвер от st - использует базовые команды 1,0 , и выше прыгнуть чисто физически не может. 

Уникальные команды от производителя доступны с версии 2,0. Там конечно бардак и полный хаос, но общий принцип описания команд достаточно простой - в виде hml. Место где расположено описание, у каждого производителя уникальное. По этому нужно читать id карты и использовать свои таблицы. Уникальные команды позволяют достичь максимальной скорости общения с картой. Ради экспериментов можно распотрошить драйвер от современного кардридера, там это почти в текстовом варианте записано.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

36 minutes ago, AVI-crak said:

Ради экспериментов можно распотрошить драйвер от современного кардридера, там это почти в текстовом варианте записано.

Ага, интересную информацию для себя почерпнул. Но всё-таки ТС говорит о скоростях 20 и 40 кБайт/сек. Тут повышением скорости и не пахнет, ибо если точно помню, почти все карты дают 25 Мбит на SPI-шине. По-крайней мере те карты, которые у меня были в наличие.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 hours ago, haker_fox said:

Адназначна!!!))))

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

Пытаюсь понять насколько правильно это делает FatFS. Но это слишком глубоко в железе.

 

8 hours ago, haker_fox said:

Кстати, а как можно писать намеренно с какой-то скоростью? Я так понимаю, карта сама позволит это.

Пожно. По таймеру раз в 2мс как и должно быть в изделии. Только возможности не хватает  нужно 80К/сек, о факту - только 21.

2 hours ago, haker_fox said:

Тут повышением скорости и не пахнет, ибо если точно помню, почти все карты дают 25 Мбит на SPI-шине. По-крайней мере те карты, которые у меня были в наличие.

SPI по спецификации если не ошибаюсь 20МГц. На каких же скоростях там все летает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 minutes ago, Димон Безпарольный said:

Пытаюсь понять насколько правильно это делает FatFS. Но это слишком глубоко в железе.

Это не FatFS. Это драйвер карты и интерфейса. Самой FatFs глубоко индифферентна физика.

5 minutes ago, Димон Безпарольный said:

SPI по спецификации если не ошибаюсь 20МГц. На каких же скоростях там все летает?

И всё-таки 25) У меня пишет 300 кБайт/сек, читает около 2 Мбайт/сек. SPI. Измерения делал косвенно через тотал коммандер (железяка ещё и ftp-сервер организует).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, haker_fox said:

У меня пишет 300 кБайт/сек, читает около 2 Мбайт/сек.

Используете двойную буферизацию? Размер буфера не подскажите?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, Димон Безпарольный said:

Используете двойную буферизацию? Размер буфера не подскажите?

Удивительно, но не использую буферов вообще. Драйвер FatFs напрямую общается с драйвером карты. Вот как-то так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, haker_fox said:

Удивительно, но не использую буферов вообще. Драйвер FatFs напрямую общается с драйвером карты. Вот как-то так.

Значит допустимы потери или поток не постоянен - у меня нет. Поток идет каждые 2мс и потери недопустимы.  Карта по спецификации имеет задержки до 250мс кажется.

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, Димон Безпарольный said:

Значит допустимы потери или поток не постоянен - у меня нет.

В конкретном приборе одна задача (FreeRTOS) копирует данные с внутренних носителей на карту. Файл за файлом. Тоже самое можно делать и через фтп-сервер. Поток может быть непостоянен, но потери данных недопустимы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 hours ago, haker_fox said:

либо атомарность доступа к какой-либо переменной.

Похоже так. Если не останавливать поток, даже f_mount выполняется с ошибкой. sprintf не хочет печатать в буфер имя файла. В потоке не такой уж сложный код - почему он так влияет - не пойму. Может кто намекнет, как отлавливать сей баг - почему прерывание по таймеру с несложным кодом так влияет на основной процесс? Гешил на стек - добавил. Не помогло.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для ускорения процесса нашел вот эту статью:

 /* Предварительное выделение кластеров (чтобы предотвратить переполнение буфера
 при потоковой записи) */
    res = f_open(file, recfile, FA_CREATE_NEW | FA_WRITE); /* Создание файла */
    res = f_lseek(file, PRE_SIZE);           /* Предварительное выделение кластеров */
    if (res || f_tell(file) != PRE_SIZE) ... /* Проверка - было ли успешным 
 увеличение размера файла */
    res = f_lseek(file, DATA_START);         /* Запись потока данных без задержек
 на выделение кластеров */
    ...
    res = f_truncate(file);                  /* Обрезка неиспользуемого пространства */
    res = f_lseek(file, 0);                  /* Запись заголовка файла */
    ...
    res = f_close(file);

http://microsin.net/programming/file-systems/fatfs-seek-file.html

Но мне кажется - уж не вредитель ее писал или я настолько туп? 

res = f_lseek(file, DATA_START);         /* Запись потока данных без задержек
 на выделение кластеров */

Как f_lseek может что  - то записать? Это же просто перемещение указателя?

Или это: res = f_lseek(file, 0); /* Запись заголовка файла */

Не пойму я этого. 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, Димон Безпарольный сказал:

Как f_lseek может что  - то записать? Это же просто перемещение указателя?

Или это: res = f_lseek(file, 0); /* Запись заголовка файла */

Что? Какие записи этой функцией...  Если уже есть файл определенного размера, и в нем что-то заменить без его увеличения, еще куда ни шло.  Или использовать ее для позиционирования в конец файла с послед. дописыванием с увеличением размера на то, что дописали.

ЗЫ. Ускорить запись средствами ФС можно только, если убрать синхронизацию после добавления фрагмента, но если при этом пропадет питание или перезагрузка, то все, после последней синхронизации или закрытия\открытия файла потеряется.

Проверьте линейную запись на карту памяти(без ФС), работайте с секторами 4К, а не 512 байт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, Димон Безпарольный said:

почему прерывание по таймеру с несложным кодом так влияет на основной процесс?

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

void IsrHandler() {
  __disable_irq();
  while(1);
}

 

6 hours ago, Димон Безпарольный said:

уж не вредитель ее писал

Читайте оригинал. Ведь это не статья. А просто перевод.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 hours ago, haker_fox said:

Читайте оригинал. Ведь это не статья. А просто перевод.

Так и в оригинале тоже самое - переводчик не наврал.

res = f_lseek(fp, DATA_START);           /* Record data stream WITHOUT cluster allocation delay */
    ...                                      /* Write operation should be aligned to sector boundary to optimize the write throughput */

http://elm-chan.org/fsw/ff/doc/lseek.html

Как может f_lseek делать Record data stream WITHOUT cluster allocation delay? Где - то в этой последовательности должно быть F_Write.

Изменено пользователем Димон Безпарольный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...