ATmega ASM vs C (продолжение холивара)

Я постоянно сталкиваюсь с мнением, что со мной что-то не так. Ведь я пишу на ассемблере для 8бит микроконтроллеров. Все поголовно твердят одно и тоже, что ассемблер очень не практичен, так как на нем сложно писать, что это не оправданно дорого и долго по сравнению с Си.

Но это все какие-то детские байки. И дальше я приведу пример, ради которого и пилю этот пост.

Пожалуй самый реальный аргумент - это сложность найти специалиста для поддержки проекта. Си программистов огромное количество, чего нельзя сказать о асм программистах.

Но позвольте, мы говорим о микроконтроллерах(тем более 8бит), в этой сфере даже Си программист должен знать периферию и уметь отлаживать код, что достаточно сложно сделать на зная ассемблера. Это Вам не UI формы рисовать, здесь совсем другой кодинг. Здесь по большему счету нет серьезного взаимодействия с пользователем. В основном это работа с железом и передача данных по бинарным протоколам. И очень много низкоуровнего программирования, к примеру часто приходится работать с таймингами на милли, микро и нано секундами, часто нужно работать с бинарной логикой и экономить каждый байт как в RAM, так и во Flash и EEPROM. Здесь нет серьезной математики, а иногда нет даже целочисленного деления и умножения. Потому что если Вам нужна серьезная математика, то Вы попросту выбрали не тот чип, и очень большая вероятность, что Вам нужен не микроконтроллер, а чипсет типа Mediatek. Даже процедуры выделения памяти и те слабо востребованы.
Так в чем преимущество Си в проектах где не нужна математика, выделение памяти, указатели, но нужен подсчет тактов и жесткая экономия ресурсов?
А также не забываем, что исходя из начальных условий Вам вряд ли будут полезны стандартные Си библиотеки, типа работы с UART(об этом далее)

Хотя в моей ОС на ассемблере есть работа с памятью, есть драйвера UART, есть математика и многое другое.

Ну а теперь пример:

Конкретно я пишу прошивки на ассемблере чаще всего для МК ATMega88/168/328. Хотя ядро может поддерживать практически всю линейку ATmega и некоторые ATTiny.
Я создаю прошивки для своих IOT устройств которые действительно умные. Например эти устройства умеют общаться друг с другом на одной шине RS485 без ведущего. Умеют сообщать показания датчиков остальным устройствам, умеют на базе таких сообщений управлять силовой частью, хранят историю, шлют события, поддерживают интеллектуальный ввод, имеют множество программных настроек и прочее, прочее, прочее.
Чтобы этого добиться мне потребовалась реализация конечных автоматов, которые потом были переписаны в ОС реального времени. Я создал свой протокол, который требует точного подсчета тактов(на Си этого не сделаешь). Я наработал кучу драйверов, которые выполняют ряд функционала отсутствующего в широко распространенных библиотеках Си. Например есть поддержка программного UART и различных других интерфейсов, которые работают совместно друг с другом и даже с несколькими инстансами. И это тоже вопрос ресурсов, который на данных железках будет очень сложно решить возможностями Си. У меня реализовано очень много кода, свой бутлоадер в конце концов. И весь этот объем удается запихать в ATMega88/168 только благодаря тому, что он реализован на ассемблере. Такой функционал с реализацией на Си поместиться только в монстрах типа STM32.

Вот так выглядит мой протокол:
; addr size code data0 dataN crc
; |eaaaaaaa|rrssssss|qucccccc|dddddddd|...|dddddddd|wwwwwwww|
; где:
; e - бит extrascan, если включен, то пакет состоит из 2 байт(addr+crc)(если а=0 - режим таймингов)
; a - адрес ведомого устройства (1-127, 0-новое или ведущее устройство)
; r - зарезервированный
; s - размер всего пакета(40B максимум, длина данных = s-4)
; q - бит 0-запрос, 1-ответ
; с - код функции или ответа
; u - признак адресации по UID (значение a игнорируется)
; d - данные функции (при включенном u, первые 8 байт = UID)
; w - crc8(1wire)

При этом все устройства умеют передавать большие объемы данных, например шить новую прошивку в 16 килобайт. Умеют определять магическое слово по UART, после чего используется временное окно в несколько миллисекунд в котором все устройства сообщают есть ли у них свежие данные. И здесь крайне важен корректный подсчет тактов.


Ниже задача которая логирует символ.
Здесь подсчитан каждый такт. Как это сделать на Си? Использовать asm вставку? А где ее не использовать? - там где вы пишете ровно тот-же код но в виде Си синтаксиса? А зачем Вам Си синтаксис, когда Вы все равно пишете низкоуровневый код? Вам просто нравится быть зависимым от компилятора и забивать себе голову его правилами кодинга?

;--------------------------------------------------------
C5_OUT_CHAR:
;--------------------------------------------------------
;Логирование символа
;IN: TEMP-байт
;--------------------------------------------------------
    PUSH_Z
    PUSH ACCUM
    PUSH LOOP_CNTR
    PUSH TEMP
    PUSH FLAGS

    LDI_Z (PORTS_TABLE*2+((LOGGING_PORT>>4)*0x03))
    LPM ZL,Z
    CLR ZH

    LD ACCUM,Z
    ORI ACCUM,(EXP2 (LOGGING_PORT & 0x0f))
    ST Z,ACCUM
    LDI ACCUM,0x14;0x08
    DEC ACCUM
    BRNE PC-0x01

    LDS FLAGS,SREG
    CLI
    LD ACCUM,Z
    ANDI ACCUM,~(EXP2 (LOGGING_PORT & 0x0f))
    ST Z,ACCUM
    LDI ACCUM,0x14;0x08
    DEC ACCUM
    BRNE PC-0x01

    ;DATA BITS
    LDI LOOP_CNTR,0x08
_C5_OUT_PROC__BITES_LOOP:

    LD ACCUM,Z
    SBRC TEMP,0x00
    ORI ACCUM,(EXP2 (LOGGING_PORT & 0x0f))
    SBRS TEMP,0x00
    ANDI ACCUM,~(EXP2 (LOGGING_PORT & 0x0f))
    LSR TEMP
    ST Z,ACCUM

    NOP
    LDI ACCUM,0x13;0x07
    DEC ACCUM
    BRNE PC-0x01
    DEC LOOP_CNTR
    BRNE _C5_OUT_PROC__BITES_LOOP
    ;STOP
    LD ACCUM,Z
    ORI ACCUM,(EXP2 (LOGGING_PORT & 0x0f))
    ST Z,ACCUM

    STS SREG,FLAGS
    POP FLAGS
    POP TEMP
    POP LOOP_CNTR
    POP ACCUM
    POP_Z
    RET

И еще, не стоит забывать, про багфиксинг. На Си Вы оперируете сущностями такими как, функции работы с памятью, указатели, сложный синтаксис, огромное количество примитивов, не читабельный код с большим количеством условностей которые обязательно нужно знать(как например приоритет операции). Все это вызывает огромное количество багов. На которые Си разработчики тратят огромное количество ресурсов и именно за отличное знание всех этих сущностей Си разработчики просят много денег. А весь юмор в том, что на ассемблере эти сущности либо отсутствуют, либо выглядят гораздо проще, Вы загружаете мозг уже не Си сущностями, а элементарными алгоритмами и прямой работе с периферией. Алгоритмы кстати как и в Си, можно вынести в виде библиотек.

И да. Как такой проект поддерживать? Да все очень просто, просто Вам нужен настоящий программист, который работает с алгоритмами и не с заученными шаблонами играясь в кубики лего. В рамках такого проекта ему будет плевать Си это Ассемблер или Си++ с Джавой.
Конечно вопрос - зачем такой проект нужен? Можно же взять ардуинщика набрать STM32(они еще продаются? дешево?) и пускай себе кодит как мартышка. Ну и какой проект мы получим на выходе?
А получим мы на выходе современное качество IT проектов, такое качество, при котором все постоянно глючит, много весит и много стоит. Нам точно нужно все это в автоматизации?

Я плохо отношусь к паразитам, простите меня.

Насколько сложно писать на ассемблере?
Ведь давно уже известно, что на ассемблере никто не пишет.
Совершенствуйся, ведь именно для тебя были придуманы Си, Джава Скрипт и ПХП, более того посмотри в сторону Dart - это же совершенство. Зачем тебе язык для умственно отсталых?

Давайте начну с хеллоу верд.
Конкретно код для включения светодиода(с использованием моего ядра) выглядет так:

LDI ACCUM,PA0
MCALL PORT_SET_HI
Но перед этим порт нужно перевести в режим вывода:
LDI ACCUM,PA0
MCALL PORT_MODE_OUT

Т.е. оба блока можно написать как:
LDI ACCUM,PA0
MCALL PORT_MODE_OUT
MCALL PORT_SET_HI

Сложно? Здесь стоит объяснить кто такой аккум, да все просто:
.DEF ACCUM=r24
Т.е. регистру r24 дано имя 'ACCUM' - подразумевающее, что это регистр общего назначения для хранения временных данных.
Если посмотрим в заголовок библиотеки port_set_hi.inc, то увидим:
;--------------------------------------------------------
PORT_SET_HI:
;--------------------------------------------------------
;Устанвливаем порту высокий уровень
;IN: ACCUM-порт
;--------------------------------------------------------
Потяно ведь кто такой аккум и для чего он в данной процедуре?

Ну а теперь пример сложнее. Как вызвать драйвер и получить темпрературу с датчика DS18B20?
LDI TEMP,PID_DS18B20_DRV
MCALL C5_EXEC
Оно само сделает все что нужно. Даже в услуовиях многопоточности.
Это действительно сложно?
Ребят, это проще бейсика. И гораздо проще любого Си.
Это элементарный пример использования библиотек как и в Си. т.е типа:
.include "./core/drivers/1wire_s.inc"
.include "./core/drivers/ds18b20.inc"
.include "./io/port_mode_out.inc"
.include "./io/port_set_hi.inc"
.include "./io/port_set_lo.inc"

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

Это для вас сложно? А мне вот сложно соответствовать вашим идиотским пропиареным стандартам, которыйе каждый месяц меняются.

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

Почему я изобретаю свои велосипеды.

Вот один из явных примеров.

Те, кто пишет или писал на ассемблере для микроконтроллеров Atmel скорее всего знают утилиту avra - это ассемблер для AVR(собирает прошивку из исходного assembler кода).

Есть конечно Atmel Studio, в которой сборщик от производителя, но Atmel Studio основана на Microsoft Visual Studio и более-менее стабильно работает только под Windows и по большему счету никаких преимуществ не имеет(если конечно у вас нет оборудования для дебага непосредственно МК).

Поэтому, по большому счету мне достаточно GNU Linux, Geany, avra и avrdude.
Поэтому, при реализации своей операционной системы для AVR я часто пользовался avra.

Но с недавних пор avra стала сбоить.
Похоже мало кто сбирает прошивки в 7500 ассемблеровских мнемоник и поэтому остальных эта беда не коснулась.

В итоге, какие варианты у меня есть:

Отказаться от GNU Linux и работать под Windows на Atmel Studio
И это пожалуй наихудший вариант для меня по ряду причин.

Написать автору с просьбой решить проблему
Идеальное решение, но вот уже прошло 10 дней и мое сообщение даже никто не прочитал. Сколько потребуется времени, чтобы автор пофиксил багу?

Изучить сишный исходный код проекта avra, подготовить инструментарий для отладки, сборки, тестирования и выяснить в чем дело сделать багфикс
Это, казалось бы самый реальный и верный вариант, но есть но:
1) Нахрапом найти багу не получилось, а значит нужно изучать проект в деталях, дебажить и тестировать. Для Си это достаточно трудоемкий процесс.
2) В проекте, как оказалось, есть и другие ошибки, менее критичные, но тем не менее видно, что авторы проект не довели до релиза. Например у них до сих пор наблюдаются проблемы с директивами .ifdef и .ifndef. Мне тоже это фиксить?
3) 10 дней сообщение об ошибке не прочитано. А запрос на добавление фикса через какое время будет рассмотрен? Возможно через год. Ведь авторы никому ничем не обязаны. Нужно как минимум сказать спасибо за то, что они сделали. Спасибо!
4) Ну и главное - это все требует времени, это время можно потратить по другому, а именно:

Написать свое решение на языке более высокого уровня
И я выбрал данный вариант, причины:
1) Мне нужно понимание как работает проект, так как хочу похожее написать на асме для AVR для своей операционной системы.
А анализ чужих кодов и реализация своего решения на более удобном и быстром языке - лучший способ для этого.
2) Время, грубо говоря я потратил на свою реализацию столько же времени, сколько бы потратил на багфиксинг чужого проекта на Си.



Теперь у меня есть свой проект ассемблера для AVR написанны на Java - https://github.com/w5277c/javra (пока еще тестирую).

Зачастую так бывает, что чтобы найти сбой в чужом проекте нужно потратить приблизительно столько-же времени, сколько для реализации своего проекта. А если учесть, что зачастую нужен не весь функционал?
Надежность?  Да бросьте, я пишу свое решение у которого как минимум на одну серьезную багу меньше, а если еще учесть, что высокоуровневый язык программирования сам по себе не допускает ряд ошибок, которые встречаются в Си?


Вот так я и создаю велосипеды, всего-лишь надо несколько условий:
1) Решение проблемы занимает больше времени чем своя реализация.
2) Решение проблемы своими силами(поддержка чужого проекта) требует практически столько же ресурсов что и реализация своего решения.
3) Изначальное решение реализовано на языке требующем от программиста значительно больших трудозатрат, в то время как мое решение пишется легко и непринужденно.
А главное, свое - есть свое, я независим от других.

Update. Я вот тут задумался, а ведь в avrdude есть глюк из-за которого я не могу пользоваться usbasp для новых МК... Что такое реализовать свой avrdude без вот этого всего для бешеной собаки? Ведь он мне тоже понадобится для своей ос? А еще я краем глаза глянул на реализации Java для AVR... но на это нет времени.

(no subject)

"Все умные лампы и розетки «Сбер» вышли из строя из-за санкций. 🤔

Умные лампы, светодиодные ленты, реле и розетки «Сбер» сняты с продажи, уже проданные устройства больше не работают.

Этими устройствами можно управлять по сети Wi-Fi голосом или через тач-интерфейс с помощью смартфона с приложением «Сбер Салют», а также через мультимедийный дисплей SberPortal и ТВ-приставку SberBox.

Однако, их теперь нельзя подключить.😅

☝🏻Как оказалось корпорация с многомиллионными бюджетами решила сэкономить на своих пользователях и передала всю бэкенд-инфраструктуру под управление сторонней корпорации.

Выяснилось, что умные гаджеты используют платформу Tuya. Данный сервис, из-за санкций, сейчас блокирует все новые подключения по идентификатору, который есть у каждого устройства «Сбер».

Даже VPN в данном случае не поможет.

Проблема существует еще с 14 апреля. «Сбер» настаивает, что это временная проблема. 😊
На начало мая проблема продолжает быть актуальной."

Взято из просторов интернета.


Вот отрывок из моего самого первого поста 17-го года.
"3)Решение должно иметь возможность управляться локально и с нескольких клиентов одновременно.
Пользователь должен быть уверен, что если я завтра все брошу и выключу сервер, то их железо не превратится в тыкву.
Кстати, да, такие решения как у Ксиаоми - очень хорошо, но Великий Китайский Фаервол сильнее.
Он еще не закрыл Вам доступ к единственному облачному решению находящемся в Китае?"

Я в течении всего этого времени несколько раз обращал внимание на тот факт, что ваше дорогостоящее оборудование от крупных брендов может легко превратиться в тыкву.

Ничего не меняется. Крупные компании продолжают нас стричь, а я имею 'интересный' проект без необходимой поддержки.

Переход с 8бит к 16бит, наc уже тогда поимели?

Давайте обратим внимание что такое 8 бит для 8 битных процессоров.
По сути это обработка процессором команды за минимально возможное количество тактов между двумя регистрами, чья разрядность обычно заявлена в процессоре.
Например Z80 был частично 8 битным процессором, и при этом частично 16 битным процессором(ведь у него были 16 битные регистры типа IX,IY)

Но на этом не все. По большему счету не так важен размер регистра процессора, как его интерфейсы взаимодействия с остальными устройствами.
Напомню, что даже сейчас(в пору 64 битных процессоров), чаще всего последовательные и даже почти мертвые параллельные интерфейсы являются 8 битными.
Припомню до сих пор широко используемый UART, он до сих пор остался в основном 8 битным. I2C(или TWI) также ориентирован на 8 бит.
А Вам знакомо слово 'октет'? Оно означает порцию данных в 8 бит. Да, т.е. байт это совсем не обязательно 8 бит, он может и должен быть 16 битным в 16 битных системах.

Давайте обратим внимание на кодировки символов. Да, мы знаем, что 8 битами не возможно описать все символы всех алфавитов. Поэтому у нас есть UTF8 и UTF16(Java между прочим работает с UTF16). Т.е. используя 16 бит и принимая байт 16 битным мы тут-же на всех уровнях кодинга избавляемся от проблем с кодировками прямиком на уровне процессора. Да и почему тот-же UART c TWI не сделать 16 битным?
И так буквально во всем. Нас оставили в мире 8-битного байта. На палочках в школе в каком классе перестают считать?

P.S. Может быть я не достаточно полно выразился... Вся периферия 16 битного процессора также может быть 16 битной. Т.е. на всех уровнях минимальной единицей информации после бита следует байт(16 битный байт)

Современная жесть

Мы же вроде уже договорились, да? Что здесь я выражаю свою истинную позицию, без этих всех масок, которые нам позволяют жить в нашем обществе?

Я не принимаю, и не поддерживаю наше развитие ИТ в течении уже десятилетий.

Я имел опыт работы с программами работающих на 3.5 МГц 8 бит процессоре с 64 Кбайт ОЗУ подключенным к магнитофону и телевизору. Я имел опыт работы с программами на более популярных Intel 80286/80386 процессорах.
Я помогал бухгалтерии с отчетностью реализованной в DOS программе. Которая не нуждалась практически ни в чем кроме ручной поддержки матричного принтера.
И я прекрасно понимаю, что практически все программы, которыми пользуются современные пользователи, могут быть основаны даже на Z80(конечно с использованием дополнительных устройств). Нам не нужны гигагерцы, потребность в гигагерцах обусловлена только зарубежным рынком который живет за счет потребления.
Да, где-то нужны мощные видео процессоры для распаковки HD видео. Но с каких пор для русского человека качество картинки стало значительно важнее сюжета? Дайте мне хорошую игру типа Sierra Shivers и графика для мена будет не важна. А вот говно должно быть в красивой обертке, иначе не съесть. Что насчет 'Hellblade: Senua's Sacrifice'? Там главное графика или реальные переживания? Для чего так старались разработчики?

Я лично буду рад, если мы вернемся на несколько десятков лет назад. Потому что текущее развитие направлено на потребление, как будто речь о тараканах. И это однозначно не путь Русского человека.

Многое можно сделать на старых платформах, если вы не таракан конечно. Особенно, если применить Русскую смекалку.

Современный UI

Как и прежде, я ухожуК.
Превращаю этот аккаунт в оффтоп, здесь будет моя не официальная, темная сторона.

Сегодня я хочу поделиться своей болью по поводу современных графических интерфейсов ориентированных для пользователей(GUI).

Я не будут их классифицировать и разбираться в их корректных названиях, просто вывалю список известных названий:
Swing, AWT, JFX, Android, QT, WinForms и многие другие, названия которых я не вспомнил с ходу.

Плюс конечно огроменное количество WEB фреймворков, которые позволяют на базе разных языков создавать формы для браузеров.

Ну и большое разнообразие мобильных GUI тоже не упустим.

Это просто блядский зоопарк, особенно WEB. И это развивающийся блядский зоопарк современные ИТшнеги называют прогрессом.

На мой взгляд это явный регресс. И регресс настолько мощный, что я после эннадцать попыток взять хоть что-то на вооружение всегда сталкивался с серьезными проблемами. Это касается и любомой мной JFX.

Я могу предположить, что я умственно отсталый и не понимаю всю глубину глубин мирового сообщества.
Но лично мне, как предпологаемо умственно отсталому видится, что можно достаточно легко разработать компонентное решение, которое сможет рисовать элементы UI в консолях, вебах, десктопах, калькуляторах, на ZX Spectrum'ах и т.п.
Ведь мне, как пользователю, самое главное - нужно понимать интерфейс на все 100%. А это уже больше имеет отношение не к дизайну картинок, а к дизайну логики интерфейса, где не важно чем представлены элементы UI - картинками или ASCII символами.

И ведь, по сути, почему нет? Мы можем создать ряд функционала GUI серверов, работающих с общими примитивами UI. На базе коммуникации по сети(тот-же TCP). Отдельные реализации серверов обеспечивают решение для WEB, или Desktop, или Mobile(Android, IOS и прочее)
Где-то функционал будет ограничен, а скорее не функционал  а динамическая графика(она Вам действительно нужна в консоле?)

ПОЧЕМУ этого до сих пор нет? ЭТО ВЕДЬ ПРИМИТИВНЫЙ ФУНКЦИОНАЛ!!!

Я настолько устал от этого мирового говнища, что прихожу к единственному решению - нужно пилить этот велосипед самому.

Спасибо.