В этой короткой заметке я попытаюсь сравнить три разных микроконтроллера по времени реакции на внешнее прерывание. Дело это интересное, просто потому что иногда микроконтроллер должен реально контролировать и желательно по-быстрее. Ну и конечно, хочется оценить работу шины, прерываний и всего остального.
Итак, схема опыта очень проста — будем использовать 3 первые пина порта GPIOA, первый как источник внешнего прерывания (exti0), а 1 и 2 для вывода данных. Хватило бы и одного, но тогда осциллограф, как понимаете, подключать не так удобно — а на скорости кода это не сказывается. Первый пин и второй, естественно, соединим проводком…
Будем подавать на второй пин высокий уровень, это вызовет прерывание, сработает обработчик. В нем будем просто выводить 0 на все пины порта GPIOA — а по факту на второй и третий, получается. И цикл повторяется. Код примерно одинаков и для ARM и для RISC-V и приведен ниже.
Да, для опытов у нас будет два процессора ARM, обе stm — так уж вышло, они были под руками — stm32f103 и stm32h750, соответственно, первую запустим на 64 МГц, а вторую на 400 МГц (ну на шине будет всё равно 200 МГц). А вот для RISC-V попалось изделие WCH-IC а именно ch32v307 и он будет у нас на 144 МГц. Кстати, в нем реализовано железячное переключение при прерывании с сохранением регистров, так что если постараться, то можно несколько еще ускорить код, выбросив пару-тройку тактов.
Однако для эксперимента компилятор был использован с одной и той же опцией оптимизации -Os и никаких трюков не применялось. Код на ассемблере получился примерно похожий, с ньюансами, конечно, но всё же…
Итак, сам код
// это код обработчика для ARM void EXTI0_IRQHandler(void) { __HAL_GPIO_EXTI_CLEAR_IT(1); GPIOA->ODR = 0; } // а это для RISC-V void EXTI0_IRQHandler(void) { EXTI->INTFR = EXTI_Line0; GPIOA->OUTDR = 0; } // ну а это код выполняется в главном цикле for(;;) { GPIOA->ODR = 6; __NOP(); // и так далее примерно 100 раз ... }
Для замеров использовался осциллограф с 1 Gsps, что дает разрешение в 10 нс — вполне для наших целей подходящее. На экране, конечно, череда импульсов — ну это как и ожидалось.
Итак, вот замеры — еще раз подчеркну, что так как точность 10 нс (а цикл шины у h750 всё же 5 нс), то и число округлялись до десяток.
Микроконтроллер |
stm32f103 |
stm32h750 |
ch32v307 |
Архитектура |
ARM |
ARM |
RISC-V |
частота шины, МГц |
64 |
200 |
144 |
время импульса, нс |
610 |
200 |
120 |
Итак, что жы мы видим? Ожидаемо на почти втрое большей частоте шины H750 имеет в три раза меньшее время.. Но посмотрите — а risc-v то при меньшей частоте шины дает вдвое меньшее время! Это очень интересно… А если еще и оптимизировать код, думаю, можно выдать еще на 10-15% меньшее время. Ну тут конечно, надо не забывать о скорости работы самого порта — у всех была выставлено максимальная скорость (это 40 МГц для ARM и 50 МГц для RISC-V), так что по этому параметру надо было бы округлять до 20 нс.
И всё равно, похоже для «быстрых» приложений RISC-V, похоже всухую выигрывает у ARM. Если не согласны, напишите в комментариях, как говорится 🙂
ссылка на оригинал статьи https://habr.com/ru/post/718818/
Добавить комментарий