jcxz 241 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба 4 минуты назад, mantech сказал: но потеряем в безопасности при откл. питания в частности. Вроде речь шла только о кешировании чтения.... Не надо мешать мух с котлетами - при записи совсем другой алгоритм. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 50 25 марта, 2021 Опубликовано 25 марта, 2021 · Жалоба Только что, jcxz сказал: Вроде речь шла только о кешировании чтения.... При чтении безопасно, кроме усложнения кода ничем не грозит... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
korotaev 0 2 апреля, 2021 Опубликовано 2 апреля, 2021 (изменено) · Жалоба 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. Подскажите, кто знает в чём засада. Изменено 2 апреля, 2021 пользователем korotaev Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 2 апреля, 2021 Опубликовано 2 апреля, 2021 · Жалоба 44 минуты назад, korotaev сказал: Подскажите, кто знает в чём засада. В калокубе. Однозначно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 50 3 апреля, 2021 Опубликовано 3 апреля, 2021 · Жалоба 02.04.2021 в 11:14, korotaev сказал: RxStatus0, которое изменяется в callback. И нет никакого зависания. Никто ж не знает, что это за коллбэк и чего он делает, а самое главное - как? В ту сторону и "копайте"... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rudy_b 4 4 апреля, 2021 Опубликовано 4 апреля, 2021 · Жалоба Есть стандартная проблема при обработке прерываний - перед выходом из прерывания нужно проверить, не пришло ли еще одно и, если пришло обработать его и т.д. Если этого не сделать - то можно пропустить следующее прерывание, т.к. оно может быть сброшено при выходе из прерываний. По хорошему - в начале обработки сбросить pending бит, а в конце проверить не встал ли он снова. Если точнее, в начале сбросить источник запроса на прерывание, сбросить pending бит, в конце - проверить pending бит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 4 апреля, 2021 Опубликовано 4 апреля, 2021 · Жалоба 3 часа назад, rudy_b сказал: Есть стандартная проблема при обработке прерываний - перед выходом из прерывания нужно проверить, не пришло ли еще одно и, если пришло обработать его и т.д. Если этого не сделать - то можно пропустить следующее прерывание, т.к. оно может быть сброшено при выходе из прерываний. По хорошему - в начале обработки сбросить pending бит, а в конце проверить не встал ли он снова. Чушь! Это невозможно в принципе (в конце проверить не встал ли он снова). Посмотрите как устроен любой ISR чтобы понять "почему". Стандартный способ обработки прерываний от любых источников на Cortex-M: 1. Сбросить флаг прерывания (в начале ISR). 2. Обработать прерывание. 3. Выйти из ISR. Ничего "в конце ISR" проверять не надо, ибо - бесполезно. Если новое прерывание возникнет во время работы ISR, то сразу после выхода из ISR будет вход по новой в него. Вот и всё. "Проблема" надуманная. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 50 4 апреля, 2021 Опубликовано 4 апреля, 2021 (изменено) · Жалоба 4 часа назад, rudy_b сказал: По хорошему - в начале обработки сбросить pending бит, а в конце проверить не встал ли он снова. В догонку к предыдущему комментарию - если у вас запрос на прерывание выставляется в процессе обработки предыдущего, а еще если и не один раз за это время, значит либо неправильно проработан алгоритм работы с прерываниями, либо очень медленный их обработчик, тут явно нужно что-то делать, либо на основную программу почти не останется времени... Изменено 4 апреля, 2021 пользователем mantech Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 4 апреля, 2021 Опубликовано 4 апреля, 2021 · Жалоба 2 часа назад, mantech сказал: если у вас запрос на прерывание выставляется в процессе обработки предыдущего, а еще если и не один раз за это время, значит либо неправильно проработан алгоритм работы с прерываниями На одном векторе часто висят обработчики обработчики разных событий (прием, готовность передатчика, ошибки и т.п.), и одни из них могут возникать во время обработки других. Это совершенно штатная ситуация даже при самом правильном обрабочике. Один вектор на каждый флаг всегда был непозволительной роскошью. Достаточно просто в начале обработчика считать флаги во временную переменную и сбросить только те флаги, которые в этой переменной установлены. И именно эти флаги и обрабатывать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 50 4 апреля, 2021 Опубликовано 4 апреля, 2021 · Жалоба 18 минут назад, Сергей Борщ сказал: На одном векторе часто висят обработчики обработчики разных событий (прием, готовность передатчика, ошибки и т.п.), и одни из них могут возникать во время обработки других. Это понятно, я писал про один и тот-же флаг, который устанавливается, пока еще предыдущее событие по нему не отработано. Да и делать какой-то огромный обработчик для всех флагов от различных устройств без выхода в основную программу, пока все не отработает - по мне так не гуд тоже... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rudy_b 4 5 апреля, 2021 Опубликовано 5 апреля, 2021 · Жалоба 21 hours ago, jcxz said: Чушь! Это невозможно в принципе (в конце проверить не встал ли он снова). Посмотрите как устроен любой ISR чтобы понять "почему". Стандартный способ обработки прерываний от любых источников на Cortex-M: 1. Сбросить флаг прерывания (в начале ISR). 2. Обработать прерывание. 3. Выйти из ISR. Сразу видно, что вы не умеете работать с прерываниями. В начале нужно сбросить не флаг прерывания, а источник запроса, и, только потом, сбрасывать флаг (pending бит) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 5 апреля, 2021 Опубликовано 5 апреля, 2021 · Жалоба 2 часа назад, rudy_b сказал: В начале нужно сбросить не флаг прерывания, а источник запроса, и, только потом, сбрасывать флаг (pending бит) А что такое "источник запроса"? И каким образом его нужно сбросить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rudy_b 4 6 апреля, 2021 Опубликовано 6 апреля, 2021 · Жалоба В стандартных случаях источником запроса на прерывание является периферия, DMA и т.п. Например при приеме байта UART при разрешенном прерывании, таймер, SPI и т.д. Они устанавливают запрос на прерывание, он отрабатывается процессором и запускается соответствующий обработчик прерывания. Для сброса источника прерывания, как правило, нужно считать соответствующий регистр или ручками сбросить бит в периферии. А, затем, снять бит в NVIC процессора. Последнее может делаться автоматически при возврате из прерывания по reti. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 6 апреля, 2021 Опубликовано 6 апреля, 2021 · Жалоба А вот мне кажется, что именно Вы, @rudy_b, не совсем понимаете, о чем говорите. Последним сообщением Вы просто, по сути, пересказали то, о чем говорил @jcxz. Ведь тезисом 22 часа назад, rudy_b сказал: Сразу видно, что вы не умеете работать с прерываниями... явно затевался, видимо, какой-то аргументированный спор. И не надо снимать бит в NVIC - в некоторых случаях так можно только потерять событие. Да и нет в Cortex-Mx никакого RETI. Для них ISR не отличается по ABI от обычной функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 6 апреля, 2021 Опубликовано 6 апреля, 2021 · Жалоба 7 часов назад, rudy_b сказал: А, затем, снять бит в NVIC процессора. Последнее может делаться автоматически при возврате из прерывания по reti. Давайте вы почитаете учебник по теме "Ядро Cortex-M. Механизм прерываний.", узнаете что такое NVIC, как работают прерывания в нём, какие там есть флаги, зачем они и как производится вход и возврат из прерывания в Cortex-M. Как используется регистр LR при этом. Почему бесполезно в конце ISR проверять наличие флага нового прерывания. Почему в типичном ISR не нужно трогать pending-биты и другие биты в NVIC. А потом придёте на пересдачу. А пока вам - назачёт по теме. Arlleex вам уже задал начало правильного направления и подсказал некоторые моменты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться