Комментарии 31
меня статья в ступор завела
разве это не абсолютный клон stm32?
Клон это GD32F103, а GF32VF103 — это не клон. Работает походу китайский маркетинг… Я как раз там на этом заострил внимание.
Пусть вас не смущает буква F в названии микроконтроллера GD32VF103 — это просто маркетинговое название, чтобы было похоже на уже существующую линейку GD32F103 на ядре CortexM3. Никакой поддержки инструкций с плавающей точкой здесь нет. Наверное, ставка была на то, что кто-то спутает GD32F103 с STM32F103 и не заметит подвоха… а затем еще спутает и GD32VF103 c GD32F103. Мой продавец попался в эту ловушку (это другая ловушка, если что), и вначале мне пришел микроконтроллер GD32F103, вместо GD32VF103.
Такое чувство, что разработчики RISC-V подглядывали в MIPS, когда обводилипроектировали ядро
Даже выпустили отличный совместный учебник-справочник по RISC-V в 2018 году: Patterson, Hennessy «Computer Organization and Design RISC-V Edition».
Логично что китайцы воспользовались наработками по MIPS для проектирования своей реализации топологии RISC-V ядра.
Спасибо за статью!
Мне RISC-V нравится. Hello World в Platform IO был, а потом перешел на EmBitz (как и в случае с ARM). А процессор — Kendryte K210.
Примерно так: https://youtu.be/IpXfuqj_YmY
Вам нужно будет знать некоторые данные архитектуры конкретного процессора. Разрядность, адреса памяти и т.д. чтобы указать опции для компиляции. Сформировать, в частности, LD файл для редактора связей.
И конфигурируем его.
Открываем вкладку Settings->Tools, в ней в поле Selected compiler задаем ARM GCC… (или другой по вкусу).
Во вкладке Toolchain executables указываем:
C compiler — riscv64-unknown-elf-gcc.exe
CPP compiler — riscv64-unknown-elf-g++.exe
И так далее. Можно с путями, а можно в переменные среды вписать.
Были некоторые проблемы при компилировании проектов C++, путем гугления решились на удивление быстро. Работают на ура проекты C и C++. (Потом то, что нужно, перевел на чистый C).
Обычно с платой разработчика приходят некоторые файлы для начала работы. Или в PlatformIO, или в Arduino, или ещё в чём. Вот оттуда можно вытащить информацию, чем их компилировать, с какими опциями, а также LD файлы.
Пожалуйста, не сдавайтесь, всё получится.
P.S. Для Raspberry Pi 3+ делал проекты в EmBitz на «голом железе», подключив aarch64-linux-gnu… (и без -linux- тоже).
Нравится EmBitz. Работал с ADS1.2 (Metrowerks), c Keil, c IAR, с PlatformIO…
На работе точно, это рискованно… у нас надежные применения. А вот в университете — почему бы нет. Я все отечественный жду на этом ядре, там хоть его использование будет обосновано в связи с 719 постановление правительства.
Или вот совершенно новый российский мк на risc V, первые кристаллы уже готовы, начинается разработка sdk, тестирование и допиливание документации RISC-V микроконтроллер MIK32 (mikron.ru)
А вообще есть кардинальная разница между GD32/GF32 и STM32?
Даже не знаю, могу только сказать, что регистры периферии прямо почти слизаны с STM32. Но могу ошибаться.
И еще немного не понял — камень 32х разрядный а внешние порты 16 — зачем?
Адрес возврата записывается в mepc регистр. В pc загружается адрес обработчика… при выходе в pc обратно записывается адрес из mepc. Тоже самое про mstatus. Текущий режим, текущее состояние разрешения прерываний сохраняются в нем, при выходе восстанавливаются. В стек ничего не сохраняется — все руками нужно сохранять.
- При входе в ловушку ядро обновляет CSR контрольные регистры
- mcause
- mepc
- mstatus
- mintstatus для прерывания или исключения
- Одновременно ядро переходит в Машинный Привилегированный режим и в соответствующий подрежим машинного режима
- В это же время останавливается выполнение текущей программы и PC загружается адрес обработчика ловушки в зависимости от того, какое событие произошло — Исключением, Прерывание или NMI. Адрес обработчика может браться из разных регистров.
А interrupt latency не пробовали измерять? Подавать на вход прерывания сигнал с внешнего генератора, в обработчике менять состояние какого-нибудь пина, и измерять прошедшее между этими событиями время. Интересно, насколько результат будет отличаться от STM32, там interrupt latency в районе сотен наносекунд.
Не измерял, но судя по описанию должно быть больше. Так как нужно сохранять рабочие регистры при входе, а в не-векторном режиме еще искать нужную функцию и вызывать её.
The overhead caused by jumping to the interrupt handler which is about 4 cycles ideally.
The overhead caused by saving CSRs mepc, mcause, msubm into the stack is about 3 cycles ideally.
if it is RV32I architecture, then there are 16 general purpose registers required to be saved.
The overhead caused by jumping to the Interrupt Service Routine which is about 5 cycles ideally.
Однако, в не-векторном режиме, есть такая фишка, как упреждение прерывания, т.е. если у вас одновременно несколько прерываний случилось, то можно контекст сохранить только один раз, на первом прерывании… а на последующих уже не надо. https://doc.nucleisys.com/nuclei_spec/isa/interrupt.html
В векторном режиме такого нет, там просто всегда нужно контекст сохранять (В отличии от STM, где stacking делается аппаратно, одновременно с переходом на обработчик), ну и, соответственно, затрат на поиск указателя на функцию обработки прерывания и её вызов в векторном режиме нет.
Вы про обертку над регистрами? Про самый верхний класс, типа CSR?
Так генерилку сделал… Она уже генерит структуры, переделывать поздно.
Согласен, для сокращения наверное удобнее было бы.
Вы про обертку над регистрами?
Да нет, про структуры вокруг статических обработчиков прерываний…
Дак, заранее же непонятно какие они будут, SystemTimer, например, это целый класс с ссылками на программные таймера. Потом вообще любой статический метод любого класса можно сделать обработчиком. Поэтому есть смысл сделать все в одном стиле. Иначе, странно выйдет, в одном случае так, в другом по другому...
Прочитал, но не понял самого главного. Откуда iar компилятор, если это свежий китайский чип?
Светодиод, таймер и прерывания на RISC-V с нуля (на примере GD32VF103 и IAR C++)