Skip to content

Вопросы на собеседовании: Embedded-инженер

100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior Embedded-инженер.

Смотреть пример резюме: Embedded-инженер

Тренировка флешкарточками

Интервальное повторение · Hunter Pass

Вопросы

mcu

Это микроконтроллер, потому что процессорное ядро, память и аппаратная периферия объединены в одной микросхеме.

  • Ядро Cortex-M3 выбирает и выполняет инструкции прошивки, хранящиеся в 64 КБ flash.
  • В 20 КБ SRAM при включенном питании находятся изменяемые данные, например стек, глобальные переменные и коммуникационные буферы.
  • Встроенные GPIO, таймеры, ADC, UART, I2C и SPI позволяют прошивке управлять аппаратурой без отдельных микросхем-контроллеров.
  • Частота ядра 72 МГц задает верхний темп выполнения инструкций, но периферия может работать медленнее из-за собственных частот и делителей шин.

Зачем это спрашивают: Интервьюер проверяет, отличаете ли вы процессорное ядро Cortex-M от построенного вокруг него полноценного MCU.

firmwareperipheralsmcu

Memory-mapped I/O означает, что обычная на вид операция загрузки или записи обращается по этому адресу к аппаратной периферии, а не к RAM.

  • Для 32-разрядного регистра по адресу 0x41004410 прошивка должна использовать определение из заголовка производителя или volatile-указатель на uint32_t.
  • Запись меняет аппаратные биты GPIO, поэтому значение может управлять физическими выводами, а не храниться как обычная память.
  • Перед обращением нужно включить тактирование GPIO, иначе запись может не дать эффекта или вызвать ошибку шины.
  • Справочное руководство определяет доступные для записи и зарезервированные биты, поэтому прошивка должна сохранять поля, которыми не управляет.

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

mcu

Сначала ядро читает векторы через загрузочный alias 0x00000000, который STM32 может сопоставить с flash по физическому адресу 0x08000000.

  • Первое слово по адресу alias аппаратно загружается в MSP до выполнения первой программной инструкции.
  • Второе слово загружается как адрес обработчика сброса, причем бит 0 должен задавать состояние Thumb.
  • Загрузочные выводы, option bytes и remap определяют, какая физическая память видна по адресу 0x00000000, поэтому начальное чтение не обязано идти прямо с 0x08000000.
  • Затем обработчик сброса инициализирует память и частоты перед main, а позже прошивка может перенести таблицу через VTOR.

Зачем это спрашивают: Интервьюер проверяет, отличаете ли вы загрузочный alias Cortex-M от физического адреса flash STM32.

firmwaremcu

Прошивка должна настроить и стабилизировать источники частоты, прежде чем выбрать выход PLL на 72 МГц системной частотой.

  • Включить внешний генератор 8 МГц и дождаться его флага готовности, а не считать, что он запускается мгновенно.
  • Настроить множитель PLL на 8 МГц умножить на 9 и делители APB так, чтобы ни одна шина периферии не превысила допустимую частоту.
  • До повышения частоты ядра установить нужное для 72 МГц число тактов ожидания flash, иначе выборка инструкций может нарушиться.
  • Переключить источник системной частоты на PLL и по статусным битам проверить, что выбран нужный источник.

Зачем это спрашивают: Интервьюер проверяет знание того, что настройка частот выполняется в определенном порядке и учитывает ограничения flash и шин.

peripheralsconfig

Я бы включил тактирование порта C, настроил только PC13 как выход и управлял светодиодом через регистр установки и сброса GPIO.

  • Сначала нужно включить тактирование порта C и по справочному руководству найти конфигурационное поле PC13.
  • Затем очистить только четыре бита этого поля и выбрать двухтактный выход с невысокой скоростью, достаточной для светодиода.
  • Запись в половину сброса BSRR для PC13 включает светодиод, а запись в половину установки выключает его.
  • BSRR меняет один вывод без read-modify-write, способной затереть одновременное изменение других битов порта.

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

interruptsmcu

Нет, volatile делает обращения наблюдаемыми для компилятора, но не придает атомарность и не синхронизирует последовательность проверки и очистки.

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

Зачем это спрашивают: Интервьюер проверяет ключевое ограничение: volatile не обеспечивает ни атомарность, ни синхронизацию.

peripherals

Я бы очистил трехбитное поле маской, а затем вставил значение 101, сдвинутое в биты с 4 по 6.

  • Маска поля равна 0x7 со сдвигом влево на 4 и покрывает ровно биты 4, 5 и 6.
  • Один раз прочитать регистр, выполнить value &= ~mask, затем value |= (0x5 << 4) & mask.
  • Записать собранное значение обратно через volatile-определение 32-разрядного регистра от производителя.
  • Если аппаратура имеет отдельные регистры установки и очистки, при наличии одновременных писателей лучше использовать их вместо небезопасной read-modify-write.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы менять многобитное поле, не повреждая несвязанные состояния аппаратуры.

Я бы хранил каждый отсчет в uint16_t, а сумму 1000 отсчетов накапливал в uint32_t.

  • Двенадцать бит помещаются в uint16_t, тогда как uint8_t обрежет значения выше 255.
  • Максимальная сумма равна 4 095 000, что превышает максимум uint16_t, равный 65 535.
  • Аккумулятор uint32_t безопасно вмещает этот максимум и позволяет затем вычислить целочисленное среднее.
  • Типы фиксированной ширины явно закрепляют предположения о размере и диапазоне между компиляторами и семействами MCU.

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

mcu

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

  • Реальное число тактов определяют инструкции, переходы, такты ожидания flash и работа конвейера, а не только частота 48 МГц.
  • Оптимизация компилятора может сократить, переставить или полностью удалить пустой цикл задержки.
  • Прерывания могут приостановить цикл и непредсказуемо растянуть 10-микросекундный импульс.
  • Сравнение таймера или канал output compare отсчитывает такты периферии и может переключить вывод на заданном значении счетчика.

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

mcu

Регистр должен иметь тип uint32_t, потому что его аппаратная ширина всегда равна 32 битам независимо от модели данных компилятора.

  • Тип uint32_t при наличии занимает 32 бита, тогда как unsigned long на разных платформах бывает 32- или 64-разрядным.
  • Volatile-обращение неверной ширины может затронуть соседние адреса или породить неподдерживаемую транзакцию на шине.
  • Битовые маски вроде UINT32_C(1) << 31 тогда имеют известную ширину и предсказуемое поведение.
  • Статическая проверка размера типа регистра может рано обнаружить неподходящую конфигурацию сборки.

Зачем это спрашивают: Интервьюер проверяет понимание того, что размеры типов C нужно явно согласовывать с шириной аппаратных регистров.

mcudata-structures

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

  • Статическая память вместе с запланированным стеком уже занимает 20 КБ, оставляя 12 КБ до учета библиотек и стека прерываний.
  • Выделение 6 КБ оставляет мало запаса и может завершиться ошибкой или фрагментацией после разных последовательностей выделения.
  • Фиксированная рабочая область на 6 КБ с явным владельцем дает детерминированный расход памяти, если одновременно собирается только один пакет.
  • Оставшийся запас нужно подтвердить по карте линкера и измерению максимального использования стека, а не по номинальным 32 КБ.

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

peripherals

Внутри функции buffer является указателем, поэтому sizeof возвращает размер указателя, а не исходного массива на 64 байта.

  • При передаче в функцию аргумент-массив преобразуется в параметр-указатель.
  • На 32-разрядном Cortex-M sizeof(buffer) обычно равен 4, а не 64.
  • Нужно явно передавать емкость, например указатель вместе с length типа size_t, и проверять по ней все индексы.
  • Если функция действительно требует ровно 64 байта, интерфейс может использовать тип-обертку, который сохраняет контракт размера.

Зачем это спрашивают: Интервьюер проверяет понимание преобразования массива в указатель и безопасных интерфейсов для буферов.

callbacks

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

  • Те же байты стека могут быть повторно использованы другой функцией до запуска callback через 5 мс.
  • Чтение через устаревший указатель дает неопределенное поведение и может случайно работать только в некоторых сборках.
  • Буферу нужно дать статическое время жизни, разместить его в объекте с более долгой жизнью или скопировать нужные данные в хранилище callback.
  • Правило владения должно определять, кто может менять эти 32 байта, пока callback ожидает запуска.

Зачем это спрашивают: Интервьюер проверяет, умеете ли вы находить висячий указатель, возникший из-за времени жизни объекта на стеке.

firmwaremcu

Прошивка должна скопировать или собрать четыре байта в выровненный uint32_t, а не приводить buffer + 1 к указателю на uint32_t.

  • Адрес со смещением 1 не обязан удовлетворять требованию четырехбайтного выравнивания счетчика.
  • Прямое приведение может вызвать fault на целевой платформе и нарушает правила C об aliasing или представлении объектов.
  • memcpy в выровненный uint32_t понятен, а компиляторы обычно эффективно оптимизируют фиксированное копирование четырех байтов.
  • После копирования нужно декодировать заданный порядок байтов, потому что выравнивание и endianness являются разными вопросами.

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

peripheralsmcu

В пакет UART нужно сначала отправить 0x12, затем 0x34, потому что сетевой порядок байтов является big-endian.

  • Little-endian описывает размещение 0x1234 в памяти MCU, обычно 0x34, а затем 0x12 по возрастающим адресам.
  • Протокол на линии задает собственный порядок байтов и не должен зависеть от размещения данных в памяти процессора.
  • Старший байт кодируется через value >> 8, а младший через value & 0xFF.
  • Тест приемника со значением 0x1234 хорошо выявляет случайную сериализацию в порядке байтов хоста.

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

mcu

Я бы ожидал padding и проверил размер через sizeof, а не считал, что три поля суммарно занимают 7 байтов.

  • Компилятор обычно добавляет три байта перед timestamp, чтобы uint32_t начинался на границе четырех байтов.
  • Он также может добавить два байта в конец, чтобы элементы массива структур сохраняли нужное выравнивание, и тогда размер будет 12 байтов.
  • Перестановка полей в порядке uint32_t, uint16_t, uint8_t может уменьшить типичный размер до 8 байтов без упакованных обращений.
  • Для формата на линии или во flash поля нужно сериализовать явно, потому что раскладка компилятора не является стабильным протоколом.

Зачем это спрашивают: Интервьюер проверяет понимание padding структуры из-за выравнивания и отказ от использования нативной раскладки как формата.

types

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

  • const документирует, что 256 байтов доступны только для чтения после сборки образа прошивки.
  • Типичный embedded-линкер может оставить такие данные во flash, не копируя их при запуске в дефицитную RAM.
  • Параметр типа const uint8_t * разрешает чтение через указатель, но запрещает запись через этот интерфейс.
  • Размещение все равно зависит от скрипта линкера и toolchain, поэтому карта должна подтвердить отсутствие копии в RAM.

Зачем это спрашивают: Интервьюер оценивает и корректное применение const, и его практическую связь с расходом flash и RAM.

peripheralstyping

Я бы жестко соблюдал протокольный максимум 48 байтов и резервировал еще один байт под конец строки.

  • Перед записью полезного байта нужно проверять, что текущая длина меньше 48, а не считать физическую емкость буфера новым лимитом протокола.
  • После полной команды длиной от 0 до 48 байтов нулевой терминатор записывается в buffer[length], поэтому максимальная строка занимает 49 байтов.
  • При получении 49-го полезного байта нужно отбрасывать данные до разделителя кадра, а не принимать команду вне протокола.
  • Явный статус превышения длины не позволит парсеру принять обрезанный префикс за корректную команду.

Зачем это спрашивают: Интервьюер проверяет, отделяете ли вы лимит протокола от емкости хранилища и места под терминатор.

resiliencefirmwaremcu

Нужно использовать беззнаковое вычитание и сравнивать прошедшую разницу с 500, а не сравнивать абсолютные метки времени.

  • Сохранить start как uint32_t и проверять (uint32_t)(now - start) >= 500.
  • Беззнаковая арифметика работает по модулю 2^32, поэтому разность остается корректной при одном переполнении счетчика.
  • Шаблон безопасен, когда измеряемый интервал меньше половины диапазона счетчика, чему 500 мс явно соответствует.
  • Тест со start около 0xFFFFFFF0 и now после нуля должен проверить граничный случай.

Зачем это спрашивают: Интервьюер оценивает, правильно ли вы используете определенное стандартом переполнение беззнаковых чисел для embedded-таймеров.

Парсер должен проверить, что count не превышает SIZE_MAX, деленное на 12, и что получившиеся 72 000 байтов помещаются в реальный бюджет буфера.

  • Умножение нужно проверить до выполнения в типе размера, иначе переполненное малое значение приведет к выделению слишком маленького блока.
  • Даже без арифметического переполнения 72 000 байтов превышают всю RAM MCU объемом 64 КБ, поэтому значение нужно отклонить.
  • Преобразовывать недоверенное значение count в size_t следует только после проверки его допустимого диапазона по протоколу.
  • Один и тот же проверенный размер в байтах должен ограничивать и выделение, и последующий цикл обработки элементов.

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

Закрытые вопросы

  • 21

    PB5 переназначили на альтернативную функцию UART, после чего записи для светодиода на этом выводе перестали менять напряжение; как найти причину и безопасно вернуть вывод в режим GPIO?

    peripherals
  • 22

    Кнопка соединяет PA0 с землей и читается каждую 1 мс на плате Cortex-M0+ с напряжением 3,3 В; зачем входу pull-up и какие значения должна видеть прошивка?

    firmwaremcu
  • 23

    Механическая кнопка опрашивается каждые 5 мс и может дребезжать 12 мс; как отфильтровать ее с интервалом стабильности около 20 мс?

    debounce
  • 24

    Таймер общего назначения получает частоту 48 МГц и должен вызывать прерывание каждую 1 мс; приведите допустимую пару prescaler и auto-reload и объясните правило минус единица.

    interrupts
  • 25

    Таймер на 48 МГц должен генерировать PWM с частотой 20 кГц и коэффициентом заполнения 25 процентов для вентилятора; какие значения периода и сравнения вы выберете?

  • 26

    12-битный ADC использует опорное напряжение 3,3 В и возвращает код 2048; какому входному напряжению это примерно соответствует и какие предположения влияют на результат?

  • 27

    12-битный ADC должен измерять сигнал датчика с частотой 200 Гц на MCU с частотой 64 МГц; разумна ли частота выборки 1 кГц и какой простой буфер выделить для 100 мс данных?

  • 28

    Кнопка на EXTI0 из-за дребезга вызывает десять прерываний за 3 мс на Cortex-M0+ с частотой 48 МГц; что должен делать обработчик и где выполнять debounce длительностью 20 мс?

    interruptsmcudebounce
  • 29

    На Cortex-M4 прерыванию ADC с частотой 10 кГц назначен приоритет NVIC 2, а прерыванию UART на 115200 бод приоритет 5; у какого выше срочность и что произойдет, если оба ожидают одновременно?

    interruptsperipheralsmcu
  • 30

    Windowed watchdog принимает обновление только через 200-400 мс после предыдущего, а исправный superloop выполняется каждые 100 мс; как собрать признаки здоровья и выбрать момент обновления?

    firmwarereliabilityaggregation
  • 31

    Сколько времени один байт занимает на линии UART при 115200 бод и формате 8N1 и какова примерная максимальная скорость полезных данных?

    peripheralsconfig
  • 32

    MCU на 48 МГц отправляет UART на 115200 бод в формате 8N1, а приемник настроен на 9600 8E1; почему он будет сообщать об ошибках кадра или четности?

    peripheralsconfig
  • 33

    Два устройства на 3,3 В используют общую шину I2C 400 кГц с дорожками длиной 10 см; почему SDA и SCL работают с открытым стоком и зачем каждой линии нужен подтягивающий резистор?

    peripherals
  • 34

    Датчик температуры имеет 7-битный I2C-адрес 0x48 и регистр 0x00; опишите транзакцию на 400 кГц, которая читает два байта данных и включает решения об ACK.

    transactionsperipherals
  • 35

    Шина I2C на 400 кГц имеет полную емкость около 150 пФ и медленные фронты с подтяжкой 10 кОм; почему 4,7 кОм тоже может не хватить и какое значение попробовать на плате 3,3 В?

    peripherals
  • 36

    SPI-датчик требует mode 3, частоту не выше 8 МГц и низкий chip-select на протяжении передачи 3 байтов; как настроить и выполнить транзакцию на MCU с частотой 48 МГц?

    evmtransactionsconfig
  • 37

    Во время полнодуплексной передачи 4 байтов по SPI на 4 МГц MCU хочет только отправить команду; почему он все равно должен обработать принятые байты и как узнать, приняла ли периферия команду?

    peripheralsevm
  • 38

    Два узла одновременно начинают передавать стандартные CAN-кадры на 500 кбит/с с идентификаторами 0x120 и 0x080; какой кадр выиграет арбитраж и что произойдет со вторым узлом?

  • 39

    Стандартный CAN-кадр данных на 500 кбит/с несет идентификатор 0x321 и DLC 8; для чего нужны идентификатор, DLC, CRC и поле ACK?

  • 40

    На плате 3,3 В находятся четыре датчика температуры, каждый выдает 2 байта с частотой 10 Гц по дорожкам длиной 15 см, а MCU имеет одну I2C на 400 кГц и одну SPI на 8 МГц; какой протокол выбрать?

    peripheralstypingevm
  • 41

    Bare-metal MCU с частотой 48 МГц должен читать кнопку каждую 1 мс, обновлять светодиод каждые 10 мс и отправлять статус каждые 100 мс; как организовать superloop без блокирующих задержек?

    bare-metal
  • 42

    Датчику нужно 50 мс на преобразование, а передача его отчета из 12 байтов по UART занимает около 1,1 мс при 115200 8N1; спроектируйте простой автомат состояний IDLE, MEASURING и REPORTING для цикла 100 мс.

    designperipherals
  • 43

    Вход статуса создает одно событие в секунду, но минимальная ширина импульса неизвестна, а UART принимает пакеты по 64 байта на 115200 бод; какие сигналы можно безопасно опрашивать?

    peripherals
  • 44

    Обработчик UART получает один байт каждые 86,8 микросекунды при 115200 8N1, а основной цикл может остановиться на 5 мс; как будет работать кольцевой буфер на 128 байтов?

    interruptsperipherals
  • 45

    Карта линкера для MCU со 128 КБ flash показывает 72 КБ .text, 10 КБ .rodata и 4 КБ загрузочного образа .data во flash; сколько flash остается и что проверить дальше?

  • 46

    Карта MCU с 32 КБ RAM показывает 4 КБ .data, 12 КБ .bss, зарезервированный стек 6 КБ и кучу 2 КБ; какой запас RAM остается?

    cssdata-structures
  • 47

    После сброса образ Cortex-M имеет 2 КБ инициализированной .data и 6 КБ .bss в 32 КБ RAM; что аппаратура делает до обработчика сброса и что startup-код внутри него выполняет перед main?

    mcu
  • 48

    Вы меняете UART платы на 48 МГц со скорости 9600 на 115200 бод и правите три определения регистров; какой базовый Git-процесс использовать перед отправкой на review?

    zero-to-onegitperipherals
  • 49

    Сборка для Cortex-M4 на 64 МГц предупреждает, что 12-битное значение ADC типа uint16_t преобразуется в uint8_t перед передачей; как обработать предупреждение при -Wall -Wextra -Wconversion?

    mcu
  • 50

    12-битный ADC с опорным напряжением 3300 мВ передает данные в расчет температуры каждые 100 мс; где провести границу unit-теста, чтобы тестам не требовалась аппаратура Cortex-M?

    hypothesis-testingtestingmcu
  • 51

    Сигналы A и B квадратурного энкодера создают 4000 фронтов в секунду и иногда дают недопустимые переходы; как надежно считать направление?

  • 52

    На таймер поступает тактовая частота 1 МГц, а LED должен завершать один цикл включения и выключения каждые 500 мс. Какой период таймера нужен, если ISR переключает LED?

    interrupts
  • 53

    Цифровой вход получает высокий импульс длительностью 37 мкс; как измерить его через input capture свободно работающего таймера на 1 МГц?

  • 54

    LED с активным низким уровнем подключен к PWM-пину, но при значении сравнения 75% его яркость выглядит примерно как 25%. Что вы проверите?

  • 55

    12-битный ADC постоянно занижает показания датчика с выходным сопротивлением около 100 кОм при самом коротком времени выборки; что нужно изменить?

  • 56

    Стабильный датчик измеряется 12-битным ADC с частотой 10 тысяч выборок в секунду, но коды скачут в диапазоне 20 отсчетов. Как исследовать и уменьшить шум?

  • 57

    Свободно работающий 16-битный таймер тикает с частотой 1 МГц, но прошивке нужно измерять интервалы в несколько секунд; как расширить и безопасно читать такой таймер?

    firmware
  • 58

    GPIO на кабеле длиной 2 м дребезжит в шумной установке, хотя прошивка включает логическую подтяжку вверх; как сделать вход надежным?

    firmwareperipherals
  • 59

    Красный LED с резистором 330 Ом должен управляться от 3,3 В, но настроенный высокий GPIO показывает только 0,2 В. Какие безопасные проверки вы сделаете?

    peripheralsconfig
  • 60

    Плата печатает нечитаемый текст по UART, логический анализатор измеряет длительность каждого бита около 8,68 микросекунды, а терминал настроен на 9600 бод. В чем ошибка?

    peripherals
  • 61

    Обе платы используют 57600 бод, но приемник сообщает об ошибках кадра во многих байтах. Анализатор показывает дополнительный бит четности перед стоп-битом. Что нужно изменить?

  • 62

    I2C-анализатор показывает адресные биты и 9 импульсов SCL, но SDA остается высокой на 9-м импульсе, а MCU сообщает об отсутствии подтверждения. Что вы проверите?

    peripherals
  • 63

    В datasheet датчика указаны 0xD0 для записи и 0xD1 для чтения, но API MCU ожидает 7-битный I2C-адрес. Какое значение должен передать драйвер?

    peripheralsapi
  • 64

    После reset MCU во время передачи на 400 кГц SDA остается низкой при высокой SCL, и I2C-периферия не может начать работу. Как безопасно восстановить маленькую плату?

    peripherals
  • 65

    SPI-датчик возвращает сдвинутые и непостоянные байты на 2 МГц. Его datasheet требует CPOL 1 и CPHA 1, а анализатор правильно декодирует только в режиме 3. Что вы сделаете?

    evmperipherals
  • 66

    Два SPI-устройства совместно используют MISO, и линия держится около 1,4 В, когда оба chip-select случайно активны. Какова вероятная неисправность и безопасное исправление?

    evmperipherals
  • 67

    Прошивка отправляет SPI-байт 0x96, но периферийное устройство интерпретирует 0x69. Clock mode и chip select выглядят правильно. Что проверить дальше?

    firmwareperipheralsevm
  • 68

    На CAN-шине 500 кбит/с установлены три терминатора по 120 Ом, и часто появляются error frame. Какое сопротивление ожидается между CAN_H и CAN_L при выключенном питании?

    peripherals
  • 69

    После повторных ошибок передачи CAN-узел переходит из error-active в error-passive, а затем в bus-off; что означают эти состояния и как искать причину?

  • 70

    Протокол на скорости 115200 бод разрешает ровно один кадр на 100 байтов до обслуживания приемника; какова минимальная полезная емкость буфера и когда пауза 20 мс требует больше памяти?

    capacitytyping
  • 71

    Таймерное прерывание частотой 1 кГц выполняет вычисление длительностью 2 мс, и другие прерывания теряются. Что нужно изменить?

    interrupts
  • 72

    На 8-битном MCU ISR увеличивает 16-битный счетчик выборок, а main loop его читает. Иногда main loop видит невозможное значение. Почему?

    interrupts
  • 73

    UART idle-line разделяет кадры переменной длины от 20 до 200 байтов, которые принимает циклический DMA; как находить границы кадров и не терять данные при переходе через конец буфера?

    peripherals
  • 74

    Двоичный кадр начинается возле конца кольцевого буфера на 128 байтов и продолжается с индекса ноль; как разобрать и проверить его без предположения о непрерывной памяти?

    indexesvalidationmemory
  • 75

    ADC измеряет 10 тысяч выборок в секунду в циклический DMA-буфер на 200 значений. Когда должны происходить half-transfer и full-transfer callbacks и как их использовать?

    peripheralscallbacks
  • 76

    12-битный ADC пишет в массив uint16_t, но DMA настроен на 32-битную ширину периферии и памяти, и в буфере на 100 выборок появляются пропуски. Что исправить?

    peripheralsconfigmemory
  • 77

    ISR заполняет буфер пакета на 32 байта и устанавливает ready, но main loop иногда читает пакет из байтов двух кадров. Как безопасно передать данные?

    interrupts
  • 78

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

    firmwareinterruptsperipherals
  • 79

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

  • 80

    Конфигурационная переменная неожиданно изменяется примерно раз в 3 секунды. Как поможет watchpoint в JTAG или GDB?

    configdebugging
  • 81

    Плата на Cortex-M4 входит в HardFault через 30 секунд. Какие значения из exception stack frame вы сохраните сначала и что они покажут?

    mcuerror-handling
  • 82

    Прошивка доходит до assert(state == READY), потому что после команды состояние осталось IDLE; как через GDB найти неверный переход?

    firmware
  • 83

    Обработчик HardFault на Cortex-M работает через MSP, но прерванная задача могла использовать PSP; как найти автоматически сохраненный exception frame?

    interruptsmcuerror-handling
  • 84

    В отчете о сбое есть PC 0x0800432A, но у вас только map-файл и ELF от вчерашней сборки. Как надежно найти исходный код?

  • 85

    SWD подключается после reset, но отключается примерно через 50 мс, когда новая прошивка входит в sleep и перенастраивает пины. Как вернуть управление?

    firmware
  • 86

    I2C-датчик возвращает неправильное значение, но логический анализатор показывает адрес 0x48, регистр 0x01, ACK и два ожидаемых байта данных. Что исследовать дальше?

    peripherals
  • 87

    SPI работает на 1 МГц, но ломается на 12 МГц. Логический анализатор декодирует чисто, а осциллограф у приемника показывает фронт около 30 нс и сильный ringing. Что делать?

    evmperipherals
  • 88

    UART надежен через перемычку 10 см, но повреждает данные через кабель 1 м на 115200 бод. Как разделить ошибку прошивки и физического канала?

    firmwareperipherals
  • 89

    Функция объявляет локальный массив на 512 байтов и работает в задаче со стеком 1 КиБ. Чем это опасно и что изменить?

  • 90

    Embedded heap на 8 КиБ получает случайные выделения от 20 до 200 байтов и освобождает их в другом порядке. Через несколько часов выделение 300 байтов не удается, хотя свободно 2 КиБ. Что произошло?

    embeddeddata-structures
  • 91

    После одного commit прошивка выросла на 14 КиБ, хотя новая функция выглядит небольшой; как найти причину и не допустить следующего сюрприза с размером?

    firmware
  • 92

    Стек на 2 КиБ заполнен 0xA5 при запуске, и после стресс-теста 600 байтов в нижней части остались нетронутыми. Что показывает watermark?

  • 93

    Компилятор предупреждает, что индекс 10 выходит за границы int values[10] в цикле с условием i <= 10. Что нужно сделать?

  • 94

    Локальная переменная состояния функции читается до присваивания, и плата запускается в разных режимах при 20 повторных reset. Как исправить и проверить это?

  • 95

    Сборка для MCU с SRAM 32 КиБ падает после добавления debug-буфера 8 КиБ; теперь map сообщает 40 КиБ .bss. Что делать?

  • 96

    Задача FreeRTOS должна запускаться каждые 100 мс, но между запусками она крутится в busy wait и лишает времени низкоприоритетную задачу логирования. Что нужно использовать?

    rtoslogging
  • 97

    GPIO ISR должен отправить событие в очередь FreeRTOS на 8 элементов, которую ждет задача с более высоким приоритетом. Какой API и какое поведение yield нужны?

    rtosinterruptsperipherals
  • 98

    Разработчик передает 256 как stack depth в xTaskCreate и документирует это как 256 байтов. Почему это может быть неверно?

  • 99

    Плата на батарее должна просыпаться от RTC каждые 5 секунд и потреблять 10 микроампер во сне, но мультиметр постоянно показывает 2 мА. Как это отлаживать?

  • 100

    Watchdog с таймаутом 1 секунда кормится из timer ISR, поэтому плата не перезапускается при deadlock в main loop. Кто должен владеть кормлением watchdog?

    interruptsreliabilitylocking