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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Это список вопросов на которые должен уметь ответить тот кто хочет программировать микроконтроллеры и заниматься разработкой электроники. Вопросы в частности взяты из технических собеседований при устройстве на работу в разные компании. Постарался отобрать только самые приближенные к практике вопросы, которые можно выделить после 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 секторы разных размеров?

Решение проблем

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

--Сколько способов подключить 4 провода к 8 ми клемникам?

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

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

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

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

--Напишите функцию для вычисления угла между 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);

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

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

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Сколько раз вы участвовали в технических интервью на роль embedded программиста?
66.67% 1 2
33.33% 2....10 1
0% 11....49 0
0% 50..99 0
0% больше 100 0
Проголосовали 3 пользователя. Воздержались 6 пользователей.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы знали все ответы на все вопросы сразу после прочтения текста?
0% да 0
100% нет 11
Проголосовали 11 пользователей. Воздержался 1 пользователь.
Источник: https://habr.com/ru/post/676076/


Интересные статьи

Интересные статьи

В данной пошаговой инструкции мы подробно опишем весь процесс получения доступа к WhatsApp Business API через официального партнера Facebook — сервис Gupshup и подключени...
Мне было необходимо делать 2 раза в сутки бэкап сайта на «1С-Битрикс: Управление сайтом» (файлов и базы mysql) и хранить историю изменений за 90 дней. Сайт расположен на VDS под уп...
VUE.JS - это javascript фрэймворк, с версии 18.5 его добавили в ядро битрикса, поэтому можно его использовать из коробки.
Каждый лишний элемент на сайте — это кнопка «Не купить», каждая непонятность или трудность, с которой сталкивается клиент — это крестик, закрывающий в браузере вкладку с вашим интернет-магазином.
Если Вы используете в своих проектах инфоблоки 2.0 и таблицы InnoDB, то есть шанс в один прекрасный момент столкнуться с ошибкой MySQL «SQL Error (1118): Row size too large. The maximum row si...