Pull to refresh

Коллоквиум по программированию микроконтроллеров

Level of difficultyHard
Reading time13 min
Views16K

Это список вопросов для тех кто числится программистом микроконтроллеров и занимается разработкой электроники. Вопросы в частности взяты из технических собеседований при устройстве на работу в разные реальные компании. Постарался отобрать только самые приближенные к практике вопросы, которые можно выделить после 10 лет InSider(ского) опыта. Тут не будет моветонных вопросов из серии "как инвертировать связанный список". Тут представлен обогащенный концентрат. Всё исключительно и только по делу.

По коду

1--Зачем static?

2--Зачем ключевое слово volatile C

3--Всё ли в порядке с кодом?

int square(volatile int *ptr) {
    return *ptr * *ptr;
}

4--Может ли быть const volatile?

5--Зачем ключевое слово register?

6--Зачем ключевое слово restrict?

7--Зачем ключевое слово weak?

8--Зачем в С(ях) нужны битовые поля?

9--Зачем в С(ях) нужны объединения?

10--Как проверить, что в числе установлен/сброшен бит?

11--Как проверить, что два float числа равны между собой?

12--В какую память попадет глобальная переменная с ключевым словом const?

13--Какие есть способы передачи переменных в С функцию?

14--Есть ли способ запустить С-код до запуска main?

15--Что произойдет при компиляции этого участка кода?

const int MAX=100;
#if 100==MAX
#error "MAX:100"
#endif

int main(){
   printf("MAX:%d",MAX);
   return 0;
}

16--Зачем нужен препроцессорный #error?

17--Какое значение в локальной static переменной при первом вызове?

18--В чем недостаток inline функций?

19--Зачем нужен оператор препроцессора ##?

20--Как делать примитивы инкапсуляции в C?

21--Какие знаешь адекватные правила MISRA 2004 или MISRA 2012?

22--Как делать примитивы полиморфизма в С?

23--Напишите функцию, которая при передаче по аргументу значения 1 печатает "One". При передаче 2 печатает "Two". Запрещено использовать оператор if и оператор switch.

24--Может ли С функция во время исполнения определить, что ее вызвали рекурсивно?

25--Может ли C функция с переменным числом аргументов узнать сколько у нее аргументов?

26--Назови три способа вернуть массив из функции.

27--Зачем используют do{...} while(0); если это всего лишь 1 итерация?

28--Зачем нужен extern "C" ?

29--Напишете одной строчкой установку значения 0x11223344 по абсолютному адресу 0x20000016.

30--Что напечатается на экран?


int main() {
    char str5[]={'s','t','r','i','n','g'};
    printf("\n5 %s size: %d len:%d",str5, sizeof(str5), strlen(str5));
  
    char *str1="string";
    printf("\n1 %s size: %d len:%d",str1, sizeof(str1), strlen(str1));
  
    const char *str2="string";
    printf("\n2 %s size: %d len:%d",str2, sizeof(str2), strlen(str2));
  
    char str3[]="string";
    printf("\n3 %s size: %d len:%d",str3, sizeof(str3), strlen(str3));
  
    char str4[10]="string";
    printf("\n4 %s size: %d len:%d",str4, sizeof(str4), strlen(str4));
  
    char *str6=strdup("string");
    printf("\n6 %s size: %d len:%d",str6, sizeof(str6), strlen(str6));
  
    char *str7=(char[]){"string"};
    printf("\n7 %s size: %d len:%d",str7, sizeof(str7), strlen(str7)); 
    return 0;
}

31--В чём разница между этими двумя прототипами?

uint16_t calc_crc16(uint8_t *inData, uint16_t const len); 
uint16_t calc_crc16(uint8_t inData[], uint16_t const len); 

32--Чему равен размер структур?

struct Foo {
    int iiii;
    char c;
};

struct record {
    char tag;
    unsigned index;
    char has_extra_data;
    char has_value;
    int value;
};

33--Как упаковать структуру в компиляторе GCC?

34--Зачем нужны упакованный структуры кроме экономии RAM памяти?

35--Что напечатается в консоли при отработке функции

typedef struct{
	int a:1;
	int b;
}ab_t;

int main(void) {
    ab_t ab;
    ab.a = 1;
    printf("%u" CRLF, ab.a);
    return 0;
}

36--Чему равен 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);

37--Что вернет код?

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));

38--Какой код выполняется быстрее: первый или второй?

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]++;
       }
    }
}

39-- Есть константный Си-массив структур, который формируется препроцессором (cpp.еxe) до компиляции gcc из разных файлов проекта. Как проверить во время компиляции (до исполнения кода), что в финальном массиве структур нет повторяющихся элементов?

Структуры данных

1--Чем циклический буфер отличается от FIFO?

2--Как удалить элемент из связанного списка не зная указателя не предыдущий элемент?

Про DevOps

1--Зачем собирать из скриптов, если всегда можно мышкой щелкнуть на зеленый треугольник в GUI-IDE?

2--Зачем нужны все эти сервера сборки типа Jenkins(а)?

3--Какие файлы следует подвергать версионному контролю в GIT?

4--Что для тебя значит рефакторинг? Что ты подразумеваешь под словом рефакторинг?

Про прерывания

1--Что такое прерывание?

2--Зачем нужны программные прерывания? Можно ведь просто функцию вызвать.

3--Что такое реентерабельная функция?

4--Сколько тактов процессора нужно для запуска возникшего прерывания на Cortex-M4?

5--Сколько тактов процессора нужно для вызова функции?

6--что такое таблица прерываний?

7--Каков алгоритм обработки прерываний? Что происходит во время срабатывания прерывания?

8--что такое вектор прерываний?

9--Какие есть внутренние прерывания?

10--Как регистр программного счетчика PC узнает куда возвращаться после обработки прерывания?

Про ToolChain

1--Как проверить что конкретный *.c или *.h файл вообще собирается?

2--Какой путь проходит Си-код с момента написания до попадания во flash память?

3--Как отключить/подавить какое-либо отдельное предупреждение компилятора GCC (например -Wrestrict)?

4--Компоновщик пишет, что прошивка не собирается из-за нехватки on-chip NOR-Flash памяти. Какие меры ты предпримешь, чтобы утрамбовать прошивку?

5--Что такое ABI (application binary interface)?

6--На какие сегменты разбита вся память прошивки? На какие сегменты разбита RAM память?

7--Какие доки(спеки) нужны для того, чтобы разрабатывать встраиваемый софт? Назовите минимум 4 дока.

8--Компилятору подали 5 *.с файликов и 20 *.h файликов. Сколько будет *.o файликов?

9--Тебе предоставили файл *.с чрезвычайно запутанный препроцессором. Как ты поймешь, что там происходит и в какой последовательности?

10--Что такое binutils? Какие знаете? Что можно с ними сделать?

11--Какие расширения файлов являются результатом работы разработчика MCU (артефакты)? Для чего нужен каждый из них?

12--В каких случаях артефакты в *.hex файликах предпочтительнее артефактов в *.bin файликах?

Вопросы про RTOS(ы)

1--Что такое Bare-Bone сборка RTOS прошивки?

2--Что такое поток?

3--что такое гонки в программах?

4--Что такое bit-banding и зачем нужен bit-banding?

5--Что такое контекст потока?

6--Что такое spinlock?

7--Что такое deadlock?

8--Что такое preemptive многозадачность?

9--Что такое критическая секция?

10--Что такое мьютекс?

11--Что такое семафор?

12--Пример атомарной операции?

13--Все ли в порядке в этом многопоточном коде?

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);
}

14--Что такое инверсия приоритетов?

15--Как бороться с инверсией приоритетов?

16--В стеке какого потока работают прерывания?

17--Что значит thread-safe код?

18--В чем разница между мьютекксом и семафором?

19--Что такое Reentrancy?

20--В чем разница между Joined и Detached потоками?

21--Написать функцию атомарного обмена содержимого переменных.

22--Что такое атомарные операции?

23--Как измерить процент загрузки MCU в прошивке без ОС?

Про цифровые фильтры:

1--В чём достоинство цифровых фильтров в отличие от аналоговых?

2--В чём недостаток FIR фильтра в сравнении с IIR фильтром?

3--Дан цифровой FIR фильтр. Иcходников нет, реализован в виде статической библиотеки *.a файла. Как узнать массив его коэффициентов B[0...N]?

Про железо (аппаратное обеспечение)

1--Чем резистор, конденсатор и катушки индуктивности отличаются друг от друга? В чём их сходство?

25--Каким напряжением открывается NPN транзистор?

26--Зачем микроконтроллерам функция Pull-Up/Pull-Down, если всегда можно включить LED просто установив логический уровень на GPIO?

2--Что такое PUSH-PULL, а что OPEN-DRAIN?

3--Как на 8MHz(цовом) микроконтроллере можно измерить частоту примерно 100MHz прямоугольного сигнала с GPIO?

4--Как проверить, что два PWM сигнала на 2х GPIO синфазные?

5--На одной SPI шине 2 Slave чипа. На оба подали одновременно Chip Select 0V и начали вычитывать регистры в которых разные данные. Что будет? Сгорит/не сгорит?

6--Какие регистры есть у микропроцессора ARM Cortex-M3 и для чего они нужны?

7--Что значит суперскалярный микропроцессор?

8--Почему частота часового кварца именно 32768 Hz?

10--Что нужно сделать программе с микроконтроллером, чтобы моргать светодиодом? Напишите словами каждый шаг.

11--Как сделать проверку-защиту, что firmware в самом деле предназначено именно для этой электронной платы?

12--По какому интерфейсу код взаимодействует с железом (ядром микроконтроллера)?

13--Что такое scatter/gather IO?

14--В чем отличия между архитектурами 8051, AVR, ARM, Xtensa, PowerPC, MIPS, RICS-V, x86, SPARC, ARC?

15--Что происходит с микроконтроллером между подачей питания и запуском функции main()?

16--Какие виды памяти есть в микроконтроллере.

17--На какие части обычно делится Flash память?

18--На какие части делится RAM память?

20--Как обрабатывать кнопку? Как преодолевать дребезг контактов?

21--Какой способ подключения LED предпочтительнее: a или b?

22--Дорисуйте блок-схему процессора ARM Cortex-M4 настолько, насколько вы в нем разбираетесь.

дорисовать ARM Cortex-M4
дорисовать ARM Cortex-M4

23-- Как при помощи микроконтроллера измерить сопротивление выводного резистора?

24-- Каким напряжением на затворе открывается P-channel MOSFET?

По интерфейсам

1--Какое напряжение на UART TX в режиме idle?

2--Зачем UART опция 2 стоповых бита, если это уменьшает data rate?

3--На шине SPI 2 разных чипа. На оба подали CS-0v и начали читать. Что произойдет: Сгорит/не сгорит/другое?

4--Как измерить процент загрузки CAN шины?

5--Какая разность потенциалов в CAN когда ничего не передается?

6--Есть два Lin интерфейса. У одного подтяжка data провода к 24V у другого подтяжка data провода к 12V. Data провода соединили. Что будет? Сгорит /не сгорит?

7--может ли i2c работать в режиме нескольких мастеров?

8--Чем CAN принципиально отличается от Ethernet?

9--У тебя на шине RS485 N устройств. Как мастер устройству узнать количество ведомых устройств на RS485 шине и их 32 битные адреса за минимальное время?

По протоколам

1--В каких протоколах у переменных big endian, а в каких протоколах у переменных little endian?

2--Зачем в TCP пакете контрольная сумма, если контрольная сумма есть в Ethernet пакете?

3--Зачем нужен IP-адрес, если уже есть MAC-адрес?

4--Как передавать пакеты по 1024 байт, если в PayLoad транспортного протокола помещается всего только 256 байт?

5--Почему CRC часто в конце пакета, а не в заголовке пакета?

6--Зачем нужно кодирование Base64 в Embedded?

7--Насколько процентов кодировка Base64 расширяет размер оригинального бинаря в самом худшем случае?

Вопросы про стек

1--Что происходит когда мы вызываем функцию?

2--Что хранится в стековой памяти?

3--Что такое стековый кадр? И что в нем хранится?

4--Какой код копирует в стек адрес возврата?

5--Можно ли на стеке выделить массив длинна которого задается аргументом функции?

6--Какой код копирует из стека адрес возврата из функции для регистра программного счетчика?

7--Кто инициализирует локальные переменные если их не проинициализирован явно ?

8--В какую сторону растет стек?

9--Сколько указателей стека в ARM Cortex-M4?

10--Что определяет в каком направлении будет расти стековая RAM память?

12--Какое значение в локальной переменной если ничего не присвоено при создании?

13--Что произойдет при переполнении стека?

14--Как определить на какую максимальную глубину заполнялась стековая память с момента запуска программы?

15--Все ли в порядке с функцией?

int8_t* foo(void) {
    int8_t val=-5;
    return (&val);
}

Беспроводные интерфейсы

--Как определить что передатчик в самом деле передает что-то?

--Нет радио Link(а) (например в LoRa). Как выявить в чем дело? Передатчик не передает или приемник не принимает?

Про heap память

--Как определить размер блока выделенного malloc?

--Как бороться с фрагментацией памяти?

--Как проверить сколько памяти выделено в куче в случайном месте программы?

Про загрузчики (Bootloader)

1--Зачем нужен загрузчик во встраиваемых системах? Назовите минимум 3 его функции.

2--Как загрузчик может обмениваться данными с приложением?

3--В чем опасность вызова функций загрузчика из приложения?

4--Как защитить микроконтроллер от загрузки чужеродного кода через загрузчик?

5--Как загрузчику понять, что загрузчик принял в самом деле прошивку, а не набор случайных циферок с правильной CRC?

6--Как сделать обновление прошивки по TCP/IP, если в загрузчике хватает NorFlash памяти только для драйвера UART?

7--Можно ли сделать так, чтобы загрузчик стартовал не с адреса начала Main Flash 0x0800_0000, а например с адреса 0x0806_0000?

8--Почему в микроконтроллерах STM32 секторы NOR Flash(а) разных размеров?

*9--Вам прислали прошивки в *.bin файле. Как загрузить и запустить эту прошивку по произвольному отступу в on-chip Nor Flash памяти?

10--Что код загрузчика должен сделать перед прыжком в приложения на ARM-Cortex-Mx?

*11--Каким образом кнопочные Siemens/Motorola/Nokia телефоны могли в run-time до устанавливать игры без пере прошивки микроконтроллера внутри?

Решение проблем (TroubleShooting)

1--Тебе дали дорогую плату запрограммировать прямо с производства. Плату ещё ни разу не включали в питание. Крайне вероятно, что плата сгорит при первом же включении из-за брака монтажа. Как ты проверишь плату не испортив ценный полуфабрикат?

2--Прошивка зависла, ваши действия?

3--Какие утечки вы знаете кроме утечки памяти?

4--Прошивка после подачи питания постоянно и непрерывно перезагружается. Как вы станете это ремонтировать?

5--Ты пишешь код, собираешь, запускаешь и вдруг прошивка перезагружается. Твои действия?

6--Как отладить большой кусок кода, если нет возможности пройти JTAG/SWD отладчиком?

7--Какие меры увеличения надежности софта предлагает стандарт ISO-26262?

8--По ходу добавления функционала вы столкнулись с нехваткой RAM памяти для своих глобальных переменных. Как отобразить всё глобальные переменные одной командой в консоли?

9--По ходу добавления функционала вы столкнулись с нехваткой ROM памяти. Как отобразить все функции одной командой в консоли?

10--Зачем мультиметру функция True RMS?

11--Что такое полоса пропускания в осциллографе?

Вопросы для развернутого устного ответа (System Design)

7--Как из одного потока передать массивы разных размеров другому потоку без динамического выделения памяти?

1--Как можно реализовать энергонезависимую Key-Val Map(ку) на микроконтроллере?

2--Как померить процент загрузки микроконтроллера в конкретное время (прошивка NoRTOS)?

3--Как можно реализовать надежную доставку пакетов поверх протокола UDP?

4--Как бы ты реализовал механизм FOTA? Т.е. обновления прошивки по беспроводному интерфейсу (Bluetooth, WiFi, LoRa, RFID, UWB и т.п.)?

5--У тебя на шине RS485 N устройств. Как мастер устройству узнать количество ведомых устройств на RS485 шине и их 32 битные MAC адреса за минимальное время?

6--Чем конечный автомат Мура отличается от конечного автомата Мили?

Вопросы для проверки навыков пользования компьютером

1--Есть текстовый файл-лог размером 50Mbyte. Строки с ошибками обозначены как [E]. Как узнать есть ли в логе ошибки и сколько их?

2--Диск переполнился. Комп тормозит. Как быстро выяснить размер каждой папки?

3--Как из консоли рекурсивно открыть в Notepad++ все файлы с расширение *.mk?

4--Как рекурсивно удалить все файлы расширения *.bak?

5--Что такое регулярные выражения?

6--Как отобразить все 3-буквенные слова в текстовом файле?

7--Напиши bash команду, которая ищет во всех файлах папки проекта макрос с под именем "LED" только в файлах board.h

8--Как в папке открытой в консоли рекурсивно заменить слово old_word на new_word во всех фалах внутри папки

Вопросы со звездочкой *

1--Как измерить покрытие микроконтроллерного кода после отработки модульных тестов?

2--Опиши как работает JTAG под капотом (установка точки останова).

3--Почему на некоторых MCU RAM память не является непрерывной, а разделена на несколько отдельный непрерывных диапазонов адресов?

4--Как узнать время сборки каждого *.с файла?

5--Как рассчитать CRC на стадии компиляции, чтобы положить результат в константный массив?

6--Как добавить еще одну отладочную кнопку, если уже все пины заняты.

7--Какой путь проходят данные с момента излучения с GNSS спутника до выхода в NMEA протоколе GNSS приемника?

Вопросы на способность тестирования и отладки

1--Какие существуют способы отлаживать прошивки? Назовите как минимум 10 способов.

2--Какой самый сложный программный или аппаратный баг приходилось искать и починить?

3--Как перезагрузить прошивку? Перечислите как можно больше способов. Минимум 3 способа.

4--Для чего нужны модульные тесты (скрепы)? Назовите 2+ причины.

5--Как отобразить UART лог в коде, который отрабатывает до инициализации отладочного UART?

6--Сколько способов подключить 4 провода к 8 ми клеммникам? Речь идет про конец каждого провода. В один клеммник устанавливается только 1 конец провода.

7--Как избежать чрезмерного, избыточного количества модульных тестов?

8--Как проверить, что инфракрасный передатчик IR в самом деле излучает хоть что-то?

9--Как проверить, что два массива это перестановка одних и тех же чисел?

10--Как протестировать драйвер графического I2C дисплея c SSD1306 в режиме write only?

11--Компания разработала прошивку для научного калькулятора выражения из строчки (типа Cassio FX-991EX). Придумай минимальное количество тестовых строчек, чтобы протестировать этот научный калькулятор .

Входная строчка

Ожидаемый результат

1

"(2+3)*2"

10

2

"1.5/0.0"

Math Error

3

")("

Syntax Error

Варианты для тестового задания дома

1--Напишите функцию для вычисления угла между 2D векторами с учетом знака (правая тройка).

2--Напишите функцию, которая вычисляет PWM sample.

double pwm_sample_calc(uint64_t time_us, 
                       double freq, 
                       double cur_phase_ms,
                       double des_amplitude, 
                       double duty_cycle, 
                       double offset);

3--Напишите прошивку под STM32F4, которая генерирует на GPIO два аппаратных PWM с возможностью менять фазу, частоту, скважность через UART в run-time.

*4--Напишите энергонезависимую FlashFS(NVRAM) для, например, STM32 микроконтроллера. Предусмотрите endurance optimization и защиту данных от пропадания питания.

5--Напишите heap allocator или попросту реализуйте malloc() free().

6--Даны две GNSS координаты. Вычислить азимут в градусах. Покрыть тестами.

7--Напишите минималистичную прошивку STM32 загрузчика (MBR), которая только прыгает в определенный адрес (например 0x08016000), чтобы запустить приложение. Постарайтесь уместить *.bin файл в 1kByte. У кого меньше бинарь, тот и победил.

8--В микроконтроллерной системе аналого-цифровой преобразователь измеряет напряжение на канале. Это напряжение надо конвертировать в дискретный уровень, в зависимости от значения. Сигнал зашумлен. Надо реализовать программный гистерезис. Напишите функцию, которая выполнит эту работу. Используйте в вычислениях только целочисленные типы.

int hysteresis(unsigned int input_percent);

9--Напишите диагностическую утилиту интерпретатор 19ти 8ми битных регистров RTC чипа DS3231. Регистровый dump считывать из текстового файла.

10*--Напишите Си функцию-переходник, которая преобразует PDM сигнал с MEMS микрофона в PCM сэмплы для загрузки в интерфейс I2S.

11--Напишите Cи-функцию csv_parse_text, которая выделяет из Comma-separated values строки текст по индексу. Вот модульный тест для csv_parse_text.

bool test_csv_parse_text(void){
    LOG_INFO(TEST, "%s():", __FUNCTION__);
    bool res = true;
    set_log_level(CSV, LOG_LEVEL_DEBUG);

    char sub_text[80] = "";
    memset(sub_text, 0, sizeof(sub_text));
    EXPECT_TRUE( csv_parse_text(";;c;;",';', 2, sub_text, sizeof(sub_text)));
    EXPECT_STREQ("c", sub_text);

    EXPECT_TRUE( csv_parse_text("ll wm8731 debug;ll i2c debug;tsr 127",';', 0, sub_text, sizeof(sub_text)) );
    EXPECT_STREQ("ll wm8731 debug", sub_text);

    EXPECT_TRUE( csv_parse_text("ll wm8731 debug,ll i2c debug,tsr 127",',', 1, sub_text, sizeof(sub_text)) );
    EXPECT_STREQ("ll i2c debug", sub_text);

    EXPECT_TRUE( csv_parse_text("ll wm8731 debug|ll i2c debug|tsr 127",'|', 2, sub_text, sizeof(sub_text)) );
    EXPECT_STREQ("tsr 127", sub_text);

    set_log_level(CSV, LOG_LEVEL_INFO);
    return res;
}

12--Написать Си-функцию, которая распознает вещественное число из строчки. То есть универсальный парсер типа данных double. Вот несколько тест кейсов: "." -> 0.0; ".5" -> 0.5; "5." -> 5.0; " 6" -> 6.0; "+1e2" -> 100; " 1/3" -> 0.33;

13--Написать Си-функцию, которая берёт произвольную строку и распознает минимальный тип данных для информации в этой строке. Написать код согласно требованиям ISO26262-6

# теста

Строка на входе

распознанный тип данных

1

'1'

uint8_t

2

'-20'

int8_t

3

'some_text'

string

4

'3.14'

double

5

'0x12345678'

uint32_t

6

'0x1234567878563412'

uint64_t

7

'a'

char

8

'0x1234'

uint16_t

9

'1.56e-1'

double

10

'1/3'

string

Если Вы знаете адекватные, сложные и интересные вопросы по теме разработки на MCU, то пишите их в комментариях.


Links
https://gcc.gnu.org/onlinedocs/gcc/

Only registered users can participate in poll. Log in, please.
Сколько раз вы участвовали в технических интервью на роль embedded программиста?
21.21% 121
34.34% 2....1034
12.12% 11....4912
0% 50..990
1.01% больше 1001
31.31% ни разу31
99 users voted. 36 users abstained.
Only registered users can participate in poll. Log in, please.
Вы знали все ответы на все вопросы сразу после прочтения текста?
10.69% да14
89.31% нет117
131 users voted. 21 users abstained.
Tags:
Hubs:
Total votes 36: ↑14 and ↓22-4
Comments126

Articles