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

4 минуты назад, mantech сказал:

но потеряем в безопасности при откл. питания в частности.

Вроде речь шла только о кешировании чтения....  :unknw:

Не надо мешать мух с котлетами - при записи совсем другой алгоритм.

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


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

Только что, jcxz сказал:

Вроде речь шла только о кешировании чтения....

При чтении безопасно, кроме усложнения кода ничем не грозит...

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


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

On 2/25/2021 at 11:21 AM, korotaev said:

STM32H743. Чтение SD карты в режиме Polling.

Два прибора. Один на базе STM32F437, другой- STM32H743. Для каждого прибора скорость обмена данными по USB каналу не менее 28 Мбайт/сек. В каждом стоят одинаковые SD карты UHS-I без трансивера.

ПО для STM32F437 с использованием SPL, STM32H743 – CubeMX v.6.1, пакет для микроконтроллера STM32Cube FW_H7 V1.8.0.

Имею для прибора на STM32H743 очень маленькую скорость чтения данных в режиме USB флэшки. Проверял так.

C приборов в режиме mass storage (Polling) читается один и тот же файл размерностью 256 Мбайт. Клок для карточек в приборах одинаковый. Средняя скорость чтения для STM32F437 примерно 7 Мбайт в секунду, для STM32H743 – всего 1.5 Мбайт в секунду.

Для многих это не новость. Есть подобные сообщения на эту тему.

Вопрос: можно ли увеличить скорость чтения для H743, если перевести обмен данными в режим DMA (iDMA)?

 

     

             STM32H743, mass storage USB device, Windows.

             В режиме Polling работает, но скорости маленькие (запись 300 – 600 кБайт/сек, чтение в среднем 1.5 МБайт/сек). Проблем с USB железом нет. Скорость  передачи данных до 28 МБайт/сек.

             В режиме DMA не работает. Код внизу. Проводник открывает Окно диска и дополнительно выскакивает окно с предложением "Форматировать диск".

             

              В файле “usbd_storage_if.c”

               int8_t STORAGE_Read_HS(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len)

               {

               int8_t ret = USBD_FAIL;

               RxStatus0 = 0;  //глобальная переменная

                 if (BSP_SD_ReadBlocks_DMA(0, (uint32_t*)buf, (uint32_t)blk_addr, blk_len) == HAL_OK)

                 {

                                //while (RxStatus0 == 0) {};  //Ожидаю Callback

                               if (Wait_SDCARD_1_Ready() == HAL_OK)

                               ret = USBD_OK;

                 }

                return ret;

               }

 

            void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)

            {

            if (hsd->Instance  == SDMMC1)

                {

                  RxStatus0 = 1;

               }

            }

 

 Очень странный момент:

- Если раскомментировать while (RxStatus0 == 0) {};  //Ожидаю Callback ,

то программа виснет на этой строке, т.е. прерывания SDMMC1 и вызов HAL_SD_RxCpltCallback не происходят.

- Если закомментировать эту строку, то прерывания SDMMC1 и вызов HAL_SD_RxCpltCallback не происходят также.

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

 

Видел примеры, где внутри STORAGE_Read_HS опрашивается состояние  RxStatus0, которое изменяется в callback. И нет никакого зависания.

Более того, у меня DMA версия работала, но  также с маленькими скоростями. Теперь не могу вернуться хотя бы к работающему примеру с DMA.

Подскажите, кто знает в чём засада.

 

Изменено пользователем korotaev

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


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

44 минуты назад, korotaev сказал:

Подскажите, кто знает в чём засада.

В калокубе. Однозначно.  :russian_ru:

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


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

02.04.2021 в 11:14, korotaev сказал:

RxStatus0, которое изменяется в callback. И нет никакого зависания.

Никто ж не знает, что это за коллбэк и чего он делает, а самое главное - как? В ту сторону и "копайте"...

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


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

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

 

Если точнее, в начале сбросить источник запроса на прерывание, сбросить pending бит, в конце - проверить pending бит.

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


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

3 часа назад, rudy_b сказал:

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

Чушь! Это невозможно в принципе (в конце проверить не встал ли он снова). Посмотрите как устроен любой ISR чтобы понять "почему".

Стандартный способ обработки прерываний от любых источников на Cortex-M:

1. Сбросить флаг прерывания (в начале ISR).

2. Обработать прерывание.

3. Выйти из ISR.

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

Вот и всё. "Проблема" надуманная.

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


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

4 часа назад, rudy_b сказал:

По хорошему - в начале обработки сбросить pending бит, а в конце проверить не встал ли он снова.

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

Изменено пользователем mantech

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


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

2 часа назад, mantech сказал:

если у вас запрос на прерывание выставляется в процессе обработки предыдущего, а еще если и не один раз за это время, значит либо неправильно проработан алгоритм работы с прерываниями

На одном векторе часто висят обработчики обработчики разных событий (прием, готовность передатчика, ошибки и т.п.), и одни из них могут возникать во время обработки других. Это совершенно штатная ситуация даже при самом правильном обрабочике. Один вектор на каждый флаг всегда был непозволительной роскошью. Достаточно просто в начале обработчика считать флаги во временную переменную и сбросить только те флаги, которые в этой переменной установлены. И именно эти флаги и обрабатывать.

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


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

18 минут назад, Сергей Борщ сказал:

На одном векторе часто висят обработчики обработчики разных событий (прием, готовность передатчика, ошибки и т.п.), и одни из них могут возникать во время обработки других.

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

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


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

21 hours ago, jcxz said:

Чушь! Это невозможно в принципе (в конце проверить не встал ли он снова). Посмотрите как устроен любой ISR чтобы понять "почему".

Стандартный способ обработки прерываний от любых источников на Cortex-M:

1. Сбросить флаг прерывания (в начале ISR).

2. Обработать прерывание.

3. Выйти из ISR.

Сразу видно, что вы не умеете работать с прерываниями.

В начале нужно сбросить не флаг прерывания, а источник запроса, и, только потом, сбрасывать флаг (pending бит)

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


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

2 часа назад, rudy_b сказал:

В начале нужно сбросить не флаг прерывания, а источник запроса, и, только потом, сбрасывать флаг (pending бит)

А что такое "источник запроса"? И каким образом его нужно сбросить?

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


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

В стандартных случаях источником запроса на прерывание является периферия, DMA и т.п. Например при приеме байта UART при разрешенном прерывании, таймер, SPI и т.д. Они устанавливают запрос на прерывание, он отрабатывается процессором и запускается соответствующий обработчик прерывания. Для сброса источника прерывания, как правило, нужно считать соответствующий регистр или ручками сбросить бит в периферии. А, затем, снять бит в NVIC процессора. Последнее может делаться автоматически при возврате из прерывания по reti.

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


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

А вот мне кажется, что именно Вы, @rudy_b, не совсем понимаете, о чем говорите.

Последним сообщением Вы просто, по сути, пересказали то, о чем говорил @jcxz. Ведь тезисом

22 часа назад, rudy_b сказал:

Сразу видно, что вы не умеете работать с прерываниями...

явно затевался, видимо, какой-то аргументированный спор.

И не надо снимать бит в NVIC - в некоторых случаях так можно только потерять событие.
Да и нет в Cortex-Mx никакого RETI. Для них ISR не отличается по ABI от обычной функции.

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


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

7 часов назад, rudy_b сказал:

А, затем, снять бит в NVIC процессора. Последнее может делаться автоматически при возврате из прерывания по reti.

Давайте вы почитаете учебник по теме "Ядро Cortex-M. Механизм прерываний.", узнаете что такое NVIC, как работают прерывания в нём, какие там есть флаги, зачем они и как производится вход и возврат из прерывания в Cortex-M. Как используется регистр LR при этом. Почему бесполезно в конце ISR проверять наличие флага нового прерывания. Почему в типичном ISR не нужно трогать pending-биты и другие биты в NVIC.

А потом придёте на пересдачу. А пока вам - назачёт по теме.

Arlleex вам уже задал начало правильного направления и подсказал некоторые моменты.

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


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

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

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

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

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

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

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

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

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

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