All streams
Search
Write a publication
Pull to refresh
3
0.1
Кривенков Роман @qwerty19106

Embedded

Send message

Вот по-этому вам в самом начале и написали, что пример слишком специфичный. Вы приводите новое железо как пример, и обобщаете на все встраиваемые устройства. При этом условные 99% новых разработок делаются на старом железе, и всё отлично собирается на stable.

Давайте вы наконец признаете, что это

Мало того, что нужен еще и упомянутый build.rs, так еще не редко требуется .cargo/config.toml, rust-toolchain.toml, sdkconfig.defaults и cfg.toml

вам нужно только под новые версии ESP, и не будете вводить всех в заблуждение.

Сравнивать распространенность МК с WiFi и BLE и МК общего назначения без них выглядит по дилетантский. Когда нужен WiFi, решения Expressif пока вне конкуренции. Можете убедиться сами, покопавшись в различных IoT устройствах с WiFi.

А я вот например пишу связь на LoRa и LoRaWAN, и еще на WiFi Broadcast. И WiFi с BLE мне не нужны, т.к. расстояние для связи >20км (на скольки метрах отваливается BLE?). Зато отлично подходят МК общего назначения.

Связь бывает разная, не надо её сводить только к одному решению.

Могу добавить, что Embassy не поддерживает аффинити и жесткого real-time с тайм-слайсинг. Этого мало?

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

А еще можно запустить несколько Executor с разным приоритетом (привет FreeRTOS), так что вы тоже не в теме.

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

Из этого следует, что Nightly нужен только конкретным библиотекам под ESP32, я же писал про "на микроконтроллерах STM32 и других Cortex-M", читайте внимательнее.

С оптимизациями на Cortex-M и RISK-V тоже все норм.
Не совсем понятно, какая кодогенерация вам нужна, но описание регистров для ESP32 и NRF точно кодогенерируется из yaml файлов, и без Nightly.

Как видите, не "хочется", а "требуется".

Как видите, требуется именно под ESP32. Но ESP32 не так уж и распространен, абсолютное большинство микроконтроллеров на архитектурах Cortex-M и RISK-V.

Перепишите весь ESP-IDF на Rust. Я не против. А до этого экономически нецелесообразно отказываться от уже имеющихся средств в пользу гипотетического успешного переписывания их в будущем.

На С есть реализации TCP стека (например CycloneTCP). Но в ESP-IDF написали свою реализацию всего на свете, вы считаете это правильная архитектура? И теперь внезапно огромная куча кода, которая жестко привязывает к своему API.

Теперь сравните это с Embedded HAL например. Я на нем один раз пишу драйвер для датчика, и он одинаково работает на любых микроконтроллерах и архитектурах.

Исходя из этого, я считаю целесообразным использовать ESP-IDF только если невозможно использовать другие чипы с WiFi. И код буду писать скорее на С, чтобы избавиться от всех тех проблем с Nightly, блобами и т.д., от которых вы так страдаете.

А это при чем? С точностью наоборот, применение embassy_net на ESP32 невозможно без esp-wifi с блобами. А esp-rs, естественно, вполне может обходиться без Embassy, пользуясь ESP-IDF, предоставляемого в исходниках.

Еще раз, все библиотеки для ESP32, использующие Embassy RTOS, это сторонняя разработка. Предъявляйте претензии по блобам к их авторам. В embassy_net нет зависимостей к этим библиотекам, убедитесь сами.

Если бы вы прошли по своей же ссылке (лол), то могли бы прочитать следующее:

esp-wifi for WiFi support on bare-metal ESP32 chips. Maintained by Espressif.

Сам Embassy поддерживает только те семейства микроконтроллеров, которые есть в его репозитории. Это STM32, NRF, RP2040, RP235x и еще парочка (но их добавили прям только что, и пока нет стабильности).

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

Нет не погорячился. Несколько проектов для STM32, один для NRF и для RISC-V АМУР вполне себе собираются стабильным компилятором. Но если вам так хочется, используйте ночной.

Не только FreeRTOS, но и масса иного кода не на Rust требует установки переменных окружения при сборке.

Просто вы привыкли пользоваться FreeRTOS, и не хотите пробовать альтернативы. И про другой код хотелось бы поконкретнее.

Только если Вы являетесь производителем МК и разрабатываете весь софт для него сами сразу на Rust. Вы уж простите, но, для примера, я бы полгигабайта исходников ESP-IDF переписывал бы с C на Rust лет десять, явно не успевая за Espressif.

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

Как по мне, лучше биндится к исходникам на C, чем к блобам как тут в Embassy.

А теперь найдите в этом esp-rs зависимость от Embassy xD) Не найдете, её не существует.

В Embassy никаких блобов конечно нет. Я вообще имел ввиду не весь проект, а конкретно RTOS. Можно взять RTOS из Embassy, и написать свою (или взять стороннюю) либу под конкретный микроконтроллер, как например я сделал для АМУР.

Если же вам нужен сетевой стек, то есть например https://github.com/smoltcp-rs/smoltcp, и он будет одинаково работать на STM32Wx и ESP32. И переписывать гигабайты не потребуется.

Не скажу за все встраиваемые системы, но на микроконтроллерах STM32 и других Cortex-M этого списка файлов я использую .cargo/config.toml всегда, build.rs иногда, остальные не нужны.

toolchain.toml не нужен, т.к. код собирается на стабильном компиляторе.
sdkconfig.defaults вообще не понятно зачем, видимо ваш FreeRTOS требует.
cfg.toml это что-то специфичное только для ESP32, к Cargo отношения не имеет.

И биндинг к другим языкам на микроконтроллерах не нужен, FreeRTOS не единственный RTOS, и как бы не самый худший из них. Посмотрите лучше на Embassy.

Тоже не понимаю, зачем обсуждать аргументы 2004 года. Очевидно, что за 20 лет ситуация поменялась.

Но по вашей же ссылке можно прочесть:

It was only in 2022 meanwhile that the Linux kernel began moving from C89 to C11. Especially if there is consensus to permit a subset of C++14/C++20 programming in the kernel, it may still be some time before it's adopted to allow for broader compiler support to roll out before raising the base compiler requirements and even if receiving the miraculous endorsement of Torvalds it's not a decision to be taken lightly.

Если стандарты С в ядре внедряются так медленно, то что же будет с С++? Так что вы выдаёте желаемое за действительное.

А не они ли для этого написали свой компилятор, свой стандарт С++ и свою STL, из которого кроме исключений выпилили почти все UB?

То что получилось, уже никак нельзя называть языком С++.

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

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

подменить контекст обсуждения ядра на микроконтроллеры и потом обвинять в этом собеседника - очень достойно

Про ядро я вам тоже ответил. И про разделение ответственности между библиотеками и прикладным кодом (к которому относится и код драйверов в ядре).

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

при это игнорируя собственно практически важные вещи из треда

Укажите какие именно, и я на них отвечу. Телепатией пока не владею.

Вы можете собрать код без Cargo. Для этого нужно для каждого .rs файла запускать компилятор rustc с набором ключей компиляции, на выходе будут обычные .o файлы. Далее можно их слинковать системным линкером, желательно lld.

Но я не понимаю, зачем? Cargo это просто система сборки, как CMake для С и С++.

Теоретически можно использовать Cargo без rustup, и указать путь к компилятору rustc через переменную окружения, или .cargo/config.toml файл. Тогда можно будет использовать системный пакет с компилятором rustc, во многих дистрибутивах он есть (Debian и Ubuntu например).

Весь код на чистом Rust, и нет зависимостей от С или С++, соответственно и от gcc и llvm. Конечно компилятор Rust где-то внутри содержит llvm, но устанавливать системный не нужно.

Чтобы собрать, нужно установить компилятор Rust, и запустить строку cargo r -r -p crt < scenes/utah.crt > out.ppm (она скомпилирует и запустит код). И пожалуй всё на этом.

А вы всегда отвечаете вопросом на вопрос?

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

Я считаю что ответил. И я правда не понимаю что вы ещё от меня хотите.

Напишите свою версию определения, может понятнее будет.

Да бог с ним с UB

Это вы так признали свою неправоту?)

Тогда я перефразирую тот комментарий:

Тут надо рассматривать 3 случая:

1) На этапе компиляции известно что есть UB (например выход за пределы массива с известным индексом). Тогда код изначально не является кодом на С++.

2) На этапе компиляции известно что нет UB (все потенциальные места обвешаны проверками). Тогда код является кодом на С++.

3) На этапе компиляции нельзя доказать что нет UB, но есть места, потенциально содержащие UB (в них недостаточно проверок). Тогда нельзя сказать заранее, является ли кодом на С++.
Если при запуске такого кода происходит UB (например входные данные, которые не функция не ожидает), то в этот момент он перестает быть кодом на С++.

Термин "программа на С++" ввели вы в этом комментарии. Это я бы должен спрашивать что это xD.

Но я на это повелся, не заметил даже. Но везде имел ввиду "код на С++". Про него я подробно уже ответил вот в этом комментарии.

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

А вот код с UB (который при некоторых входных данных вызывает UB) может выдать разный результат при каждом запуске. Я выше вам привел пример с ARM.

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

Многократно эксплуатируя эту уязвимости, можно прочитать ключ шифрования например. А вы говорите:

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

Не ужели вы не видите тут ошибку в своей логике??

Конечно. Вся статья о том, как "писать правильно и не писать неправильно". Что же в этом плохого, раз компилятор не может этот момент проверить за программиста?

Но чем этот совет и способ предотвращения ошибок в программах не подходит, например, для С++?

Подходит, о чем я и писал на 4 комментария выше.

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

Compared to a real-world program, the consequences of creating a reference cycle in this example aren’t very dire: right after we create the reference cycle, the program ends. However, if a more complex program allocated lots of memory in a cycle and held onto it for a long time, the program would use more memory than it needed and might overwhelm the system, causing it to run out of available memory.

Creating a reference cycle would be a logic bug in your program that you should use automated tests, code reviews, and other software development practices to minimize.

Вы выдираете слова из контекста, и этим гордитесь почему-то.

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

Не говоря уже о разных версиях компилятора, целевого процессора, ОС компилятора и целевой ОС и т.д.

не может находится в неопределенном состоянии

Вообще-то может. Приведу простой пример:
Процессор ARM может (и постоянно делает) переупорядочивать на лету ассемблерные инструкции. И при многопоточном доступе может возникнуть data race, если не выставлены правильные барьеры памяти.

В результате один и тот же код (одинаковые инструкции ассемблера) на одном процессоре с одинаковыми входными данными выдаст разный результат. Скомпилированная программа находится в неопределенном состоянии, и это тоже UB.

Если честно, то это вы придираетесь к словам, а не к сути.

Я понимаю вашу претензию к автору статьи, он не прав про утечки памяти в С++. Но и вы не правы, они абсолютно одинаковые в С++ и Rust. И способы их избежать одинаковые: слабые ссылки.

Тут надо рассматривать 3 случая:

1) На этапе компиляции известно что null, и мы его разименовываем. Тогда изначально не являлась программой на С++.

2) На этапе компиляции известно что не null, и мы его разименовываем. Тогда UB нет.

3) На этапе компиляции не известно что лежит null / не null, и мы его разъименовываем без проверки. Тогда программа потенциально содержит UB, а фактически содержит UB в момент фактического разъименования null (и в этот момент перестает быть программой на С++).

Но изначальный мой посыл был что Undefined behavior гораздо опаснее unspecified behavior, а вы пытаетесь их приравнять.

Она safe в смысле что не вызывает UB, и может произойти без блока unsafe. Это просто описание фактического положения дел.

Другие языки не называют утечки памяти "безопасными"

Но и не называют их "небезопасными". Вот если в другом языке будет написано что утечка памяти unsafe или unsound, тогда будет о чем говорить. Можете привести такой пример?

Information

Rating
3,308-th
Location
Ижевск, Удмуртия, Россия
Date of birth
Registered
Activity