All streams
Search
Write a publication
Pull to refresh
4
0.1

User

Send message

Меня просто вот эта фраза зацепила

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

Я считаю, что именно в embedded здоровый консерватизм бывает особенно полезен. Поэтому и привёл пример, как иногда бывает, когда "древних дедов-руководителей" нет, а решения принимают молодые и прогрессивные, несущие модные технологии, идеи и паттерны, но зачастую не понимающие, что и зачем они на самом деле делают. Ну действительно, зачем в условном устройстве с тремя кнопками и двумя светодиодами несколько десятков потоков? Да, как таковая РТОС тут действительно не при чём, но она дала возможности "прострелить себе ноги". В момент принятия решений не оказалось в наличии оппозиции в виде "древних дедов", и парни сделали, как их учили в их книжках/курсах - берём ОС, на каждую задачку по потоку, разруливаем всё семафорами, применяем модных паттернов побольше. И в итоге, очень простую вещь закодировали очень сложно, а потом сами мучались от этой сложности. Не оказалось того, кто сразу, посмотрев на всё это, сказал бы - но ребята, это же простая задача, давайте решим её просто.

И где условная гарантия, что такие люди не будут плодить баги и т.п. при работе в стиле "Мегацикла"

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

Не так важно, используется RTOS или нет, но важно, как всё организуется. Из практики. Были несколько проектов, без оси. Всё крутилось в главном цикле, всё выполнялось последовательно. Работало. В новом поколении устройств внедрили РТОС, и проекты переписали. Каждый чих - отдельным потоком, и вроде всё красиво, в теории. А а по факту, работает криво-косо. Потоки вразнобой, рандомно задерживают друг друга из-за необходимости синхронизации. Эту самую синхронизацию местами забывают добавить. Чёткую временную диаграмму выдержать сложно. Период какой-то операции неправильный? Пытаются лечить задержками. Задержку у одного потока поменяли - временная диаграмма подвинулась, остальное уехало. Боль, вечные замечания от заказчика, вечная поддержка, доработка костылями. Проект переусложнённый, новички пугаются. Или, что ещё хуже, начинают считать, что это норма. Наконец это надоело уже, и переписали по-классике. Основной поток, в нём цикл, в нём последовательно выполняются функции-задачи. Отдельные потоки - только для действительно независимых, фоновых задач, не связанных напрямую с прикладным функционалом. Кучи потоков теперь нет, временная диаграмма стала чёткой и понятной, синхронизация не нужна, кода стало в два раза меньше, ресурсов процессора потребляется меньше, что и как делает проект стало наконец-то понятно человеку, впервые открывшему код. Ну и замечания, которые до этого годами копились и висели, вгоняя разработчиков в депрессию, вдруг тихо и мирно пропали.

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

Одна из лучших, если не самая лучшая, книга о программировании из всех, что я прочитал. Не только о Си и плюсах, там много очень глобальных вещей, в том числе о подходе к разработке. Никакой воды, всё из практики, всё с объяснением почему и как. Недавно перечитывал, и в очередной раз поражался, насколько вещи, там описанные, актуальны до сих пор. Большинство граблей, на которые наступают коллеги по работе, там расписаны. Так что пытаюсь по мере сил рекламировать в коллективе сию книжку.

2–Не допускать всяческих магических чисел в коде. Это уничтожает читаемость кода. Все константы надо определять в перечисления заглавными буквами.

В целом всё так, но про "все константы" это наверное зря. Я не раз встречал код, авторы которого слишком буквально понимали правило "не допускать чисел в коде". Константами там было задано вообще всё, включая 1 и 0. Это был код а-ля

x = (y >> TEN) & ONE;

Это хуже читается, искать баги становится сложнее, ведь каждую такую константу нужно проверять, а на самом ли деле ONE равно 1, а вдруг автор совсем не то имел в виду.

Ещё один пример - когда константами забиваются значения битов/полей в регистре. Да, это отличное правило, и в общем случае ему очень желательно следовать. Но, опять-таки, на практике встречается код с огромным количеством таких констант в h-файле, скажем, драйвера, а в его си-файле по факту в паре регистров пара битов проверяется, и всё. Когда осознаёшь, что кода могло бы быть в разы меньше, а сам он был бы сильно проще и понятнее, категоричность суждений снижается, и понимаешь, что правила правилами, но в отдельных случаях правильнее, как ни странно, может оказаться от них отступить. И проверить нужный бит явно, в комментарии указав, что именно мы тут делаем и в каком пункте даташита об этом говорится. Работа поддерживающего программиста станет проще в разы.

35--Для синтаксического разбора регистров использовать объединения вкупе с битовыми полями.

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

Когда пишешь что-то (потенциально) мультиплатформенное, или, не дай бог, протокол обмена, то битовые поля - это боль. Сталкивался со случаем, когда в протоколе обмена битовым полем была описана большая структура. И всё ожидаемо поломалось, когда в какой-то момент обмениваться пришлось с новой системой, с другим порядком байтов. В тот раз несколько дней потратили на ручной "переворот" битовых полей. И теперь в том протоколе две структуры - одна для BE, другая для LE, что, конечно же, не очень здорово из-за дублирования кода.

Ещё эпичный случай. Искали трудноуловимый баг в коде. Нашли, что неверно пишется значение в поле структуры. Было там примерно следующее:

state.result = SOME_ERROR_CODE;

При этом, SOME_ERROR_CODE равно двум, поле bar имеет тип int, но в результате записи там почему-то оказывается ноль. Почему? А потому что автор объявил поле так:

int result: 1;

В тот момент ему хватало двух значений для кода результата, но в какой-то момент ему понадобились ещё коды, он их добавил, а битов для поля не добавил. С точки зрения языка, тип поля - int, IDE показывает, что тип поля - int, число 3 в int влезает, компилятор не ругается. Так этот баг в итоге и остался на какое-то время незамеченным.

14–Если переменная это физическая величина, то в суффиксе указывать размерность (timeout_ms). Это увеличивает понятность кода.

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

15–Все Си-функции должны всегда возвращать код ошибки. Минимум тип bool или числовой код ошибки. Так можно понять, где именно что-то пошло не так. Проще говоря, не должно быть функций, которые возвращают void. 

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

Вот вы, например. часто проверяете, что там printf вернул? Многие и не знают даже, что он что-то возвращает. Таких примеров множество.

Представим, что мы написали библиотеку для растровой графики. Там есть функция gfxInit(). Должна ли она возвращать код результата? Скорее всего да, должна, ведь инициализация может пройти неудачно, скажем, из-за нехватки памяти, из-за аппаратных причин (железо нужное на шине не нашли), и т.п. В этом случае, очевидно, ПО должно как-то отреагировать на критический сбой. А должны ли возвращать ошибку функции навроде gfxPutPixel() или gfxDrawLine()? Моё мнение - нет. Не нужно заставлять программиста, использующего ваш интерфейс, засорять свой чистый и понятный код отрисовки графики бесполезными проверками. Код станет нечитаемым адищем, а пользы для дела - ноль. Гораздо полезнее в подобных случаях (когда подсистема/библиотека может "отвалиться" в процессе работы) создать отдельную функцию для получения текущего состояния - и вот её уже можно будет вызывать периодически (один раз за такт в главном цикле работы, например), чтобы узнать, всё ли там в порядке.

Да, mars тоже крышу сносил. В моём личном рейтинге вторым номером идёт. Но там примерно понятно, как сделано, и размер бинарника всё-же не экстремально маленький.
Спасибо! Это моя любимая демка с детства. Тогда воспринималась как нечто совершенно магическое. Вдохновившись, даже пытался что-то столь же миниатюрное на асме сделать, но у меня даже банальный летающий по экрану кирпич не получилось в 256 байтов вместить )
Уже достаточно давно Виктор Аргонов сделал логичный шаг, и выложил оперу «2032. Легенда о несбывшемся грядущем» в открытый доступ.

А вчера он объявил о том, что начинает акцию по превращению оперы в произведение с открытым кодом (что звучит достаточно оригинально в контексте музыкального произведения). Акапеллы уже выложены, а MIDI файлы, по его словам, пока что в процессе «причёсывания». Подробности тут: argonov.livejournal.com/95407.html
Насколько я знаю, в немодифицированном виде — нет. К тому же, Комстар не для всех актуален. Я вот в Питере, тут кроме Йоты другого ваймакса нет. Остаётся надежда, что тариф не поменяют. Тогда, вроде как, владельцы MAXов даже в плюсе окажутся, на фоне разгрузившейся сети )
Или теперь для ВСЕХ устройств 1400? Тогда для меня получается аж в 3 раза увеличение… Это уже где-то за границами добра и зла (
Нигде не нашёл, как изменится тариф для HTC MAX, который сейчас 500р/мес
Питер. Пользуюсь постоянно уже почти год, в целом доволен. Веб, почта, пробки в навигаторе. Торренты не качаю, но изредка приходится грузить что-либо большое, и обычно всё без проблем. Скорость в среднем полтора-два мегабита. Поначалу были проблемы с частыми разрывами связи, сейчас всё ок. Из минусов — неровное покрытие, но и оно со временем заметно улучшается.

Йотовскими сервисами не пользуюсь (пробовал йота-ТV — часто подтормаживает и мало интересных мне каналов, в йота-музыке аналогично — не нашёл ничего мне интересного).
12 ...
8

Information

Rating
3,278-th
Location
Россия
Registered
Activity