Это список вопросов на которые должен уметь ответить тот кто программирует микроконтроллеры и заниматься разработкой электроники. Вопросы в частности взяты из технических собеседований при устройстве на работу в разные компании. Постарался отобрать только самые приближенные к практике вопросы, которые можно выделить после 10 лет InSider(ского) опыта. Тут не будет моветонных вопросов из серии «как инвертировать связанный список». Тут всё исключительно только по делу.
По коду
—Зачем static?
—Зачем ключевое слово volatile C
—Может ли быть const volitile?
—Зачем ключевое слово register?
—Зачем ключевое слово restrict?
—Зачем ключевое слово weak?
—Как проверить, что в числе установлен/сброшен бит?
—Как проверить, что два float числа равны между собой?
—В какую память попадет глобальная переменная с ключевым словом const?
—Какие есть способы передачи переменных в С функцию?
—Есть ли способ запустить С-код до запуска main?
—Какое значение в локальной static переменной при первом вызове?
—Зачем нужен оператор препроцессора ##?
—Может ли С функция во время исполнения определить, что ее вызвали рекурсивно?
—Может ли C функция с переменным числом аргументов узнать сколько у нее аргументов?
—Назови три способов вернуть массив из функции.
—Зачем используют do{…} while(0); если это всего лишь 1 итерация?
—Зачем нужен extern «C» ?
—Чему равен размер структур?
struct Foo { int iiii; char c; }; struct record { char tag; unsigned index; char has_extra_data; char has_value; int value; };
—Чему равен val? Значение необходимо указать исходя из типа памяти little endian и проще выразить в hex формате
uint16_t arr[4] = {0x04,0x03,0x02,0x01}; uint32_t val; val = *((uint32_t*) (&arr[1])); printf("val=%08x \n", val);
—Что вернет код?
static char *val_2_str(int i){ static char buff[10]; snprintf(buff,sizeof(buff)," %d ",i); return buff; } printf("\n%s %s",val_2_str(3),val_2_str(4));
Какой код выполняется быстрее
void inc_matrix_ji(void) { int i=0,j=0; for(j=0; j<NN; j++){ for(i=0; i<NN; i++){ Amatrix[i][j]++; } } } void inc_matrix_ij(void) { int i=0,j=0; for(i=0;i<NN;i++){ for(j=0;j<NN;j++){ Amatrix[i][j]++; } } }
Структуры данных
—Чем циклический буфер отличается от FIFO?
—Как удалить элемент из связанного списка не зная указателя не предыдущий элемент?
Про DevOps
—Зачем собирать из скриптов, если всегда можно мышкой щелкнуть на зеленый треугольник в IDE?
—Зачем нужен сервер сборки?
—Какие файлы следует подвергать версионному контролю?
—Что для тебя значит рефакторинг?
Прерывания
—Что такое прерывание?
—Что такое реентабельная функция?
—что такое таблица прерываний?
—Каков алгоритм обработки прерываний? Что происходит во время срабатывания прерывания?
—что такое вектор прерываний?
—Какие есть внутренние прерывания?
—Как регистр PC узнает куда возвращаться после обработки прерывания?
Про ToolChain
—Как проверить что .c или .h файл вообще собирается?
—Какой путь проходит код с момента написания до попадания в flash память?
—Что такое ABI (application binary interface)?
—На какие сегменты разбита память прошивки?
—Какие доки нужны для того, чтобы программировать встраиваемый софт?
—Компилятору дали 5*. с файлов и 20*. h файлов. Сколько будет*. o файлов?
—Тебе предоставили файл *.с чрезвычайно запутанный препроцессором. Как ты поймешь, что там происходит и в какой последовательности?
—Что такое binutils? Какие знаете? Что можно с ними сделать?
—Какие файлы являются результатом работы разработчика MCU (артефакты)?
Вопросы про RTOS
—Зачем нужны программные прерывания? Можно ведь просто функцию вызвать.
—что такое гонки в программах?
—Что такое bit-banding и зачем нужен bit-banding?
—Что такое контекст потока?
—Что такое spinlock?
—Что такое deadlock?
—Что такое preemptive многозадачность?
—Что такое критическая секция?
—Что такое мьютекс?
—Что такое семафор?
—Что такое поток?
—Пример атомарной операции?
—Все ли в порядке в этом многопоточном коде?
DataA a; DataB b; DataC c; mutex ma, mb, mc; void TaskA(){ lock(ma); lock(mb); // use a, b unlock(mb); unlock(ma); } void TaskB(){ lock(mb); lock(mc); lock(ma); // use a, b, c unlock(ma); unlock(mb); unlock(mc); } void TaskC(){ lock(mc); // use c unlock(mc); }
—Что такое инверсия приоритетов?
—Как бороться с инверсией приоритетов?
—В стеке какого потока работают прерывания?
—Что значит thread-safe код?
—В чем разница между мьютекксом и семафором?
—Что такое Reentrancy?
—В чем разница между Joined и Detached потоками?
—Написать функцию атомарного обмена содержимого переменных.
—Что такое атомарные операции?
—Как измерить процент загрузки MCU в прошивке без ОС?
Про железо
—Как на 10MHz(цовом) микроконтроллере можно измерить частоту примерно 100MHz прямоугольного сигнала с GPIO?
—Что такое PUSH-PULL а что OPEN-DRAIN?
—На одной SPI шине 2 Slave чипа. На оба подали одновременно Chip Select 0V и начали вычитывать регистры в которых разные данные. Что будет? Сгорит/не сгорит?
—Какие есть регистры у Cortex M3 и для чего они нужны?
—Что значит суперскалярный микропроцессор?
—Почему частота часового кварца именно 32768 Hz?
—Есть два Lin интерфейса. У одного подтяжка к 24V у другого подтяжка к 12V. Их соединили. Что будет? Сгорит /не сгорит?
—Что нужно сделать программе с микроконтроллером, чтобы моргать светодиодом? Напишите словами каждый шаг.
—Как проверить, что 2 прямоугольных сигнала на 2х GPIO синфазные?
—Как сделать проверку-защиту, что firmware в самом деле предназначено именно для этой платы?
—По какому интерфейсу код взаимодействует с железом (ядром микроконтроллера)?
—Что такое scatter/gather IO?
—В чем отличие ARM от PowerPC?
—Что происходит с микроконтроллером между подачей питания и запуском функции main()?
—Какие виды памяти есть в микроконтроллере.
—На какие части обычно делится Flash память?
—На какие части делится RAM память?
—В чем достоинство цифровых фильтров в отличие от аналоговых?
—Как обрабатывать кнопку? Как преодолевать дребезг контактов?
—Зачем нужен препроцессорный #error?
По интерфейсам
—Какое напряжение на UART TX в режиме idle?
—Зачем UART опция 2 стоповых бита, если это уменьшает data rate?
По протоколам
—В каких протоколах у переменных big endian, а в каких протоколах у переменных little endian?
—Зачем в TCP контрольная сумма если контрольная сумма есть в Ethernet пакете?
—Зачем нужен IP-адрес, если есть MAC-адрес?
—Почему CRC часто в конце пакета, а не в заголовке?
Вопросы про стек
—Что хранится в стековой памяти?
—Что такое стековый кадр? И что в нем хранится?
—Какой код копирует в стек адрес возврата?
—Какой код копирует из стека адрес возврата из функции для регистра программного счетчика?
—Кто инициализирует локальные переменные если их не проинициализирован явно ?
—В какую сторону растет стек?
—Сколько указателей стека в ARM Cortex-M4?
—Что определяет в каком направлении будет расти стековая RAM память?
—Какое значение в локальной переменной если ничего не присвоено при создании?
—Что произойдет при переполнении стека?
—Как определить на какую максимальную глубину заполнялась стековая память с момента запуска программы?
—Все ли в порядке с функцией?
int8_t* foo(void) { int8_t val=-5; return (&val); }
Беспроводные интерфейсы
—Как определить что передатчик в самом деле передает что-то?
—Нет радио Link(а) (например в LoRa). Как выявить в чем дело? Передатчик не передает или приемник не принимает?
Про heap память
—Как определить размер блока выделенного malloc?
—Как бороться с фрагментацией памяти?
—Как проверить сколько памяти выделено в куче в случайном месте программы?
Про загрузчики
—Как загрузчик может обмениваться данными с приложением?
—В чем опасность вызова функций загрузчика из приложения?
—Как защитить микроконтроллер от загрузки чужеродного кода через загрузчик?
—Как понять, что загрузчик принял в самом деле прошивку, а не набор случайных циферок с правильной CRC?
—Можно ли сделать так, чтобы загрузчик стартовал не с адреса начала Main Flash 0x0800_0000, а например с адреса 0x0806_0000?
—Почему в микроконтроллерах STM32 секторы разных размеров?
Решение проблем (TroubleShooting)
—Тебе дали дорогую плату запрограммировать прямо с производства. Плату ещё ни разу не включали в питание. Крайне вероятно, что плата сгорит при первом же включении из-за брака монтажа. Как ты проверишь плату не испортив ценный полуфабрикат?
—Прошивка зависла, ваши действия?
—Какие утечки вы знаете кроме утечки памяти?
—Прошивка после подачи питания постоянно и непрерывно перезагружается. Как вы станете это ремонтировать?
—Ты пишешь код, собираешь, запускаешь и вдруг прошивка перезагружается. Твои действия?
—Как отладить большой кусок кода, если нет возможности пройти JTAG/SWD отладчиком?
Вопросы для развернутого устного ответа
—Как можно реализовать энергонезависимую Key-Val map на микроконтроллере?
Вопросы для проверки навыков пользования компьютером
—Есть текстовый файл-лог размером 50Mbyte. Строки с ошибками обозначены как [E]. Как узнать есть ли в логе ошибки и сколько их?
—Диск переполнился. Комп тормозит. Как быстро выяснить размер каждой папки?
—Как рекурсивно удалить все файлы расширения *.bak?
—Как отобразить все 3-буквенные слова в текстовом файле?
—Напиши bash команду, которая ищет во всех файлах папки проекта макрос с под именем «LED» только в файлах board.h
Вопросы со звездочкой *
—Как измерить покрытие микроконтроллерного кода после отработки модульных тестов?
—Опиши как работает JTAG под капотом (установка точки останова).
—Почему на некоторых MCU RAM память не является непрерывной, а разделена на несколько отдельный непрерывных диапазонов адресов?
—Как узнать время сборки каждого *.с файла?
—Как рассчитать CRC на стадии компиляции, чтобы положить результат в константный массив?
—Как добавить еще одну отладочную кнопку, если все уже пины заняты.
Вопросы на способность тестирования и отладки
—Какие существуют способы отлаживать прошивки? Назовите как минимум пять способов.
—Какой самый сложный программный или аппаратный баг приходилось искать и починить?
—Как перезагрузить прошивку? Перечислите как можно больше способов. Минимум 3 способа.
—Сколько способов подключить 4 провода к 8 ми клеммникам?
—Как избежать чрезмерного, избыточного количества модульных тестов?
—Как проверить, что инфракрасный передатчик IR в самом деле излучает хоть что-то?
—Как проверить, что два массива это перестановка одних и тех же чисел?
Варианты для тестового задания дома
—Напишите функцию для вычисления угла между 2D векторами с учетом знака (правая тройка).
—Напишите функцию, которая вычисляет PWM sample.
double pwm_sample_calc(uint64_t time_us, double freq, double cur_phase_ms, double des_amplitude, double duty_cycle, double offset);
—Напишите прошивку под STM32F4, которая генерирует на GPIO два аппаратных PWM с возможностью менять фазу, частоту, скважность через UART в run-time.
—Напишите энергонезависимую FlashFS для STM32F микроконтроллера. Предусмотрите endurance optimization и защиту данных от пропадания питания.
—Даны две GNSS координаты. Вычислить азимут в градусах. Покрыть тестами.
—Напишите минималистичную прошивку STM32 загрузчика (MBR), которая только прыгает в определенный адрес (например 0x08016000), чтобы запустить приложение. Постарайтесь уместить *.bin файл в 1kByte.
Если вы знаете адекватные, сложные и интересные вопросы по теме разработки на MCU то пишите их в комментариях.
ссылка на оригинал статьи https://habr.com/ru/post/676076/
Добавить комментарий