Pull to refresh
120
2
Send message

Это если бы я рассказывал о силовой электронике. И начинать бы пришлось с законов Ома и Кирхгофа. Но я рассказываю об архитектуре ЭВМ. Здесь светодиоды - всего лишь индикация. Описать вообще все области, где применяются контроллеры, я не смогу физически.

Набор расширений - IMA(F)C. Раз расширение "A" поддерживается, значит, должны быть. Но, еще раз говорю, сам я его не тыкал. Хм, а остальные тыкал. Может, и исправлю когда-нибудь этот пробел. Но не в приоритете, в этих камнях куча куда более интересных вещей. Да хоть прерывания или уровни привилегий.

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

У stm тоже не все так гладко. Недавно натыкался то ли, то ли на вопрос на форуме на статью (сейчас с ходу не нашел), что если подавать 5 В при выключенном питании, оно просачивается куда не надо, а это опасно. То есть защита там включается только при подаче питания на сам контроллер.
И у GD / WCH такая защита тоже наверняка есть. Но она не описана в документации и, в частности, неизвестно, какой ток она держит.

Спасибо что напомнили. Шпаргалка-то у меня есть, просто в статью добавить забыл
UPD: добавил в конце ссылку на шпаргалку и на общую документацию.

Именно для портов, как и у stm32, аналог регистра BSRR. У GD32 это GPIO_BOP / GPIO_BC, у CH32 - BSHR / BCR. У некоторой другой периферии бывают другие механизмы защиты от одновременного доступа.
А если речь об атомарных функциях уровня ядра, то расширение A как раз за это отвечает. Самому мне им пользоваться не приходилось, но если интересно, можете посмотреть в описании risc-v ""A" Extension for Atomic Instructions".

Думаю, что по доступности, да и по параметрам сравнимы.
У WCH есть несколько интересных моделей. Например, ch32v307, у которого аппаратный USB-HS (480 Мб/с) плюс не менее аппаратный Ethernet (10 Мб/с). Вроде бы собираются запускать v317, у которого эзернет будет 100 мегабитный. У того же v307 просто неприличное количество UART-ов: 8 штук в 64-ногом корпусе (ума не приложу где столько может пригодиться). Есть серия v208 с аппаратным блютусом. И напротив, есть всякие v203 в достаточно приятных корпусах, которые пригодны для новичков - CH32V203K8 в lqfp32 (шаг выводов 0.8) или, как на моей кошмарной платке под спойлером CH32V203G8 с шагом 0.635. Это не то что для ЛУТа проблем не представляет - это можно от руки маркером нарисовать. Есть v103, которая по мощности и периферии так себе, зато пятивольтовая. Есть v003 (и вроде как планируется v006), которая тоже пятивольтовая, но максимально дешевая и примитивная. Но все равно 32-битная. Мне она неинтересна именно в силу примитивности - на ней ничему не научишься.
Именно по сравнению с дешевыми stm - несколько выше частота. 108/144 МГц против 72 МГц у f103. Причем почти вся память кешируется в оперативке, то есть никаких wait-state-ов.
Впрочем, к stm-кам и прочим arm-ам я не особо присматривался. Наверняка, там есть не менее интересные камни.
Но по большей части мне просто ассемблер понравился. Гораздо проще для изучения, чем arm или тем более x86. То есть отличное наглядное пособие для изучения внутреннего устройства ЭВМ.

Не знаю как там у вас в IDE, но флаги-то компилятора где-то задать можно. Возможно, сложнее, чем руками в makefile, но мало ли, в настройках проекта...

даже в примере с названием FPU, собственно FPU не настроен.

А чего его настраивать? В смысле что в нем вообще поддается настройке? Единственное, что вспоминается - настройки округления. Которые почти никогда не нужны.

Если интересно, про дробные числа в v303 я когда-то писал.

Так что я исключительно про экосистему WCH.

"экосистема wch" это в первую очередь сами контроллеры. В вашем случае v307. Он прекрасно поддерживает FPU. И все, что требуется от программиста - указать компилятору архитектуру IMAFC. Не удивлюсь, если в примерах от производителя она и так указана.

Кстати, либо я что то не понимаю, либо все проекты из MountRiver для CH32V3xx по умолчанию не используют при компиляции FPU

Речь идет о примерах от WCH? Так-то никто не запрещает указать архитектуру -march=rv32imafc_zicsr и пользоваться FPU в свое удовольствие.

__attribute__((interrupt("WCH-Interrupt-fast")))

Здесь стоило уточнить, что это нестандартное расширение от wch, обычный gcc его не поддерживает. Есть несколько костылей вроде вот такого:

void TIM3_IRQHandler(void) __attribute__((naked)); //Это чтобы не компилятор не сохранял контекста и не делал обычного возврата
void TIM3_IRQHandler( void ) //Это чтобы сохранить регистры s0 и s1, если они используются в вызываемом коде и чтобы сделать подходящий возврат mret вместо ret
{
    __asm volatile ("call TIM3_IRQHandler_Real; mret"); //Вызов naked-кода для обработки и возврат из прерывания
}

void TIM3_IRQHandler_Real( void )
{
 /* Interrupt handler that works with upstream GCC */
}

Но тоже не идеально. Скажем, с FPU это вообще не работает.

Контроллер прерываний PFIC

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

Зачем это сделано - без понятия.

На самом деле, при изучении данной темы у меня была конкретная цель: я хотел сделать простой программатор для STM32 на базе преобразователя USB-UART, в котором выводы DTR и RTS используются для автоматического сброса микроконтроллера и активации встроенного заводского загрузчика программ.

Повторить функциональность stm32flash что ли? Только использование RTS/DTR для Reset/Boot0 не очень удобно. Когда утилита прошивки завершает работу, операционка может вернуть RTS/DTR в неудобное состояние. Например, оставить Reset на земле.

Впрочем, я такое тоже делал - для контроллеров WCH. Они через stm32flash программироваться не умеют, пришлось писать свою утилиту. И там тоже предусмотрел RTS/DTR.

Но удобнее всего оказалась самодельная платка на stm32f103 (по мотивам вот этой моей статьи), отображающаяся в системе как два COM-порта /dev/tty_STFLASH_0 и /dev/tty_DBG_0. Через первый можно прошивать, а через второй - отлаживать. Причем если на STFLASH выставить скорость 50 бод, можно управлять тремя выводами: байт 'b' отвечает за линию boot0, 'r' - reset, 'u' - реле, разрывающее линии D+/D- USB (не пригодилось). Ну и 'z' возвращает все в дефолтное состояние. Такое нестандартное управление гарантирует, что никто посторонний этими линиями управлять не будет. Ну а разделение порта программирования и порта отладки - что не надо каждый раз перезапускать screen.

Если верить Кириллу Лейферу (https://www.youtube.com/watch?v=hYpaVExfbu4 https://www.youtube.com/watch?v=8rfFLeFzgxE https://www.youtube.com/watch?v=OoZAdkxdjb8), в более новых моделях были и ЖК экраны и, кажется, плазменные. А первый да, электролюминисцентный.

Статья про плату с ценой меньше доллара в сумме с доставкой.

А камень отдельно ~20р.

Плату с m328, с v203 или с x035 на том же Алиэкспресс можно получить минимум в полтора раза дороже

И что? Этих плат нужно одну-две штуки на всю жизнь. И уж лучше взять плату с полноценным контроллером.

Плата позволяет не использовать ноги, только разъем usb, немного странным способом.

Да вроде и UART выведен на гребенку, и SDI. То есть вообще нет нужды пользоваться неудобным USB-разъемом.

Мой личный опыт показывает что это гораздо удобнее чем использовать 2.54мм колодку разъемов.

Мой опыт говорит обратное. К штырькам можно подключить любую периферию в любом порядке, достаточно пары перемычек с гнездами по типу ардуиновских. А к специализированным разъемам можно подключить только что-то специализированное.

Предполагаемое использование текущей платки далеко от промышленности.

Не платки. Контроллера. Если уж выбирать максимально дешевый камень, глупо тратить деньги на плату.

Она для любителей простых и дешевых решений. Для людей, что сейчас используют в своих проектах платки ардуинки.

Не вижу у нее существенных преимуществ перед m328. По памяти сравнимо, по скорости тоже. Ну ладно, втрое выше. Это ж шило на мыло менять. Для сравнения, та же v203 имеет 10-20к оперативки, минимум 32к флеша, в 9 раз быстрее и гораздо больше периферии.

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

Да на здоровье. Вот только через UART прошиваться могут и все остальные камни. Причем, в отличие от v003, у них загрузчик исправно работает прямо с завода. Собственно, я свои платы именно через UART и прошиваю.

Нет цели сделать аналог Ардуино, вся статья про работу с единственной платой, самой дешёвой из доступных, и про способ работы именно с ней.

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

Бедная периферия, слабое ядро, но для большинства простецких проектов этого достаточно

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

Потому что все эти DBG_STATUS_ предназначены в первую очередь не для преобразования в строку, а чтобы отслеживать ошибки внутри программы. Возвращать из функций, использовать в качестве кода завершения программы, возможно для логов.
Идея использовать вместо короткого числа указатель на строку, конечно, интересная, но указатели ведь при каждом запуске новые будут. То есть когда программа упала, расшифровать коды ошибок будет сложно.

Если вам даже в текущем варианте хочется получить набор плат, то можете написать мне в личные сообщения на площадке. Попробую помочь, какой-то минимальный запас и плат и кабелей (с uart-ом на type-c) у меня есть.

Не спешите с этим. Если уж делаете аналог ардуино, так и делайте. Совместимость по посадочным местам, распиновке, способу прошивки. Отдельный кристалл без рабочего бутлоадера купить несложно. Я в свое время тоже щепотку купил, но так и не притрагивался: уж больно бедная там периферия, да и ядро. Даже v203 интереснее, не говоря уж о v307.

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

Хорошо. Так в чем вопрос-то тогда? Если мы рассматриваем покупку готовой отладочной платы, то и там и там производитель будет зашивать загрузчик. Если самостоятельное изготовление - и там и там понадобится программатор. Единственная разница, что ардуинки на m328 выпускают все, кому не лень, а на v003 - нет. И именно эту "несправедливость" хочет исправить автор.

Существует как _countof и в вариациях имени типа array_size, ARRAY_SIZE, std::ranges::size

На все эти варианты gcc ругается undefined reference to `countof'. Может, в Си этой функции все же нет? Или имеется в виду вообще любая, в том числе самописная, функция / макрос вида (sizeof(x)/sizeof(x[0]))?

Просто проверяем, на момент компиляции, что размер массива сопадает числу элементов ENUMа.

Если используется явное указание индексов {[x]=y, [z]=w,...}, это не спасет от пропущенного элемента в середине. А если как в исходном примере {y, w, ...}, то от перепутанного порядка.

Когда в массиве элементы перечислены последовательно -- сравнивая countof()

Что такое countof? gcc ругается, гугл ссылается куда-то в С++. Или я что-то неправильно понял?

Мета-макросы, как @RR_Zz упоминул ниже;

Интересная штука. Надо будет над ними помедитировать поподробнее.

unit-testing

Это все же не средствами языка

Спасибо. Вариант с мета-макросами интересный, может и пригодится когда.

Есть много способов отследить и убедиться в этом.

Средствами языка и без накладных расходов? Что-то ничего в голову не приходит.

Information

Rating
1,379-th
Registered
Activity