Warning: Undefined array key 0 in /var/www/tgoop/function.php on line 65

Warning: Trying to access array offset on value of type null in /var/www/tgoop/function.php on line 65
- Telegram Web
Telegram Web
Об рынок софтвера

Наблюдать за рынком ПО необычайно интересно. Сначала софт писали в НИИ и на предприятиях под заказ, и распространяли промеж своих контактов.

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

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

Так продолжалось до середины нулевых, после чего продажи сломались, всем надоели коробки. Теперь, чтобы продавать софт, нужно было понять, кто твой клиент, собрать коробку под него, и целенаправленно долбиться в ЛПР.

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

Так продолжалось до начала десятых, после чего продажи сломались, всем надоело "развивать клиента". Теперь, чтобы продавать софт, надо было отыгрывать миллионы гипотез о полезных функциях софта, а зацепившись об позитивный отклик, строить софт вокруг этой функции (разумеется, онлайн).

Так продолжалось до конца десятых, после чего продажи сломались, всем надоел lean startup, бесконечное участие в роли подопытного в а/б тестах. Теперь, чтобы продавать софт, нужно [ВЫ НАХОДИТЕСЬ ЗДЕСЬ].

Что дальше сломается, и как это исправить, мы узнаем лет через пять.
Об Аду снова

Продолжим серию? В прошлый раз мы с вами освоили азы, как настроить инструменты и скомпилировать простейший "хелловорлд". На компьютере должны были появиться Alire c нативным тулкитом и VS Code с настроенными для Ады плагинами. Всё это нам понадобится.
 
Сегодня мы пойдем в embedded и попробуем скомпилировать Аду для baremetal платы на базе STM32, на мой взгляд, именно тут Ада сильна.
 
Что нам для этого нам понадобится, я напишу ниже.
 
* Нужно раздобыть плату STM32. Я буду работать с STM32 DISCOVERY на базе камня F407 с частотой 168MHz, чего и вам рекомендую, хотя и не заставляю. На плате распаяно много чего, но нам интересно, что на ней на самом деле стоит 2 чипа  STM32, второй при этом прикидывается программатором ST-LINK, flash-диском, а также USB-2-Serial конвертором и еще много чем. Это СИЛЬНО упрощает знакомство с темой, усложнить всегда успеется.
* Провод x-2-minuUSB (!) - это тот конец, который соединяется с программатором.
* Нужно внимательно почитать т.н. GNAT Supplement for Cross platform крайней версии, раздел Bareboards: https://docs.adacore.com/live/wave/gnat_ugx/pdf/gnat_ugx/gnat_ugx.pdf
* Нужно установить софт-отладчик OpenOCD, это замена проприетарных тулов для работы с ST-LINK. Я ставил через brew, у меня всё получилось. Вот вроде бы и всё, можно работать.
 
Пусть наш новый проект называется "disco1".
 
1. Итак, первым шагом надо научить GNAT компилировать под ARM. Для этого надо запустить alr вот таким образом: alr toolchain --select, и в списке выбрать что-то типа "6. gnat_arm_elf=12.2.1". GPRBuild оставляем самым свежим.
 
2. Далее нужно выполнить alr init --bin disco1, после чего перейти в свежую папку disco1. Alire сгенерировал нам новый проект, спасибо ему. Но он пока не знает, что мы хотим компилировать под ARM на голом железе, надо его научить. Нужно открыть файл disco1.gpr и добавить туда такие строки (про целевую архитектуру и рантайм):
for Target use "arm-eabi";
for Runtime ("Ada") use "light-tasking-stm32f4";

 
3. Alire сгенерировал нам пустой проект. Откроем основной файл disco1.adb и заменим текст на такой вот незамысловатый привет:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
procedure Disco1 is
begin
   loop
      Put_Line ("Hello");
      delay until Clock + Milliseconds (1000);
   end loop;
end Disco1;
 
Закроем файл и запустим alr build. Немного пошуршав, он оставит нам в папке bin elf-файлик. Теперь нам нужно получить из него прошивку.
 
4. Воспользуемся инструментами, которые принес нам Alire, и дадим такую команду:
alr -v exec  -- arm-eabi-objcopy -O binary --strip-all bin/disco1 bin/firmware
В папке bin появится файл firmware, который хоть сейчас шей! Было бы куда..
 
5. Достаем плату и подключаем её к USB, компьютер должен её опознать. Как именно это делать, посмотрите в вашей ОС, что-то типа lsusb или IOReg, факт в том, что нужно увидеть что-то похожее на STMicroelectronics, подключенное к компьютеру -- это победа
 
6. Если всё сделано правильно, у вас в системе появится флеш-диск с названием ST_F407 или что-то похожее. Там не должно быть файлов с именем Fail. Если всё ок, то нужно просто скопировать на этот "диск" файл прошивки firmware, полученный на 4-м шаге. Программатор увидит это, прошьет его в процессор, и перезапустит, флеш-диск перемонтируется и прошивка с него пропадет. Рекомендую переткнуть провод USB на этом моменте.
 
7. Теперь подключимся к программе. Надо выполнить: openocd -f board/stm32f4discovery.cfg -c "init; arm semihosting enable"
Тут обратите внимание на 2 важные вещи:
• OpenOCD знает про плату DISCOVERY, что упрощает жизнь еще немного
• После инициализации надо выполнить команду запуска semihosting; это хитрые регистры процессора STM32, которые позволяют обмениваться с программой данными без того, чтобы настраивать UART или другую периферию. В чем плюс? Наш рантайм Ады заворачивает стандартный ввод-вывод на эти регистры, а OpenOCD умеет их читать.
Извращенцы могут подсоединиться gdb на порт 3333 для удаленной отладки, а мы не будем, а просто понаблюдаем окно. Если всё сделано правильно, то лампочки замигают, а мы увидим, что каждую секунду туда валится текст Hello:
 
Info : Listening on port 3333 for gdb connections
semihosting is enabled
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : device id = 0x100f6413
Info : flash size = 1024 kbytes
Info : flash size = 512 bytes
Hello
Hello
Hello
Hello
Hello
Hello
Hello
..
 
Поздравляю, у вас всё получилось. Если нет, пишите в комментарии, будем разбираться.
 
Ниже я положу архив с более продвинутой программой, в ней будет 2 параллельно работающих задачи, одна будет просыпаться и выводить текст, а вторая - модифицировать данные для этого текста. Обратите внимание, как просто написать на Аде многопоточную программу с честным планировщиком задач для голого микроконтроллера, не задумываясь о RTOS и прочих таких вещах.
Об Аду на контроллере и загрузку в память
 
Кто-то, проделав упражнения из предыдущего поста, мог втянуться в разработку и отладку. И первое, с чем вы столкнетесь при отладке - с тем, что после пересборки прошивки необходимо еще записать её на flash. Но, во-первых, с ростом размера прошивки это замедляется, во-вторых, flash изнашивается. На помощь приходит возможность ядра Cortex M4 исполнять код прямо из встроенной в чип static RAM (1). Особенность данного ядра в том, что адресное пространство SRAM находится не там же, где ROM, поэтому линковать программу надо по другому адресу.
 
Правда, при выключении платы программа пропадет, но во время отладки нас такое устраивает, главное, не сбрасывать питание. Кроме этого, процессор сам не сможет загрузиться, поэтому после пуска надо будет его тормозить, и загружать отладчиком в него программу.
 
ПРИЕМЛЕМО.
 
1. Итак, первое, что надо сделать, это собрать программу с поддержкой запуска из SRAM. Для этого достаточно передать ключ вот так:
 
alr build -XLOADER=RAM
 
Линкер выдаст предупреждение, что обнаружил секцию данных, которая содержит исполнимый код; игнорируем. А вот bin мы готовить не будем, грузить будем прямо из elf-файла, он уже содержит всю информацию о правильных адресах.
 
2. На борту у stm32-discovery 1Мб Flash и всего 192кб SRAM, из неё часть придется потратить под программу, поэтому нужно ещё и следить за оптимизацией кода, и за тем, чтобы не случилось переполнения памяти. Мы собираемся оптимизировать код, а также посмотреть, что там с запасом по памяти. Для этого надо немного доработать файл disco1.gpr следующим образом:
 
package Linker is
   for Default_Switches ("Ada") use (
      "-Wl,--gc-sections",
      "-Wl,--print-memory-usage");
end Linker;

 
Теперь, если собрать приложение командой выше, мы увидим следующий текст:
Memory region         Used Size  Region Size  %age Used
           flash:                  0 GB         1 MB         0.00%
          sram12:          25272 B       128 KB     19.28%
             ccm:                   0 GB        64 KB         0.00%

Обратите внимание, теперь мы не будем перетирать флэш каждый раз (flash used = 0)
 
3. Теперь запустим наш OpenOCD так же, как мы делали раньше, но сбросим и остановим процессор:
openocd -f board/stm32f4discovery.cfg -c "init; reset halt; arm semihosting enable;"
 
4. Как я и говорил, грузить будем дебаггером. Для этого в соседней консоли запустим вот какую команду.
alr exec -- arm-eabi-gdb bin/disco1 -ex 'target extended-remote localhost:3333' -ex 'load'
 
Отладчик загрузит прошивку, остановится на первой команде. В этой консоли надо набрать команду "cont", и переключиться на консоль OpenOCD. Если всё сделано верно, можно увидеть сообщения от исполняющейся программы, как и в предыдущей серии.
 
--
 
Итого, теперь при перекомпиляции и заливке flash-память мы не будем трогать, код будет работать из встроенной RAM кристалла. А когда понадобится опять подготовить прошивку для flash, нужно будет указать ключ -XLOADER=ROM или удалить его вовсе из строки.
 
(1) То, что исполнение из SRAM может быть медленнее, чем из Flash, удивительно для десктопа, но вполне нормально для некоторых чипов с эффективной подкачкой кода.
Об подсветку кода

Лично я использую монохромную подсветку кода (чёрное — тёмно-серое — серое на белом), но не в этом суть, а вот в чём — я нахожу даже самую тупую и простую подсветку полезной. Но не в том смысле, в котором вы подумали, а в обратном, вот в каком.

Сейчас будет заход издалека.

Мое мнение, что сложную прикладную задачу надо решать через построение базиса/API, при помощи которого в дальнейшем и выражается вся тело программы. Обычно этот базис называют “ядром” или “моделью предметной области/прикладной моделью”
В большинстве языков такой базис реализуют на основе функций/методов, а вовсе не операторов языка.

А в самых простых “расцвечивателях” используется именно раскраска ключевых слов. И в этом весь трюк.

Если такую подсветку конструкций языка сделать ярко выделяющейся в тексте, то градация яркости кода очень хорошо показывает, где именно разработчик не в том месте решил “срезать угол” и использовал слишком низкоуровневый код в виде ключевых слов языка, а не прикладную модель. В это месте код будет насыщен ключевыми словами, а цвет его будет "ярким"

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

А больше я подсветку ни для чего и не использую.
Об эти выходные

Говорят, что верблюд это скаковая лошадь, которую дизайнил комитет.
 
В языке Ада, точнее, в стандартной библиотеке, существует важная часть, которую дизайнят вот совсем комитетом - это embedded для bare bone boards. Ограниченные ресурсы разных платформ каждая по-своему отсекает те или иные воможности языка, где-то и строки в heap это перебор, а где-то -- исключения. Поэтому тот самый комитет для embedded постарался собрать общий знаменатель, который бы одинаково хорошо подходил под усредненные задачи. Этот знаменатель называется "профили", и он описывает, что можно, а что нельзя из языка использовать на данной платформе.
 
Раньше эти профили назывались креативно, например, zero-footprint, Ravenscar, Jorvik, с недавнего времени чуть более скучно: embedded, light, light-tasking, но всё равно комитет не может угадать с запросами для всех - одним нужно что-то типа turbopascal на микроконтроллере, другому -- полновесный рантайм с задачами (потоками). Собственно, потоки и коммуникация между ними это одна самых сложных задач в смысле жырности потребного рантайма.
 
Ну а там, где подходящего профиля нет, а реализовывать весь профиль неохота, приходится закатить рукава и писать с нуля каждый раз. Один из таких повторно пригодных легковесных рантаймов, но с поддержкой задач/потоков и целиком на Ada, начал писать Вадим https://github.com/godunko, а я взялся портировать её на доску STM32F4 DISCO, которая была под рукой, потому как она достаточно популярная.
 
Это был мой первый опыт работы с crates в Alire в таком объеме, поэтому времени потрачено было больше, чем нужно, однако всё завелось, светодиод (из примеров) замигал успешно. В целом могу сказать, что ARM Cortex-M и Ада прямо-таки созданы друг для друга. Минимальный рантайм, который инициализирует ядро и периферию + код с планировщиком, где одна задача зажигает диод, а вторая его гасит, занял в прошивке около 2кб.

В итоге я отправил пулл-реквесты, а Вадим их принял, так что в коллекцию добавилась поддержка DISCO. Код можно увидеть тут (это планировщик и те самые примеры) и тут (это рантайм + инициализации). Отдельно в Alire довелось отправить issue по обнаруженному расхождению в поведениях для удаленных и локальных репозиториев.
 
У самого Вадима основная плата это Cortex-M3, на ней он строит шестинога, подкрепляя обратную кинематику расчетами в Octave.
Об искусственный интеллект

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

По шагам я сначала удалил с телефона старую eSIM, а потом запросил ссылку на активацию новой, и её - тадам - оператор послал на номер этой eSIM, о чём мне и написал.

После недолгого выяснения оказалось, что инструкцию мне нагаллюцинировал и прислал ИИ чат-бот. Работает ли она? Ха-ха, конечно же нет

Спустя два дня переговоров с оператором и такой-то матери ссылку удалось исправить и переотправить.

Будующее такое яркое..
Please open Telegram to view this post
VIEW IN TELEGRAM
В какой-то момент, примерно с Windows 98 или ME, MS забросила приложение, вместо него предложив MS Schedule+, который шел в пакете с MS Office и даже мог импортировать старые карточки, правда, из-за измененного формата Unicode делал это неправильно. Правда, это приложение страдало от проблемы 2000 (на самом деле), и MS, зная о проблеме, не стали его переделывать, а забросили, в качестве альтернативы с 97 года продвигая использование контактной книги из MS Mail и Outlook (Express) с новыми крутыми вещами, типа поддержки лунных календарей и настройки автоматического уничтожения старых записей (YOUTHINKIMFUCKINGWITHYOU? IMNOTFUCKINGWITHYOU! https://microsoft.fandom.com/wiki/Microsoft_Outlook#Outlook_2002). Стоит ли уточнять, что альтернативой это можно назвать с огромной натяжкой? Так, мы лишились одной из программ, помогающей наладить и систематизировать нетворкинг, вместо него получив невротическую "контактную книгу". Кто в здравом уме и по своей воле заглядывает в контактную книгу Outlook?

Ладно, MS есть MS, от него ничего хорошего не жди. А что у Apple?
У Apple история еще интереснее. Понимая важность инструмента, Apple выпустили свой вариант под названием HyperCard, также бесплатно встраивая его в саму ОС. Однако, Apple шагнули еще дальше, и добавили к карточкам возможность привязать скрипты, элементы ввода кнопки, так что прямо в картотеке можно было организовать разнообразный мультимедиа-калейдоскоп. Кроме того, специальные карточки с преднаписанными скриптами, который могли быть добавлены в "ежедневник", оборудовали картотеку возможностью запрашивать данные из БД, читать устройства, расставлять сеть гиперссылок в карточках - этакое программирование без программирования. У "настоящих программистов" из Oracle настолько бомбануло, что они резко выпустили свой бесславный мультимедиа-аналог - Oracle Card - который спустя непродолжительное время был так же резко заброшен (https://en.wikipedia.org/wiki/Oracle_Media_Objects).
В общем, с одной стороны, Apple сделали всё, чтобы покрыть запросы максимально широкие, а с другой - превратить картотеку в инструмент программиста, этакий Powerpoint, который, как известно, рак любого серьезного дела. Ну а далее всё пошло по накатанной: в Mac OS X эту программу не пустили, так что многие современные пользователи и не знают, что она была.

Одни последовательно выбивали ноги из-под табурета вашего личного нетворкинга, другие сделали всё, чтобы вы делали "креатив & программирование", а не выстраивали отношения.

А вы ведете Ролодекс? Или для вас нетворкинг это синоним "заёбывать малознакомых людей приглашением на чашку кофе?"
Об мышиное зрение

В связи с появлением у меня Intel Core Ultra 155H решил попробовать оседлать NPU, встроенный в него. Для тестирования использовал модельки YOLO, потому что они достаточно понятно написаны на Питоне, а также могут быть легко экспортированы во множество форматов.

Что касается inference — работает без проблем, всё ускоряется в 2-3 раза по сравнению с голым cpu таргетом. Для компиляции и запуска я использовал OpenVINO и готовую модель, датасеты для которой стащил с сайта Roboflow и все сразу заработало в дефолтной конфигурации.

Что касается обучения, то результат хуже.

Само по себе YOLO не умеет использовать для обучения ускорители, кроме CUDA (похоже). Есть некие проекты вроде:
1. Intel extensions for pytorch (ipex) - для CPU и XPU (дискретная карта Intel)
2. intel-npu-acceleration-library (npu)
3. DirectML для ускорения операций при помощи любого железа, поддерживающего opencl
4. Разные опенсорсные поделки, приземляющие openCL на железо.

Из всего этого списка я смог разобраться только со вторым пунктом, так что YOLO успешно стало тренироваться с загрузкой NPU на 35-50%. Также хочу еще попробовать п.1 для CPU. Как использовать встроенный iGPU для обучения я пока не нашел способов.

Результатом NPU я, скорее, недоволен — обучение ускоряется всего на 20-25% относительно голого CPU в моей конфигурации. С учетом перспектив п.1 с расширениями для CPU, которые потенциально могут ускорить итерации вдвое, NPU не выглядит как подходящий бэкенд для тренировки — видимо, сказывается недостаточное количество блоков в архитектуре. А вот запуск натренированной сетки — ускоряет заметно.

Про ipex напишу еще, если что-то получится.
Об мышиное зрение 2 /памятка для себя самого/

Так как не на каждое изделие можно взгромоздить системный блок, а распознавание картинки требует сложных вычислений, приходится выбирать что-то более портативное. Мой выбор пал пока на творения китайской Rockchip серии RK35xx, оснащенные нейроускорителем. Вариантов исполнения модуля доступно несколько, мне приглянулся самый простой Orange Pi.

Многочисленные тесты показывают на модельке YOLO v5 производительность вывода на кадре 640х640 пикселей такую:

* i7 7700k - 120ms
* i5 13600k - 80ms (npu)
* rk3566 - 100ms

> ПРИЕМЛЕМО <

Ниже пишу шаги, как дойти от готовой модели к работающей системе. Тренировку модели оставим за скобками. Я использовал Python 3.10.15 для всего.

1. Китайцы из Rockchip немного доработали модель YOLO, так что её input/output форматы не совместимы с оригинальной моделью. Причина написана в пункте 2. Код для тренировки модели, а так же код для детекции надо брать в репозитории самого Rockchip, а не у Ultralytics: https://github.com/airockchip/yolov5

2. Если вы сами тренировали модель на своих данных, предстоит её экспортировать из PyTorch в Onnx. Тут надо сделать небольшое отступление. Современные модели давно уже не просто матрицы весов, а целые программы для виртуальных машин, со своими байт-кодами. Они могут быть не совместимы между собой, хотя и используют общий базис операторов. Не все операции поддерживаются аппаратно Rockchip, именно для такой оптимизации модель видоизменена. Модели PyTorch (.pt) и вовсе могут включать в себя сериализованные питон-объекты. Чтобы привести модель к каноническому виду, нужен экспорт в какой-то нейтральный формат. Экспорт делается, как указано тут https://github.com/airockchip/yolov5/blob/master/README_rkopt.md Результатом будет модель формата ONNX. Это тоже промежуточный шаг на пути к плате.

3. Для симуляции работы модели на компьютере следует использовать библиотеку https://github.com/airockchip/rknn-toolkit2/tree/master/rknn-toolkit2, а для работы на плате https://github.com/airockchip/rknn-toolkit2/tree/master/rknn-toolkit-lite2
Библиотеки существуют только для Linux. Ubuntu 24 в WSL2 подойдет.
При этом в симуляции работает только ONNX модель, а на плате для использования ускорения только RKNN.
В исходниках можно найти код загрузки ONNX модели и конвертации её на лету в RKNN модель. Также в репозитории можно найти инструкции, как конвертировать ONNX в RKNN запуском скрипта.

4. Остальной код, включая препроцессинг и постпроцессинг изображений, одинаков и для симуляции, и для платы, и взят тут https://github.com/airockchip/rknn-toolkit2/blob/master/rknn-toolkit2/examples/onnx/yolov5/test.py.

После загрузки RKNN в ускоритель можно подавать в неё кадры и получать положительные результаты.

Картинки детектятся, Python круто, Orange Pi 3B тоже хороша.
Об OSD

Если вы умеете не только в цифровое, но и в аналоговое радио, то сделать прототип векторного OSD для своей fpv-камеры не составит труда. Кое-что добавить на экран с картинкой с композитного видео не помешает. Следующим постом я покажу картинку со схемой, а тут приведу описание. Что нам нужно для работы простого монохромного OSD - суметь в правильный момент вмешаться в формирование строки и кадра, и подтянуть напряжение в нужных точках на нужное время к питанию (это будет белая точка или к земле — это будет черная). Для того, чтобы это сделать, хватит atmega на кристалле 16 Мгц и несколько ширпотребных радиодеталей. Я буду рисовать белым.

Сначала из входного сигнала надо отсечь положительное смещение, потому что у разных камер оно разное, это делается конденсатором C1. После этого на R1 и D1 собрана схема восстановления положительной составляющей, которая поднимает сигнал до нужного нам уровня. На R2 и D2 собран генератор референсного напряжения порядка 0.56В. D1, D2 у меня это дешевые импульсные диоды 1N4148.

В итоге мы получаем на входе Comparator-A сигнал, который каждую строку и каждый кадр проседает до примерно 0.3В. Теперь потенциометром R3 на входе Comparator-B можно задать примерно 0.3 вольта, а на atmega настроить аналоговый компаратор, чтобы он генерировал прерывание по сравнению двух входов. В итоге мы получим, что в обработчике прерывания у нас есть момент начала гасящего импульса строки или кадра. Таймером мы считаем время, пока компаратор не вернется в исходное, и понимаем, это был ССИ или КГИ, и выставляем у себя переменные.

Итого, мы имеем номер строки на экране, понимаем начало кадра — и далее в обработчике прерывания компаратора осталось отработать эту информацию и нарисовать развертку. С таким медленным чипом, как Атмега, это непросто, и работать надо в реальном времени, так что лишего бюджета времени во время рисования линии нет даже на операцию настоящего деления - настоящее деление занимает 1/20 кадра по горизонтали — так что приходится пользоваться битовыми сдвигами или предрасчитывать ранее.

Собственно, зная, что нужно изобразить в данной точке строки экрана, загоняем соответствующие байты в SPI регистр. SPI на atmega, как вы помните, может разгоняться аж до половины тактовой частоты кристалла, и на каждый такт на выходе из него будет появляться бит, начиная со старшего. 1 будет рисовать белый участок линии, 0 — оставит картинку как есть. Чтобы
На частоте кристалла в 16МГЦ это позволит рисовать только сдвоенные пиксели относительно максимального разрешения PAL, то есть около 340 пикселов на экранную строку, но и это неплохо. Разрешение в 300+ линий по высоте остается. Самое сложное тут будет посчитать тайминги — каждая машинная операция идет в зачет, писать придется на Си или Ассемблере.

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

Что рисовать на экране? Это уже что фантазия предложит. Кому-то нужны линии уровня, кому-то текст — для текста надо будет реализовать свой знакогенератор. Я добавил i2c-интерфейс, чтобы управлять картинкой при помощи SMBus-протокола.

Дальше будет принципиальная схема.
1. Здесь Sin и Sout совмещены. Если хочется их развести, понадобится буферный каскад, например, по каскодной схеме; мне не понадобилось. 2. Кто-то говорит, что генератор PWM в atmega + интегрирующая цепочка могут заменить потенциометр — возможно, но я не пробовал, может быть, вы попробуете
Об GPIO в линуксах

Как вы знаете, некоторые время назад в линуксе декомиссовали управление GPIO через псевдо-ФС /sysfs. Несмотря на то, что поддержка в целях совместимости сохраняется, использовать это ни в коем случае не надо. Вместо этого предлагается символьное устройство, на большинстве дистрибутивов это /dev/gpiochipX и ядерный интерфейс uapi к нему. А чтобы воспользоваться интерфейсом, лучше всего использовать libgpiod.

Если в Raspberry PI этот момент разобран достаточно подробно, то наш дорогой Xulong предоставил владельцев Orange PI самим себе, опубликовав только wiringOP и байндинги к разным языкам, который еще и работает из-под рута. И если в дистрибутиве Orange OS про i2c как-то подумали и есть инструкции, то про GPIO api там вообще ничего нет. Ну и ничего, мы справимся, щас покажу как.

Сначала надо поставить libgpiod посвежее подходящей версии. У меня Ubuntu 22.04, я качал предсобранный архив отсюда https://raw.githubusercontent.com/devdotnetorg/docker-libgpiod/HEAD/out/libgpiod-bin-2.1.2-ubuntu-22.04-aarch64.zip Но у автора есть шелл-скрипт, который позволит и версию выбрать, и собрать из исподников, если надо. Скачанное просто нужно распаковать в /usr как есть.

Дальше я поставил библиотеку для питона вот такой командой:
LINK_SYSTEM_LIBGPIOD=1 pip install gpiod
Переменная окружения тут говорит, что не надо тащить с собой никакие библиотеки, надо брать, что в системе есть.

По умолчанию доступ к GPIO есть только из-под рута, поэтому чтобы обычный юзер получил доступ, потребуется слегка настроить udev. Доступ необходимо дать к устройству, отвечающему за нужный вывод ( /dev/gpiochipX). Как определить нужное устройство в Orange Pi, тоже есть нюанс.

Открываем распиновку платы в документации, скажем, вывод (pin) 27 помечен как GPIO1_A0. Надеюсь, вы не активировали альтернативные функции — UART, I2C, SPI — в device tree через orangepi-config на этот вывод, и он доступен (проверьте командой gpio readall, рядом не должно светиться ALTx). GPIO1_A0 расшифровывается так:
1 - чип
A - банк выводов (A= 0, B = 1, C.., D..)
0 - номер вывода в банке.
Номер чипа = 1, номер линии (понадобится потом) = 8 * номер_банка + номер вывода. В моем случае chip = 1, line = 0, пригодится.

Делается это в моём случае так:
sudo groupadd gpiod
sudo usermod -aG gpiod orangepi
sudo echo '# udev rules for gpio port access through libgpiod
SUBSYSTEM=="gpio", KERNEL=="gpiochip1", GROUP="gpiod", MODE="0660"' > /etc/udev/rules.d/61-gpiod.rules

gpiochipX=gpiochip1, потому что у меня chip=1. После перезагрузки у пользователя orangepi, как состоящего в группе gpiod, будет доступ к нужному контроллеру.

Теперь в вашем скрипте управления умным изделием можно сделать так:

import gpiod
from gpiod.line import Direction, Value
LINE = 0
request = gpiod.request_lines("/dev/gpiochip1",
consumer="example",
config={LINE: gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.ACTIVE)})
# ...
request.set_value(LINE, Value.ACTIVE)
# ..
request.set_value(LINE, Value.INACTIVE)


Если есть дополнения, то пишите тоже.
Please open Telegram to view this post
VIEW IN TELEGRAM
На последней TeamleadConf один из докладчиков пожаловался на то, что на их микросервисное монорепо, все писанное на Go, перестало хватать разработчиков -- буквально вот не могут найти на рынке, конкуренция жёсткая даже между командами внутри (ха-ха, кто мог подумать? Вот бы кто-то об этом раньше написал!)

А я в связи с этим предлагаю вспомнить один пост из этого канала трехлетней давности, из которого становится ясно, почему делать микросервисы, но все писать на одном языке (а монорепо значит с вероятностью 99% и моноязык) это потенциальная глупость и ошибка 👇
Об микросервисы в который раз

Ну, хорошо, всем продали микросервисы: дескать, и устройство системы понятнее из-за них, и two pizza team вообще стандарт в Гугл ИТ, значит, и нам надо тоже. И код можно писать на самом подходящем языке: хочешь, пишешь на php, не хочешь, пишешь на nodejs, что очень удобно (особенно потом сопровождать комплекс, написанный на 10 языках). А еще можно переписать за две недели маленький микросервис, любой. Ну круто же, правда?! А еще архитектура очень отказоустойчивая, и если один сервис упал, то остальные выживут (на практике - не работает никогда). И самое главное - можно МАСШТАБИРОВАТЬ приложения! О том, что монолит тоже можно масштабировать, тем более сейчас, когда железо ничего не стоит, молчат.

Но это все selling points для недоверчивых технарей, а я расскажу, почему на самом деле бизнес выбирает микросервисы. Причин всего две:
1. Быстрая проверка гипотез, которые в 9 из 10 случаев проваливаются - да, продакт-менеджеры тоже не боги. В случае монолита вы стоите перед непростым выбором: или вкладываться по полной в эксперимент (дизайн, код, тесты), который, скорее всего, будет выброшен, или на коленке слепить то, что рискует выстрелить, и тогда с этим поделием придется жить вечно в монолите. Какой вариант хуже? Оба хуже. В случае с микросервисами эксперименты не сильно трогают ядро системы, которая кормит всю компанию и их семьи.
2. Найм. В ситуации, когда средней компании найти хорошего разработчика за праздник, в случае микросервисной архитектуры можно нанимать вообще любых программистов, которые подвернулись, а не те, которые подходят по стеку или согласны работать с легаси и т.п.

Эти две причины пересиливают все сложности, связанные с МСА. А сложностей немало, от оркестрации до смены парадигмы владения системами.

Все, больше на самом деле ни зачем не надо. А, еще маленькое замечание: проще нанимать людей, потому что "у нас такие же крутые технологии, как в Гугле, так что мы будем платить поменьше".
2024/12/27 02:19:35
Back to Top
HTML Embed Code: