Недавно мне в руки противоестественными путями попал интересный представитель RISC-V контроллеров производства НИИЭТ. Упакован он в пластиковый lqfp100 корпус, в котором скрывается ядро на 50 МГц, мегабайт флеш-памяти и 256 кБ оперативки. Разумеется, в наличии и стандартная периферия вроде UART-ов, SPI и USB. А вот из необычного — сигма-дельта АЦП на 16 бит. Ну и всякая неинтересная периферия вроде аппаратных модулей шифрования. Сразу оговорюсь, что тыкаю палочкой я его меньше двух недель, поэтому здесь описаны именно первые впечатления.
1. Корпус и плата
Корпус у контроллера большой, стоногий. Что любопытно, НИИЭТ расположили выводы портов GPIO по порядку, а не хаотично как какие-нибудь stm. Разве что между PB7 и PB8 не удержались и воткнули-таки одно из питаний. Это приятно. А вот что неприятно, так это куча абсолютно бесполезных AT_IN и WAKEUP, которым зачем-то отвели индивидуальные ноги вместо того, чтобы совместить с чем-то полезным. Да и USB могли бы убрать в альтернативную функцию, все равно, если верить еррате, он едва работает. А вот вынесение аналоговых входов понять можно: вероятно побоялись наводок на них от цифровых цепей. В конце концов, если уж ставить 16-битный АЦП, глупо портить сигнал посторонними шумами. На это же указывает наличие отдельной ножки AREF, выводов под соответствующие конденсаторы и вообще группировка всей аналоговой части в одном углу.
Еще в глаза бросается, что выводы SPI назвали нетрадиционно: вместо обычных MISO, MOSI обозвали их RX, TX. Впрочем, переключение режима ведущий — ведомый прямо на лету требуется не так уж часто, наверное это не доставит слишком больших проблем.
2. Карта памяти и стартап
В отличие от тех же stm32 (и контроллеров, которые создавались под впечатлением от них — gd32, ch32), флеш-память начинается не с 0x0800'0000, а с 0x8000'0000, ОЗУ с 0x4000'0000 (второе ОЗУ — с 0x1000'0000), а периферия с 0x2000'0000. А вот бутлоадера не завезли, поэтому его придется изобретать вручную.
Стартует камень на встроенном RC-генераторе на 1 МГц, но программно можно переключиться на внешний кварц или ФАПЧ до 50 или 60 МГц (в документации встречаются и то, и другое). И тут, внимание, грабли: частота встроенного RC-генератора довольно сильно отличается от заявленной. В моем экземпляре она оказалась примерно 947 кГц — более чем на 5% ниже обещанного. Это настолько большая погрешность, что не позволяет обеспечить работу UART без ручной подстройки.
Стартап, расположенный в официальном репозитории, был, похоже, взят от существенно более сложного ядра. Там неоднократно упоминаются Hart-ы, вызывается прямая проверка поддерживается ли FPU, предприняты специальные ухищрения для получения позиционно-независимых адресов. В относительно несложном микроконтроллере все это ни к чему, поэтому я его переписал. Из интереса — на Си. Получилось чуть компактнее, но менее универсально. И, честно говоря, учитывая количество ассемблерных вставок, смысла от Си в стартапе для RISC-V немного. Отдельно отмечу вот этот участок стартапа от НИИЭТ (чуть сократил):
.macro load_addrword_abs reg, sym
.option push
.option norelax
lui \reg, %hi(\sym)
addi \reg, \reg, %lo(\sym)
.option pop
.endm
...
load_addrword_abs gp, __global_pointer$
Здесь в регистр gp
записывается абсолютное значение переменной __global_pointer$
, объявленной в ld-скрипте. Обычное присвоение выглядело бы как la gp, __global_pointer$
, развернулось бы в auipc + addi
и записало бы в регистр значение, вычисленное относительно pc
. Отличие в том, что "фирменный" стартап может быть прошит не только в 0x8000'0000, но и в любое другое место без перекомпиляции. Вот только пользу из этого извлечь можно только когда и весь остальной код написан в том же стиле. Под контроллеры же обычно позиционно-независимый код не пишут, и все наши обращения к переменным из Си будут развернуты в тот же la
, что сводит смысл от страдания со стартапом на нет. Поэтому в своей версии я оставил la
.
Ах да, еще "фирменный" стартап требует наличия функций memset и memcpy. Они, конечно, есть в libgcc, но его подключение в мейкфайле тоже может оказаться далеко не таким тривиальным, как хотелось бы. Разумеется, я говорю про обычный risc-v gcc из репозитория.
3. Прошивка
Как уже было сказано, бутлоадер в данный контроллер не записали. И, зная любовь различных производителей делать бутлоадеры ни с чем несовместимыми, возможно, оно и к лучшему… Но вот что не сделали отдельной области памяти и отдельной ножки, конечно, недочет. Поэтому прошивка по умолчанию возможна только через JTAG при помощи пропатченного openocd. Ну хоть не стали изобретать свои проприетарные протоколы, как, скажем, WCH, камни которого шьются только их же wch-link-ом. В данном же случае можно обойтись обычным программатором на микросхеме ft2232. У меня, правда, нашелся только ft4232, но по сути это тоже самое. На всякий случай выложу приблизительное заклинание прошивки (хотя особой нужды в этом и нет. Спасибо НИИЭТам, свои примеры они не скрывают: niiet_riscv_sdk/tools/openocd/openocd-snippets/README.md
):
../xpack-openocd-k1921vk-0.12.0-k1921vk/bin/openocd -f ft4232.cfg -f k1921vg015.cfg -c 'init' -c 'reset halt' -c 'program firmware.bin 0x80000000 verify' -c 'reset run' -c 'exit'
Внимание, грабли: прошивка по JTAG не может полноценно поресетить контроллер. В регистрах сохраняются старые значения, и это здорово мешает. Лично я пока что использую костыль с ручным ресетом кнопкой. Возможно, есть какая-то команда и для openocd чтобы он все-таки ресетил контроллер по-нормальному.
Также, я думаю, здесь самое место рассказать об одной интересной ножке, SERVEN. Если ее подтянуть к питанию во время старта, контроллер перейдет в сервисный режим, в котором его можно только стереть. Сначала я подумал, что это просто еще она "лишняя" ножка, которой разработчики не нашли применения (как те же AT_IN). Но нет. Иногда, записывая некоторые значения в регистры, контроллер можно превратить в кирпич. Причем настолько качественно, что JTAG к нему подключиться не может. В этом случае ножку SERVEN можно замкнуть на питание (после чего JTAG все-таки подключается, но полноценно все равно не взаимодействует) и подать команду сервисного стирания. Это важно: не обычного, а именно сервисного. В общем, себе я на всякий случай написал отдельную команду для makefile:
unbrick:
echo "Connect SERVEN to VCC, reset controller and press Enter"
read
ssh $(virt) "cd /home/user/prog/vg015/rem ; "\
"../xpack-openocd-k1921vk-0.12.0-k1921vk/bin/openocd -f ft4232.cfg -f k1921vg015.cfg -c 'init' -c 'reset halt' -c 'mww 0x3000F104 0x00000100' -c 'mdw 0x3000F104' -c 'reset run' -c 'exit'"
4. GPIO
Портов у нас три. Как я уже сказал, они удобно сгруппированы по трем сторонам корпуса, и ноги в них идут подряд. У каждой ноги есть хотя бы две альтернативные функции — I2C, Timer,… ну, все как обычно. А вот работа с ними уже необычна. Вместо одного — двух регистров, отвечающего за режим работы, вход — выход, наличие подтяжки и т.д., в которые можно писать нули и единицы, здесь многие регистры организованы по принципу set — clear. Например, в регистр OUTENSET
можно записать единицу, это переведет соответствующую ножку в режим выхода. Но вот запись нуля не повлияет ни на что. Чтобы вернуть ее в режим входа, надо записать единицу в другой регистр, OUTENCLR
. Такой подход проявляется повсюду. Вероятно, разработчики хотели сделать работу с периферией максимально атомарной, но при первом знакомстве это изрядно ломает мозг.
А вот с регистром выхода DATAOUT
они, наоборот, недожали. Да, у него есть DATAOUTSET
, DATAOUTCLR
и даже DATAOUTTGL
, но вот атомарной установки по маске (аналог GPIO->BSRR
в stm32, где можно было в reset-половину записать маску, а в set — значение) как раз нет. Ну, по крайней мере, я не нашел.
Альтернативные функции порта задаются в "обычном" (не set-clear) регистре ALTFUNCNUM
(а вот само их включение — как раз в set-clear паре ALTFUNCSET
, ALTFUNCCLR
). Причем сами номера альтернативных функций не прописаны нигде. Есть предположение, что они соответствуют положению вот в этой таблице
То есть для PA4 альтернативной функцией 1 будет UART2_RX, функцией 2 будет TMR1_CCIA, а функцией 3 — QSPI_CLK. Как минимум, для UART это предположение подтверждается, но как на самом деле, пока не знаю.
Также из таблицы видно, что альтернативные функции назначаются не для периферии, а для самих портов. То есть можно настроить, например, UART0_RX на PA0, а на UART0_TX не PA1, а PB7. Более того, можно настроить и PA1, и PB7 на UART0_TX, выход UART пойдет на обе ножки. Что будет, если настроить две ножки на RX, я проверять не рискнул.
Что еще интересно в регистрах 1921вг015, так это то, что в заголовочном файле разработчики прописали не только битовые маски, но и битовые поля:
/*-- DATAOUTSET: Data output set bits register ---------------------------------------------------------------*/
typedef struct {
uint32_t PIN0 :1; /*!< Data output set bit 0 */
uint32_t PIN1 :1; /*!< Data output set bit 1 */
uint32_t PIN2 :1; /*!< Data output set bit 2 */
uint32_t PIN3 :1; /*!< Data output set bit 3 */
uint32_t PIN4 :1; /*!< Data output set bit 4 */
uint32_t PIN5 :1; /*!< Data output set bit 5 */
uint32_t PIN6 :1; /*!< Data output set bit 6 */
uint32_t PIN7 :1; /*!< Data output set bit 7 */
uint32_t PIN8 :1; /*!< Data output set bit 8 */
uint32_t PIN9 :1; /*!< Data output set bit 9 */
uint32_t PIN10 :1; /*!< Data output set bit 10 */
uint32_t PIN11 :1; /*!< Data output set bit 11 */
uint32_t PIN12 :1; /*!< Data output set bit 12 */
uint32_t PIN13 :1; /*!< Data output set bit 13 */
uint32_t PIN14 :1; /*!< Data output set bit 14 */
uint32_t PIN15 :1; /*!< Data output set bit 15 */
} _GPIO_DATAOUTSET_bits;
Благодаря этому выставить PA3 в лог.1 можно не только наложением маски GPIOA->DATAOUTSET = (1<<3);
, но и обращением к соответствующему битовому полю GPIOA->DATAOUTSET_bit.PIN3 = 1;
. Не то чтобы это сильно на что-то влияло, но подход интересный. Опять же, когда битовые поля состоят из нескольких битов, запись может получиться чуть более компактной.
5. Прерывания
А вот тут разработчики решили обойтись необходимым минимумом. В стандарте RISC-V описана единственная точка входа в обработчик, вот и нам хватит. Никаких таблиц векторов прерываний, никаких таблиц адресов. Даже разделения на прерывания и исключения — и то нет. При любом событии ядро прыгает по адресу mtvec
, а дальше уже пусть программисты разбираются. Вот только программисты немного схалтурили:
void PLIC_MachHandler(void) {
uint32_t isr_num = PLIC_ClaimIrq(Plic_Mach_Target);
if(mach_plic_handler[isr_num] != NULL_IRQ) {
mach_plic_handler[isr_num]();
PLIC_ClaimComplete(Plic_Mach_Target, isr_num);
}
}
...
void trap_handler (void)
{
uint32_t mcause_val = read_csr(mcause);
if((mcause_val & MCAUSE_INTERRUPT_FLAG) == 0) {
// handle exception
switch (mcause_val & MCAUSE_EXCEPT_MASK)
{
case MCAUSE_EXCEPT_INSTRADDRMISALGN:
break;
case MCAUSE_EXCEPT_INSTRACCSFAULT:
break;
case MCAUSE_EXCEPT_INSTRILLEGAL:
break;
case MCAUSE_EXCEPT_BREAKPNT:
break;
case MCAUSE_EXCEPT_LOADADDRMISALGN :
break;
case MCAUSE_EXCEPT_LOADACCSFAULT:
break;
case MCAUSE_EXCEPT_STAMOADDRMISALGN:
break;
case MCAUSE_EXCEPT_STAMOACCSFAULT:
break;
case MCAUSE_EXCEPT_ECALLFRM_M_MODE:
break;
default: // MCAUSE_EXCEPT UNKNOWN
break;
}
while(1) {}; //TRAP
} else {
// handle interrupt
PLIC_MachHandler();
}
}
Если присмотреться, сначала идет проверка mcause чтобы выяснить прерывание произошло или исключение. И если второе — программа просто-напросто зависает. Даже без возможности добавить юзерский обработчик. Ну а для прерываний они просто разместили в оперативной памяти таблицу mach_plic_handler
указателей на функции обработчиков. И тут даже копированием из более сложного проекта, как в случае стартапа, оправдать нельзя. Ну разве ж это дело, молча зависать при любом исключении! В общем, со временем придется эту функцию переписывать.
А еще я не нашел способа сбросить флаг прерывания программно, без вызова обработчика. Но тут, возможно, просто плохо искал.
6. АЦП
(мнение Бориса, @Debian_ks)
Вчера разбирался с дельта-сигма АЦП. По факту каналы ch0 — ch6 заработали, канал ch7 молчит, даже флаг DATAUPD не выставляется. Помимо этого каналы ch0 — ch6 смещены вниз каждый от -920 до -1020 отсчетов. Кроме этого в SVD файле и K1921VG015.h есть некий регистр DIFF который не описан в руководстве пользователя.
7. Бонус, или "извините, не смог удержаться"
Ну и как же без реализации чего-нибудь красивого и бесполезного. Как-то так сложилось, что у меня одной из первых прошивок под новые контроллеры оказывается реализация трехмерной графики. Так было с stm32, так было с gd32. Так же получилось и с 1921вг015. Разумеется, код ни в коем случае не может служить примером для подражания, но демка это демка, много от нее не требуется. Частота ядра и частота SPI 60 МГц, частота обновления 11 — 12 кадров в секунду, причем ограничена она в основном SPI, а не расчетами.
Заключение
Вот такой вот камень мне довелось пощупать.
Начнем с недостатков. Крайне неточный HSI. Отсутствие таблицы прерываний. Отсутствие бутлоадера. Поддерживается прошивка обычными JTAG-программаторами (это-то достоинство), но все же нужен пропатченный openocd. Целых семь ног отвели под какую-то ерунду — AT_IN, WKUP, плюс еще две под USB. Сами-то функции, может, и могут где пригодиться, но их стоило совместить с GPIO. Слабый USB (даже без учета ерраты, всего 4 конечные точки). Суровая необходимость в ножке SERVEN (иначе говоря, возможность окирпичить контроллер просто записью неверного значения в регистр).
Достоинства. Необычность: что распределение памяти, что подход к регистрам не похож на то, что я видел в stm32; довольно интересно его изучать. Большой объем памяти: 1 МБ флеша и 256+64 кБ ОЗУ. Выводы портов расположены по порядку, а не абы как. Поддерживается прошивка обычными JTAG-программаторами. Мощные аналоговые модули (АЦП, компараторы — теоретически; в реальности я их не проверял).
Возможно, достоинства, но лично мне применить их некуда. Аппаратные блоки подсчета CRC-сумм, хеширования, криптографии (AES-128, AES-256, "Кузнечик", "Магма"), CAN.
В целом, камень весьма интересный. Косяков, конечно, много, но будем надеяться, что НИИЭТ в будущих разработках их исправит. Да и те, что есть, обойти почти всегда возможно. Полагаю, что применение ему в каких-то устройствах найдется.
Комментарии (111)
Mox
17.02.2025 11:50А где его реально делают? И делают ли?
torgeek
17.02.2025 11:50Ядро риск5 — делают в Петербурге.
СФ-блоки — скорее всего собственные проекты компании в Воронеже.
Топологию всего чипа делают в Воронеже.
Кристаллы выпекают, наверное, в поднебесной.
Корпусировку чипа делают в Воронеже, хотя именно эта партия, может и нет.
Тестирование делают в Воронеже.
Отладочные платы делают во Владивостоке.
Рабочую документацию и системный софт делают в Воронеже и Владивостоке.Mox
17.02.2025 11:50Я имею ввиду именно изготовление кристаллов.
А тот просто наши производители CPU никак не могут осилить изготовление в Китае, а внутри РФ только Амур делают - хочется понять - это реально изготавливается или как с Эльбрусами - все выпущенные партии распроданы, ждите.torgeek
17.02.2025 11:50Почему не могут? Это же "мелкие" чипы. Поставки идут бесперебойно с прошлой зимы, как минимум.
checkpoint
17.02.2025 11:50Тоже интересуюсь этим впросом. Есть у кого-то информация на сей счет ?
Судя по описанию, там внутри сэндвич из двух кристаллов - сам МК и flash память. Flash понятно что китайская, а где произведен кристалл МК ?
torgeek
17.02.2025 11:50Его заявили как чип второго уровня, так что понятно — не конкурент АМУРу, который первого уровня.
AKudinov
17.02.2025 11:50Ну разве ж это дело, молча зависать при любом исключении!
Насколько помню, штатный код для STM32 делает так же. А нужно это, чтобы можно было увидеть, что контроллер завис, подключиться отладчиком через JTAG и увидеть, что программа циклит в обработчике исключения, и дальше уже разбираться, как так вышло. Например, прочитать регистры, в которые сохранилось значение PC, при котором было выброшено исключение (STM32 так делает; как здесь реализовано, не знаю).
COKPOWEHEU Автор
17.02.2025 11:50Принцип максимизации ошибки это, конечно, хорошо. Плохо, когда ошибку не дают отследить из юзерского кода. Самое простое - могли сделать дефолтный обработчик исключений и объявить его weak. Соответственно, если юзер напишет свою альтернативу - использоваться будет она. И, насколько я понимаю, в stm32 используется именно такой подход. Те же ecall-ы как иначе отслеживать? Это же не ошибка, это именно системный вызов.
AKudinov
17.02.2025 11:50Согласен с вами. Возможно, предполагается, что пользователь сам перепишет предлагаемый ему код.
Rusrst
17.02.2025 11:50Демка зачёт (камень тоже) ! Может её ещё подробно опишете? Я бы почитал)
COKPOWEHEU Автор
17.02.2025 11:50Про демку там есть ссылка на статью по прототипу, который еще давным-давно под stm32 писался. Что там еще описывать?
Про камень - надо будет сначала самому разбираться. Если чего-то интересное найдется - опишу.
byman
17.02.2025 11:50А вот тут разработчики решили обойтись необходимым минимумом. В стандарте RISC-V описана единственная точка входа в обработчик, вот и нам хватит. Никаких таблиц векторов прерываний, никаких таблиц адресов
Сейчас у RISC-V с этим вроде все ОК. Но похоже МК делался долго и процессорное ядро еще не включало последних обновлений.
COKPOWEHEU Автор
17.02.2025 11:50А можно подробнее? Сейчас пролистал спецификацию на risc-v, не увидел ничего более интересного, чем парсинг того же mcause.
lorc
17.02.2025 11:50У больших ARMов почти так же. Хотя, все же есть отдельные точки входа для прерывания и для исключения. А дальше - либо лезем в контроллер прерываний смотреть что там пришло, либо в регистр ESR, разбираться что за исключение.
byman
17.02.2025 11:50Я имел ввиду работы https://github.com/riscv/riscv-fast-interrupt/blob/master/src/clic.adoc#copyright-and-license-information
rojer
17.02.2025 11:50спасибо за обзор! мне вот показалось странным, что уартов аж 5, а I2C всего один.
во всей своей практике не видел применения для более 3 уартов, а вот разделять слейвы по I2C шинам приходилось (когда нет возможности смены адреса).
jaha33
17.02.2025 11:50Имею обратный опыт, уартов надо 5 и более, а шины i2c одной хватает, на нее 3-4 микросхемы можно вешать. Тут уже каждому свое
rojer
17.02.2025 11:50я же уточнил: когда нет возможности поменять адреса слейвов. плюс, допустим, одна шина может смотреть "внутрь", а другая "в мир", в виде расширения. в любом случае, иметь всего 1 и2ц - это странно.
kgbplus
17.02.2025 11:50У меня ощущение, что этот контроллер делался под конкретную задачу (оттуда и 16 бит АЦП и хитрый бутлоадер)
nixtonixto
17.02.2025 11:50Почти все отечественные СБИС делаются под конкретное применение, в частности, эта - под счётчики. Иначе не выбить денег на разработку.
torgeek
17.02.2025 11:50Тогда уж все СБИС в мире делают под конкретные применения. Зачем делать под случайные не просчитанные задачи? Кстати, у этого ВГ015 неизвестна дола между коммерческими инвесторами, кредитами и госбюджетным заказом. Вполне возможно, что там чип — чисто коммерческая инициатива НИИЭТ. К тому же он напрямую конкурирует по назначению с миландровским риск5 чипом Счётчик, который выпускается серийно несколько лет.
nixtonixto
17.02.2025 11:50Нет. Вот, к примеру, STM32 с такой же мегабайтной флешкой - там и таймеров больше десятка, причём с кучей режимов работы, и все (кроме BOOT0) ноги видны как GPIO, включая ноги резонаторов и программирования, и ремап есть почти на все ноги, и даже у F373 ремап на входы 16-битного АЦП никак не влияет на этот самый АЦП. Тут же таймеров всего 4 шт, чего достаточно какой-то АТмеге, но уже маловато для 32-битника с большой программой... Треть ног прибита гвоздями к какой-то одной функции, из которых конкретно мне сейчас вообще ничего не нужно - может кнопки повешу на WAKEUP-ноги, если не хватит GPIO, но там, возможно, будет не просто фильтровать дребезг и удержание. И вот по этим безальтернативным функциям виден заказчик - какая-то измерительная штука с защитой от вскрытия и шифрацией данных.
COKPOWEHEU Автор
17.02.2025 11:50может кнопки повешу на WAKEUP-ноги, если не хватит GPIO, но там, возможно, будет не просто фильтровать дребезг и удержание.
Это вы здорово недооцениваете бездну геморроя с использованием WKUP как входов. Нормального чтения там нет вообще никак. Единственный способ, которым мне удалось воспользоваться - через прерывание RTC. И этот способ невероятно кривой. Хотя есть шанс, что это я чего-то недоглядел.
torgeek
17.02.2025 11:50Про какой из итальянцев речь? SMT32 не чип, а большая линейка совершенно разных чипов под разные задачи.
У НИИЭТ линейка разнообразная в выпускаемых чипах и в проектируемых. Для примера только чипы на риск5 системе команд:
— К1921ВГ015 в серии
— К1921ВГ1Т разработка
— К1921ВГ3Т разработка
— К1921ВГ5У разработка
— К1921ВГ7У разработка
yaxn
17.02.2025 11:50Спасибо за обзор. Как там дела с сишными библиотеками, они есть вообще? Не хочется самому USB стек делать. И я не вижу реальное применение криптоядра, кроме как делать криптофлешки, ключи и т.п. Жаль, что нет MII, считаю, что добавление Ethernet стека должно быть стандартом 32х битных современных микроконтроллеров.
COKPOWEHEU Автор
17.02.2025 11:50С usb, если верить еррате, там все плохо. Работает только одна конечная точка, и то нестабильно. Впрочем, возможно, это верно только для старых ревизий, а в новых уже все исправлено. Не знаю.
Сишные библиотеки какие-то есть, но лично по мне они неудобные (но я-то вообще не показатель).
Для криптомодулей - хз, возможно, для военных или какой-нибудь бюрократии важен сам факт их наличия. Вряд ли ведь контроллер делали с нуля специально для продажи всяким радиолюбителям.
Ethernet - не знаю, скорее все же нет. Возможность (и желание) протащить к устройству витую пару все же меньше, чем USB или даже CAN. В любом случае, не стоит требовать слишком многого сразу. Именно этот МК заточен больше под аналоговые схемы, чем под сложные вычисления или обмен.yaxn
17.02.2025 11:50Так Ethernet не только про вычисления и обмен. Делать промавтоматику на езернет - благодать, стек обеспечивает большую надёжность и отказоустойчивость, чем RS485, особенно при разработке нового. См. промавтоматику Овен, построенную на stm32.
Для меня применение USB более экзотическая сфера. Флешки вставлять странно, делать клавиатуры и мышки избыточно, делать криптотокен хорошо, но нишевая сфера.
COKPOWEHEU Автор
17.02.2025 11:50В целом - смотря какая задача. Изобразить из контроллера флешку, на которой хранится снятые данные - а почему бы и нет? Или некое комбинированное устройство. Или, в порядке извращения, программатор для таких же микросхем.
В любом случае, вряд ли производительность ядра позволит отличить аппаратный эзернет от spi-ного.
rojer
17.02.2025 11:50езернет легко подключается по SPI. да, надо будет брать MAC+PHY, а не просто PHY, ну так и ладно, зато экономия ног - на RMII нужно 9 штук + резет, на SPI MAC+PHY надо 6 (4 SPI + int + rst). 10 мбит/с вполне потянет.
nixtonixto
17.02.2025 11:50И на каком чипе вы "легко" подключите езернет по SPI? KSZ8851 будет смотреться весьма странно в импортозамещающем девайсе, учитывая, что сайт Микрочипа даже не открывается без VPN, а на чипах WCH это не легко и с кучей ограничений по сравнению с нативным MAC.
rojer
17.02.2025 11:50речь как раз о CH392T - лично подключал, работает нормально. у него там есть претензии на поддержку IP, но их можно смело игнорировать, переводить в raw MAC режим и вперёд, с песнями. у него немного странный протокол и местами глючный SPI, но 2.5 мбита/с он мне выдавал.
checkpoint
17.02.2025 11:50Отчественный Ethernet PHY всё равно не завезли, так что большой разницы нет что и как там будет смотреться. Но в целом, я согласен, что такие МК уже должны иметь встроенный MAC.
rsashka
17.02.2025 11:50стек обеспечивает большую надёжность и отказоустойчивость, чем RS485
но обвязка на порядок дороже и требовательнее к вычислительным ресурсам.
yaxn
17.02.2025 11:50Мы же должны стремиться в светлое будущее, а опираться на RS-485 в новом - путь в никуда. Дешевеет сетевое оборудование, оптика, придуманы надежные отказоустойчивые решения. На моем опыте, с RS-485 на объектах возникает намного больше проблем, нежели с Ethernet, т.к. нет нормального стека с избыточным кодированием, адресацией, контролем линии, приходится каждый раз своё городить. Здесь в чипе пять эрэсов обалдеть, кто-то же ТЗ для поддержки своего легаси писал. CAN убирать не надо.
А еще я перед сном мечтаю об ОКРе с российской PHY микросхемой с xMII интерфейсом. Миландр был близок, но что-то не задалось.
nixtonixto
17.02.2025 11:50У Миландра есть контроллер со встроенным PHY. Но у них другая крайность - 128к флеш, чего даже на SSL маловато, не говоря уже о поддержке кучи протоколов.
yaxn
17.02.2025 11:50Хорошее замечание, что для езернета память нужна. Мы используем LWIP и ModbusTCP на ВЕ3Т, вроде умещается, но стек реально половину объема занимает. Впрочем, можно подключить дополнительное ОЗУ.
Зато во время отладки, стыковки, работы в условиях сильных наводок и помех, проблем было существенно меньше, чем с RS-485. С эрэсом по-классике перепутали RX и TX, землю припаяли не туда, кто-то всю шину повалил, и всё ради баснословной скорости в 921600 бод/с.
madiggo
17.02.2025 11:50На моем опыте, с RS-485 на объектах возникает намного больше проблем, нежели с Ethernet, т.к. нет нормального стека с избыточным кодированием, адресацией, контролем линии, приходится каждый раз своё городить.
Да, точно. Так и норовит поймать наводку, особенно если не на специальном кабеле да с заземлением хреново.
yaxn
17.02.2025 11:50В местах, где будет применяться сабж и другие контроллеры из треда, не экономят на кабеле с заземлением.
Ethernet PHY хорошо проработанная область из-за большого рынка. Можно обеспечить шифрованное TCP соединение на кабеле с плохим, окисленных контактом. Кастомный канальный протокол на RS-485 вряд ли будет также продуман, как в Ethernet.
Более того, если имеется MII интерфейс, то можно подключить оптический SFP, который с лихвой побеждает RS485 по дальности связи, скорости и защите от помех. И при более дешёвом кабеле.
YDR
17.02.2025 11:50отдельный чип флешки и криптозадачи - не очень стыкуются. То ли дело в каком-то чипе для электросчетчиков: флеш на чипе, да еще и заэкранирован проводящими слоями с защитой от иголочки стирания и пр.
almaz1c
17.02.2025 11:50А что по цене?
Со скрипом взяли в работу К1948ВК018 (Амур), хотя в нем очень не хватает CAN интерфейса.
1921вг015 по-жирнее, судя по всему?
torgeek
17.02.2025 11:50Отпуская цена в мелких партиях — около 500 ₽ плюс НДС.
Розница у перепродавцов — около 1 500 ₽.
В марте компания обещает начать официальные розничные продажи через маркетплейсы.Mox
17.02.2025 11:50Чет с такой ценой - это не перемаркированный ли китаец?
COKPOWEHEU Автор
17.02.2025 11:50Перемаркированный вряд ли, уж больно странные решения и странные косяки. Изготовление в Китае возможно. Но давайте верить в лучшее :)
torgeek
17.02.2025 11:50Это не единственный русский чип в этой ценовой категории. Есть у Миландра на том же ядре риск5 и давно в серии, причём АЦП у Миландра, говорят, лучше получается. Скоро у других компаний ожидается выход риск5 чипов. Вариантов больше чем один.
COKPOWEHEU Автор
17.02.2025 11:50речь не про Амур, надеюсь?
torgeek
17.02.2025 11:50АМУР в другой ценовой категории и он пока такой один. Вторую ревизию АМУРа или даже совсем новый чип проектируют, но это не раньше следующего года в производстве. Хотя даже текущие возможности фабрики позволяют изготовить чип с гораздо лучшими характеристиками, как показал МИЭТ со своим экспериментальным риск5 чипом Хаки, выпущенным на том же Микроне.
almaz1c
17.02.2025 11:50Вторую ревизию АМУРа или даже совсем новый чип проектируют
Что новенького ждать? CAN может быть?
byman
17.02.2025 11:50В процессорном ядре есть всякие ID , в отладочном интерфейсе. Можно посмотреть чьё.
COKPOWEHEU Автор
17.02.2025 11:501921вг015 по-жирнее, судя по всему?
Ну да. Плюс встроенная флешка аж на мегабайт есть. И подешевле вроде как. Впрочем, что там с Амуром не знаю, может, у него есть и свои преимущества. Но лично меня вг015 впечатлил больше.
jaha33
17.02.2025 11:50Разительно жирнее, флеша (встроенного) и ОЗУ много, куча интерфейсов. По сути это весьма современный контроллер по всем ТТХ. Если облагородить SDK, то вообще станет хорошо.
Но тут неясно сколько там своего. Та же периферия. Вот будет сейчас народ глюки находить, сможет ли производитель выпускать ревизии чипов с фиксами или нет. Если нет, то китайского в этих чипах сильно больше чем заявляют.
GidraVydra
17.02.2025 11:50Китайцы быстро выпускают ревизии оем чипов по требованию заказчика. Проблема в том, что эти ревизии обычно ломают больше, чем исправляют.
jaha33
17.02.2025 11:50С OEM производством ниразу не сталкивался, но все китайские STM заменители, которые пришли к нам, вообще ревизий не выпускают.
Читаешь reference manual, пробуешь так настроить какие нибудь регистры - что то работает, а что то нет. Потом выясняется что это глюк чипа. Проблем причем много, а китайцы говорят что ревизий делать не будут, пробуйте другие чипы из семейства, может там заработает, если вам это критично. Такое ощущение что они сами только корпусируют, а вся начинка покупная
GidraVydra
17.02.2025 11:50Вы смотрите на это с позиции энд юзера, ради которого никто ревизий делать не будет. Энд юзер для китайцев вообще не является заказчиком, его запросы для них - как письма в редакцию газеты Крыжопольский садовод. Если же ревизию запросит контрактор с объемами, китайцы становятся очень гибкими. Правда, обычно становится только хуже.
jaha33
17.02.2025 11:50Работаю в компании с весьма приличными объемами потребления микросхем. Всякие ST и TI, если были проблемы, всегда шли на встречу или фиксили проблему (естественно не сразу, вполне могло и больше года пройти) или предлагали временные пути обхода или скидки. С китайцами, увы, такого и близко нет.
Разговор то был изначально о том смогут ли НИИЭТ править глюки (а они будут) или забьют. Заказчик то у них видимо уже есть и ему деваться некуда. Но как мы такими путями наразвиваем свою микроэлектронику - неясно.
checkpoint
17.02.2025 11:50Спасибо за статью. Но всё же тема Bad Apple не раскрыта. ;)
COKPOWEHEU Автор
17.02.2025 11:50Еще бы про запуск Doom вспомнили :) Хватит с вас и трехмерного шныга.
Vcoderlab
17.02.2025 11:50Протестируйте пожалуйста, как плывёт результат измерений сигма-дельта АЦП при изменении температуры: поморозить корпус freezer-ом и погреть феном. В официальной документации про точность измерений ни слова, а без этого применять этот МК для точных измерений как-то слишком авантюрно.
Если есть чем, можно при этом ещё померить опорное напряжение на выводе 25 "SDADC_CAP". В документе "РП-К1921ВГ015-v3.pdf" в разделе 22.1 очень интересно написано, что напряжение на этом выводе составляет (1,250 ±0,125) В. Это же 10% разброс! Мне интересно, это допустимый разброс от экземпляра к экземпляру, или оно может в этих пределах во время работы плавать? Если второе, то о какой точности измерений вообще можно говорить?
COKPOWEHEU Автор
17.02.2025 11:50По стабильности ИОНов есть более интересные планы (не только вг015), но там надо здорово с установкой замороситься. Не малейшего представления найдется ли вообще на это время.
А что до SDADC, там же, наверное, можно внешний ИОН подключить на крайний случай?Vcoderlab
17.02.2025 11:50А что до SDADC, там же, наверное, можно внешний ИОН подключить на крайний случай?
Как я понял, нет. Потому что SDADC_CAP - это выход встроенного ИОН для подключения конденсатора 0,1 мкФ. То есть подавать сюда напряжение с внешнего ИОН нельзя - они подерутся. Про возможность использования внешнего ИОН и куда его в таком случае подключать, в руководстве не сказано. Или я не нашёл.
COKPOWEHEU Автор
17.02.2025 11:50Не буду настаивать. Я к местным АЦП пока что и близко не подходил. Важнее было с базовыми цифровыми интерфейсами разобраться. И даже сейчас важнее написать нормальный бутлоадер и собрать стенд для удобной прошивки. В общем, основной специфике вг015 придется подождать
Nick0las
17.02.2025 11:50А чем прошивка через openocd неудобна на стенде?
COKPOWEHEU Автор
17.02.2025 11:50То, что openocd из репозитория не подходит, нужно специальный от производителя. А стенд не у меня стоит, устанавливать туда сторонние программы не хочется.
В любом случае, под "собрать стенд" я имел в виду скорее железо: эмулятор клавиатуры, экрана, UART, микрофона,...wigneddoom
17.02.2025 11:50Ну чтобы OpenOCD из репозитория подходил, есть только один путь - пропихнуть патчи в апстрим, что маловероятно. Тут хоть от производителя, а много лет назад я по всея интернету искал патчи для TI.
COKPOWEHEU Автор
17.02.2025 11:50Мне разбираться с openocd не под силу. Вот написать бутлоадер - другое дело. Впрочем, там видно будет.
8street
17.02.2025 11:50Про возможность использования внешнего ИОН и куда его в таком случае подключать, в руководстве не сказано. Или я не нашёл.
Вроде есть вход AREF.
COKPOWEHEU Автор
17.02.2025 11:50Он может идти только на один АЦП, например, последовательного приближения, а сигма-дельта - от внутреннего (хотя логичнее наоборот). Но это все надо изучать отдельно.
GidraVydra
17.02.2025 11:50Извините, у них погрешность внутренней тактовки 5%, о какой точности измерений в принципе может идти речь?
VT100
17.02.2025 11:50При чём тут это? Или речь о соответствующем временном джиттере дискретизации?
GidraVydra
17.02.2025 11:50Во-первых, речь об отношении разработчика/производителя к точности в целом. Во-вторых, интегрирование в АЦП завязано на тактовку, со всеми вытекающими.
Джиттер будет если задаваемая частота нестабильна.
COKPOWEHEU Автор
17.02.2025 11:50Сдается мне, вы путаете точность и стабильность. То есть систематическую погрешность и случайную. То, что HSI отличается на 5% от номинала, не значит, что он на 5% плавает во время работы - это всего лишь значит, что НИИЭТ не стали его калибровать. Для АЦП важна именно стабильность частоты, а не точность. И интуитивно мне кажется, что стабильность у любых встроенных RC-генераторов будет примерно одинаковая, что у stm32, что у ch32, что у вг015.
VT100
17.02.2025 11:50Недорогие ширпотребные АЦП, вроде встраиваемых в МК, строятся на принципе поразрядного уравновешивания зарядов (последовательных приближений). Поэтому там нет особых требований к стабильности частоты во время квантования сигнала.
Интегрирование - более характерно для измерительных приборов. И там оно делается двухстадийным, для снижения требований к тактовому сигналу.
Dr_Faksov
17.02.2025 11:50Увидел фото печатной платы - и начал читать статью. Чтобы убедится, что это сделано сейчас, а не во времена моей далёкой молодости. Убедился, удивился.
COKPOWEHEU Автор
17.02.2025 11:50Что, недостаточно апокалиптично? Вот такая, наверное, покрасивее будет: https://habrastorage.org/r/w1560/webt/tq/q2/2b/tqq22bjmf-yx77utxwt-v0ia8u4.jpeg
sim2q
17.02.2025 11:50Неужели резцом?:)
Когда то помню старшие товарищи затачивали полотно от ножовки крючком под определённым углом. Самому повторить так не удавалось, что бы резало также хорошо.
AKudinov
17.02.2025 11:50Сурово как. Посадочное место под МК тоже руками вырезали? Респект!
COKPOWEHEU Автор
17.02.2025 11:50А как же. Ради интереса решил попробовать сделать плату максимально подручными средствами, даже без принтера. Даже записал процесс этого мракобесия: https://www.youtube.com/watch?v=tPAHEwi4Fzg&list=PLc7FYD_FgfqcgaWyrxhSr8cy2q23xCY3Q&index=14
isden
17.02.2025 11:50Мне как-то доводилось делать не очень сложную плату с парой 14 ногих микрух с помощью шила и железной линейки =)
evgeny_72
17.02.2025 11:50Нвидиа вздрогнула:)) я одину плату с мин обвязкой взял, и чувствую что надо более глобальное сделать. Нормальный проект.
COKPOWEHEU Автор
17.02.2025 11:50Видеокарта на 256 ядрах вг015. Суровая российская видеокарта с ручками для переноски.
Vytian
17.02.2025 11:50Зачем ручки, куда ее из бункера вывозить, кто позволит?
А если серьезно, присоединяюсь к просьбам насчет АЦП. Причем сразу и дифференциально.
ahdenchik
17.02.2025 11:50Отсутствие таблицы прерываний. Отсутствие бутлоадера.
Меньше аппаратуры - меньше errata. Не забывайте что с этим контроллером россияне будут жить лет 30-50
(Вообще, мне лично кажется странным когда производители пытаются напихать аппаратную поддержку в те места, которые "без штрафа" реализуемы программно)Поддерживается прошивка обычными JTAG-программаторами (это-то достоинство), но все же нужен пропатченный openocd.
Такой "патч" нужен любым микросхемам, поддерживаемым openocd: это патч к конфигу, которым краёвая конфигурация задаётся. Со временем он попадёт в ~master
Целых семь ног отвели под какую-то ерунду — AT_IN, WKUP, плюс еще две под USB. Сами-то функции, может, и могут где пригодиться, но их стоило совместить с GPIO.
Видимо, корпус выбран по каким-то другим соображениям и недостатка в ногах не было
Disasm
17.02.2025 11:50Под контроллеры же обычно позиционно-независимый код не пишут, и все наши обращения к переменным из Си будут развернуты в тот же la, что сводит смысл от страдания со стартапом на нет.
Есть как минимум два сценария, когда нужен абсолютный адрес, а не относительный:
флеш может располагаться по адресу 0x0800_0000, но выполнение кода происходить по адресу 0. Можно конечно с помощью ld-скрипта разместить код тоже по адресу 0, но тогда прошивка чипа может перестать работать
в чипе могут быть регионы кэшируемой и не кэшируемой памяти, и выполнение может начинаться с не кэшируемой памяти, а потом переходить в кэшируемую в стартапе. До тех пор, пока адрес выполняемой инструкции не будет 100% известен, пользоваться la опасно.
Помимо всего этого когда вы запускаете прошивку под дебаггером, он может начать её выполнять с "правильного" адреса, а потом после ресета микроконтроллер начнёт выполнять её с того, который ему кажется правильным. В общем, загрузка абсолютного адреса позволяет минимизировать проблемы, связанные с особенностями конкретного МК, потому что она работает всегда одинаково.
COKPOWEHEU Автор
17.02.2025 11:50Во всех этих случаях заботиться о позиционно-независимом коде приходится самому программисту. А речь-то шла о том, что компилятор gcc по умолчанию будет генерировать обычный, позиционно-зависимый код.
И, на самом деле, это проблема: я-то надеялся написать бутлоадер, который бы располагался в начале флеша, а юзерский код записывал где-нибудь дальше. И если бы прошивка получалась позиционно-независимой, проблемы бы не было: ну стартует он не с 0x8000'0000, а с 0x8001`0000 - не страшно, переходы-то относительные. Но вот обращение к ОЗУ из-за la поломается. Поэтому придется либо вкручивать флаги компилятору (пока не знаю с какими побочными эффектами), либо править ld-скрипт. А раз так, то и возня с позиционно-независимым загрузчиком не особо полезна.
А самое обидное, что я так и не нашел способа передать в li адрес метки, компилятор ругается и требует la.Disasm
17.02.2025 11:50Я пока тут не вижу никакого позиционно-независимого кода, вижу только обычный позиционно-зависимый. Тот факт, что код может выполняться из других адресов -- проблема исключительно стартап-кода, он должен сделать так, чтобы остальной код ничего не заметил.
Проблема с li, насколько я понимаю, в том, что компилятор не может её сразу скомпилировать если он не знает адрес метки. А адрес метки неизвестен до линковки. В зависимости от значения адреса нужно сгенерировать или одну инструкцию, или две, поэтому на этапе компиляции просто выдаётся ошибка. Если всё же очень хочется, приходится выписывать вручную li как две инструкции (lui+addi), тогда всё будет ок, но addi в итоге может оказаться лишней.
COKPOWEHEU Автор
17.02.2025 11:50Еще раз. Любое обращение к памяти из юзерского кода на Си. Оно разворачивается в auipc, а не в lui. Если не предпринимать дополнительных мер. И с этой проблемой стартап-код никак не поможет, будь он хоть трижды позиционно-независимым.
Disasm
17.02.2025 11:50Вероятно у нас какие-то очень разные компиляторы или параметры компиляции, потому что у меня разворачивается в lui:
int C = 5; int foo(int a, int b) { return a + b + C; }
0000000000010244 <foo>: 10244: 67c5 lui a5,0x11 10246: 2507a783 lw a5,592(a5) # 11250 <C> 1024a: 9d2d addw a0,a0,a1 1024c: 9d3d addw a0,a0,a5 1024e: 8082 ret
Но даже безотносительно этого, если у вас доступ к памяти через auipc, стартап-код как раз может обеспечить корректность выполняемого кода, передав на него управление по правильному адресу. По тому, который ожидает линкер во время линковки.
COKPOWEHEU Автор
17.02.2025 11:50int C = 5; int foo(int a, int b) { return a + b + C; 202: 952e add a0,a0,a1 204: 20000797 auipc a5,0x20000 208: dfc7a783 lw a5,-516(a5) # 20000000 <C> } 20c: 953e add a0,a0,a5 20e: 8082 ret
Похоже, дело во флаге
-mcmodel
. У меня стоялmedany
, а у вас, вероятно,medlow
. По крайней мере, я сейчас его поменял и ваше lui получилось. Так вот зачем этот флаг нужен. Спасибо что пнули в нужном направлении.
Что забавно, в документации позиционно-независимым назван как раз medany:The code generated by the medium-any code model is position-independent, but is not guaranteed to function correctly when linked into position-independent executables or libraries.
если у вас доступ к памяти через auipc, стартап-код как раз может обеспечить корректность выполняемого кода, передав на него управление по правильному адресу.
Если в ld-скрипте адрес начала прошивки указан 0x8000'0000, в реальности ее располагают в 0x8001'0000, а для доступа к оперативке используется auipc, стартап никак не может на это повлиять.
Другое дело, что если mcmodel действительно позволяет отвязать адреса оперативки от адресов флеша и генерировать позиционно-независимый код (надо будет еще проверить ссылки на функции, таблицы переходов и т.п.), то со стартапом заморачиваться уже стоит.
kompilainenn2
Первые впечатления, что судя по маркировке, он Ленина живым видел
COKPOWEHEU Автор
Если во времена Ленина выпускались РИСК-5 (ну не на иностранном же языке маркировать!) микросхемы с мегабайтом ЭСППЗУ... А вообще, это скорее последствия отмывки или неудачно выставленного света.
NekitGeek
Может он про логотип и стандартное обозначение? Видел похожий логотип на советских микросхемах от спектрума.
kompilainenn2
Может, я про первые 4 цифры на самом деле, а вовсе не про качество печати или самого чипа. Хабр в юмор не научится никогда
vladkorotnev
Тогда уж МУНИ-5 (Микропроцессор с Упрощённым Набором Инструкций) :-)
peacemakerv
Не микропроцессор, а контроллер :)
COKPOWEHEU Автор
однокристальная микро-ЭВМ!
peacemakerv
Нифига вы в аббревиатурах не понимаете :)
torgeek
Если смотреть словарь Ершова, то это микропроцессор. И далее по роли — периферийный или центральный, в зависимости от применения и выполняемым функциям.
vladkorotnev
Я сначала так и написал, но вышло слишком по Фрейду :-)
torgeek
Главное не путать редукцию и упрощение — в RISC системах команд нет упрощения, там редукция.
Hlad
Так то существует ГОСТ, который говорит, как должны называться микросхемы. И как правило, отечественные микросхемы имеют два названия: для сертификационных документов и нормальное. Например,К1986ВК025 и MDR1206FI.
kompilainenn2
Которого года сей ГОСТ? Ну и емнип, ГОСТы, которые не оказывают влияние на здоровье и жизнь людей не обязательны к применению
Hlad
Так никто не заставляет эти ГОСТы применять - разрабатывайте микросхемы на свои собственные деньги, и продавайте на свободном рынке, никто слова не скажет. Но если хочется присосаться к золотому пенису госфинансирования - будьте добры называть микросхему в соответствии с действующими стандартами.
checkpoint
Вы уверены что он золотой ? ИМХО обычный, кожаный. ;)