Embedded разработка и как я очутился на Хабре
Спустя полтора года опыта работы в embedded разработке в большом соло-проекте, в который меня совсем зелёного, ещё не окончившего университет, бросили сразу после собеседования в первой понравившейся мне компании, вдруг пришло в голову осознание: "нужен код-ревью!". Предпосылкой к этому стало то, что я почти закончил проект и подумал начать его рефакторить. Именно это подтолкнуло меня решиться попробовать оформить мысли в блог, в котором кто-то найдёт для себя идеи, как не надо делать (а где-то, наоборот, как надо), а я смогу разложить по полочкам всё то, что крутится у меня самого в голове.
Трудности новичка
Чтобы читателю сиего бреда было понятнее: за 1.5 года работы над проектом с нуля, без боевого опыта до этого, он наполнился просто неимоверным количеством говнокода. Ко мне не было поставлено наставника, не было человека с палкой подгоняющего с выполнением проекта, всё спокойно и размеренно. В некотором роде: абсолютная свобода действий, учись и работай, работай и учись. Есть коллеги, которых я постоянно терроризировал вопросами, как парсить, что такое ОСРВ(RTOS), как работать с DMA (забегая вперёд - я так и не научился ещё с ним работать) и прочими вопросами а-ля "А как какать?". Но всё это было сродни блужданию в тёмном лабиринте ночью без фонарика. ТЗ не ставили бумажно, оно было словесное: твоё устройство должно уметь это, это и это. Вот я и стал разбираться. Сперва с SIM-модулем и АТ-командами, потом с ОСРВ, потом с Bluetooth, потом с конечными автоматами, TCP и так далее. Разбил себе задачи (читай, неизвестные на тот момент вещи) на блоки и постепенно их осваивал. Для решения каждого вопроса требовались какие-то инструменты, которых у меня не было, и мне всё чаще вспоминалась строчка из одной песни: "А я-то думал - я умней. Очень жаль."©
И кстати это ощущение не покидало меня первые три месяца ни на минуту. Сейчас я могу сказать "я знаю что-то", но даже не "многое" и строчка всё ещё проносится временами в голове. Однако уже и есть чем гордиться, но об этом позже.
Ещё одним камнем преткновения было "а какие библиотеки использовать?". И тут надо сказать, что у каждого человека у нас в отделе - соло-проекты, без общих стандартов (за исключением проприетарного общего управляющего протокола), каждый разрабатывает свои устройства. Трое коллег и шеф разделились на четыре лагеря: консервативный шеф топит за регистры + старый RTL, трое коллег каждый по своему: SPL + RTL, LL + RTX5 и Hal + FreeRTOS. Всё, как говорится, на ваш выбор. Но почти все не любят Hal, даже тот, кто им пользуется.
Промучившись какое-то время с исходниками шефа, познав основы работы с ОСРВ и боль от непонятных на тот момент регистров, я решил, что буду использовать то, по чему могу найти больше информации в русскоязычном сегменте. Да, это не тру, инфу надо брать из официальных англоязычных мануалов, но когда что-то совсем уж не получалось, самооценка, и без того не высокая, летела в тартарары, а апатия хватала за горло - приходилось идти в ру-сегмент за разжовыванием. И тут как-то само собой больше инфы попадалось про SPL (Hal не брал в расчёт).
С ОСРВ оказалось проще - в Keil можно из коробки подгрузить кучу всего. Больше инфы на просторах интернетов было про FreeRTOS, но шеф сказал "не стоит, у Кейла есть своя операционка". Самая свежая - RTX5, инфы по ней тоже много, значит - решено. Осталось срастить с библиотеками SPL, чтобы всё компилировалось без ошибок и варнингов со всеми инклюдами библиотек на стадии одного пустого "while(1)" в main-е. И на одно только это у меня ушло... две недели... Разные версии подгружаемых драйверов ссылались на разные startup-ы и system_stm32fxxx-ы, где-то не хватает дефайнов, где-то происходят редефайны, и тому подобные нестыковки... Мир говно, но мы - с лопатой!
Первые успехи и новые проблемы
По итогу у меня получился каркас для будущих проектов в виде папки "FOR NEW PROJECTS" со всем нужным для начала. Окей, копируй, создавай новый репозиторий и можно работать.
Если кому-то может пригодится подобная сборка SPL (v 1.8.0) + RTX5 (v. 5.5.3 со всеми зависимостями) собранная для STMf4xx - вот готовый стартер. Мне бы в самом начале подобный стартер сильно помог.
Но чем дальше в лес - тем толще партизаны. С освоением каждого нового блока я писал свои функции, библиотеки пополнялись одноразовыми неунифицированными инструментами, неприменимыми при малейших изменениях условий. Как пример, в предрелизной версии у меня используются 5 циклических буферов для периферийных устройств с приём-передачей потока информации. И для каждого из них написан свой комплект функций, причём где-то работа строится на простой индексации, а где-то на указателях, потому что так было удобнее. "Всё не так!", подумал я и написал класс для циклобуфера, описал унифицированные методы, которыми можно будет заменить ту пачку функций, написанных прежде - пора производить замену костылей на велосипеды и тут выясняется... Надо переписывать весь (ну почти весь) проект. С десяток срр-шных файлов под 1000 строк в каждом. Глаза по 5 рублей, в них ужас, а за ними всё та же строчка из песни... Придётся релизить проект, как есть, и садиться за полномасштабный рефакторинг. Радует то, что удалось сделать его стабильным, с возможностью обновления по воздуху и отвечающим всем поставленным словесным требованиям. Ах да, ещё и защитить по нему диплом =D. Правда от бинарника прошивки под 80 кБайт глаза округлились даже у шефа.
Выводы и планы
Библиотека SPL, несмотря на полноту описания, удобство и достаточность функционала, уже больше не поддерживается и есть риск при работе с новыми контроллерами наткнуться на нестыковки. Поэтому в планах на "когда-то" стоит переписать проект под LL, который, схож с SPL, но имеет серьёзные преимущества: поддержка действует, библиотеки обновляются, а так же - LL интегрирован в Кубы (STM32CubeIDE), на которые, возможно, придётся переходить вместе с переходом на Линукс (пока только планы на будущее).
Костыли нужны. Без них не научишься ходить. Но крайне важно научиться вовремя отсекать момент, когда их нужно заменить на что-то нормальное и организованное. А то получится как у меня, с циклическими буферами.
Нужен код-ревью. Просматривая и читая блоги программистов я узнал, что некоторые из них тратят до 3 часов рабочего времени на ревью кода коллег. Но как ввести такую практику там, где нет командной работы над проектами? Мы договорились с товарищем, что будем просто объяснять друг другу свои проекты, а когда уясним принципы, попробуем объяснять друг другу свой код. Посмотрим, что из этого выйдет, надеюсь не просто трата времени.