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

По коду

0--Как в Си программе для микроконтроллера определить во Flash памяти константный массив размером 32 kByte и заполнить его сплошняком значениями 0xFF? При этом так, чтобы не писать много кода (т. е. без прямой инициализации). Без использования код генераторов.

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--Зачем нужен оператор препроцессора ##?

--Есть ли способ пометить участок кода чтобы Си препроцессор его не менял? Чтобы как встретилась строка #include <file.h> так и осталась в первозданном виде.

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 из разных файлов проекта. Как проверить во время компиляции (до исполнения кода), что в финальном массиве структур нет повторяющихся элементов?

40--Что не так с этим кодом?

typedef union {
    uint32_t dword;
    struct {
        uint32_t SOFTRESET:1;  /* 0 Software Reset Mode */
        uint32_t RES1:7;       /* 7-1  */
        uint32_t SLAVENUM:8;   /* 15-8 Slave Number in Matrix*/
        uint32_t RES2:8;       /* 23-9 */
        uint32_t MASTERNUM:8;  /* 31-24 Master Number in Matrix*/
    };
}MamRegMaxCfg_t;

static bool MamDiagRegMaxCfg(const MamRegMaxCfg_t * const pReg){
    bool res = false ;
    if(pReg) {
        LOG_WARNING(MAM, "MaxCfg:0x%08X=%s", pReg->dword, utoa_bin32(pReg->dword));
        LOG_INFO(MAM, "SOFTRESET:%u", pReg->SOFTRESET);
        LOG_INFO(MAM, "SLAVENUM:%u", pReg->SLAVENUM);
        LOG_INFO(MAM, "MASTERNUM:%u", pReg->MASTERNUM);
        res = true;
    }
    return res;
}

39-- Зачем писать слово extern у прототипов функций в *.h файле?

--Как в Си определить 24-битную знаковую переменную типа int24_t ?

--Как в Си определить 7-битную знаковую переменную типа int7_t ?

--Существует ли авто форматирование Си-кода, который принудительно и всегда выставляет аргументы функции в столбик? Clang-format, Astyle и GNU indent не предлагать, так как там таких ключей нет.

Системы сборки

40--Что такое система сборки?

41--Зачем использовать какую бы то ни было систему сборки (хоть GNU Make) если можно просто написать *.bat или *.sh скрипт который скармливает комилятору исходники? В cmd или bash скриптах же тоже есть переменные и условные операторы.

42--Чем система сборки Ninja отличается от системы сборки Make?

43-- Зачем в GNU Make нужно ключевое слово vpath?

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

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

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

Про DevOps

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

--Что такое top-half прерывание?
--Что такое bottom-half прерывание?
--Что нельзя (не рекомендуется) делать в обработчике прерываний?
--В стеке какого потока работают прерывания? Где размещаются локальные переменные, что используются внутри функции обработчика прерываний?

Про ToolChain (компилятор и компоновщик)

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

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

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

--Как отлаживать LD скрипт компоновщика GCC? Есть ли printf для ld скрипта?

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

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

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

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

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

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

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

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

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

13--Как в GCC сделать так, чтобы заполнение (padding) между переменными в структурах при выравнивании константных Си структур заполнялось не значением 0x00, а специфическим значением, например 0xFF или 0xAA?

typedef struct {
    uint32_t start;                                    
    uint32_t size;                                     
    bool valid;                                        
    uint8_t num;                                       
    char* name;     
}NvsConfig_t;

const NvsConfig_t NvsConfig[] = {
    {
        .start = NVS_START,
        .size = NVS_SIZE,
        .num = 1,
        .valid = true,
        .name = "NVS",
    },
};
тут padding 0x00 0x00, а надо 0xFF 0xFF
тут padding 0x00 0x00, а надо 0xFF 0xFF

--Как в компоновочном скрипте GCC компилятора создать секцию c именем Dummy во Flash памяти (начиная с адреса 0x08000400 размером 31 KByte) и заполнить ее сплошняком символами FF?

Вопросы про 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 в прошивке без ОС?

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

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

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

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

27--Зачем в квадратурном смесителе нужно два смесителя (перемножителя), а не один, три или четыре?

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

--Зачем вообще нужен постоянный ток DC, если в розетках всегда переменный ток AC?

--Почему электроны не высыпаются из куска металла под действием силы тяжести или при тряске?

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

60--Что значит подтягивающий резистор 1500 Oм на проводе USB_D (USB+)?

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

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

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

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

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

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

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

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

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

P‐канальный MOSFET‐транзистор открывается отрицательной полярностью напряжения затвор‐исток, и в открытом состоянии пропускает ток от истока к стоку.

--64-- Каким напряжением на затворе открывается N-channel MOSFET?
 N‐канальный MOSFET‐транзистор открывается положительной полярностью напряжения затвор‐исток, и в открытом состоянии пропускает ток от стока к истоку.

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

--Почему топологию внутренностей микроконтроллеров (SoC-ов) трассируют автоматически, а PCB по-старинке трассируют вручную? Ведь внутренности SoCов в тысячи раз сложнее, чем типовые PCBшки.

--Я собираю схему на операционном усилителе. Я никак не мог понять откуда мне получить -15 В, ведь блок питания выдает только от нуля до 32V. Как быть?

--Почему печатные платы PCB чаще всего делают зеленым цветом?

--Почему электронная логика питается и работает именно от 3.3В а не 2.2V или 1,1V?

Вопросы по процессоры

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

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

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

--33--Как проверить, что два PWM сигнала на 2х GPIO синфазные? Как микроконтроллер может проверить, что два PWM сигнала поступают с одинаковой фазой?

--Как на STM32 управлять фазой аппаратного PWM сигнала?

--Почему в МК не добавляют аппаратный Delta sigma модулятор?

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

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

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

--60--Вы программируете многоядерный MCU. Как ядро Core0 может узнать, что зависло ядро Core1?

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

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

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

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

--68-- Микроконтроллер STM32F407 может исполнять программу из SPI-NorFlash памяти (W25Q128)  eXecute in Place (XiP) ?

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

47--Почему в микроконтроллерах нет MMU (memory management unit)?

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

--67--Почему в ARM Cortex-M4 микропроцессорах 24-битный SysTick таймер сделали Down-Counting? Это же контр интуитивно. Какой выигрыш от аппаратного таймера, который уменьшается, а не возрастает? Вот DWT таймер сделали Up-Counting.

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

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

1--Почему в ARM-Cortex-Mx процессорах фактический адрес функций на единицу больше, чем то значение адреса функции, что указано в *.map файле? Вот .map файл:

реальность:

Адреса функций нечетные. При этом в Flash памяти бинарный код лежит по четным адресам.

52--Зачем внутри микропроцессоров нужен MPU?

66--Как отловить факт переполнения стека?

Вопросы по интерфейсам

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

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

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

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

11--Как прошивка MK может понять, что проводники CAN-H и CAN-L при подключении перепутаны местами?

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

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

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

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

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

10--Почему микросхемы физики Ethernet (типа DP83848IVV) не конфигурируются по I2C, а вместо этого придуман особый интерфейс MDIO, который очень похож на I2C?

11- По какой логике в STM32 выбирается поле Channel в структуре  DMA_InitTypeDef? И почему оно не совпадает с номером потока DMA?

12--Почему в интерфейсе CAN bit staffing после пяти одинаковых бит, а в USB-LS после 6 одинаковых бит? Ведь у обоих битовая скорость примерно одинаковая 1MBit/s?

13--Есть ли способ как-то настроить USB, чтобы MCU получал точное время по USB для настройки RTC?

Вопросы про интернет технологии

1--Зачем в TCP пакете контрольная сумма, если контрольная сумма и так присутствует уровнем ниже в Ethernet пакете?
2--Зачем нужен 32-битный IP адрес, если уже есть MAC адрес, да при том ещё и большей разрядности 48 бит?
3--Зачем нужен номер port, если и в операционной системе так есть PID процесса?
4--Как в локальной сети быстро найти IP адрес на котором работает TCP сервер с портом 333?

5--Почему нельзя просто взять и набрать пароль для подключения к GitTLab? Зачем вдруг стали нужны эти открытые и закрытые SSH ключи?
6--Что такое сокет?

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

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

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

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

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

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

5--Насколько процентов кодировка 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). Как выявить в чем дело? Передатчик не передает или приемник не принимает?

*--Как синхронизовать 2 аппаратных пикосекундных 64битных таймера на 2х платах, которые могут только общаться по радио? Чтобы они переполнялись одновременно.

Про 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 отладчиком?

--Можно ли по SWD подавать текст в прошивку, а не только вовне по проводу SWO?

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

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

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

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

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

12--Чем точность отличается от погрешности? Как улучшить точность и как уменьшить погрешность?

Вопросы для развернутого устного ответа (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

12--Как можно покрыть модульными тестами программу для ПЛК или Simulink? Ведь там вместо кода рисунок алгоритма. Как можно протестировать рисунок?

Вопросы на логику

Вот реальные задачи на логику, которые меня на полном серъёзе спрашивали при трудоустройстве на роль программиста микроконтроллеров:

1--Есть две комнаты. В одной 3 выключателя в другой 3 лампочки. Как понять какой переключатель соответствует каждой лампочке, если зайти в комнату можно только один раз?

2--Как проверить, горит ли лампочка в холодильнике при закрытой дверце? (холодильник маленький человек там не поместится.)

3--Вы прошли 10 км на север, потом 10 км на восток и 10 км на юг. Пришли в ту же точку. Где такое возможно?

4--Есть 1000 одинаковых колб с прозрачной жидкостью. В 999 колбах вода, а в одной случайной колбе - отрава. Если мышь попробует отраву, то она погибнет через 1 час (тот час же). Как при помощи 10 мышей найти колбу с отравой? Сколько времени потребуется, чтобы найти отраву? Как при этом погубить как можно меньше мышей?

5--Есть 2 емкости: 5 литров и 3 литра. Как отмерить 4 литра жидкости используя только эти 2 емкости?

6--Каждый гость на встрече обменивается рукопожатием с другим. Всего было 78 рукопожатий. Сколько гостей пришло на встречу?

7--Бросают кубик три раза. Какова вероятность, что выпавшие значения образуют треугольник?

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

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 и защиту данных от пропадания питания. Плюс есть запрет на до-запись ячеек flash памяти.

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

14--Написать на си утилиту-экстрактор массивов из *.hex файлов. Даешь hex файл, физический адрес, размер непрерывного куска памяти. Получаешь hex массив интервала памяти в текстовом файле и в stdout. Это нужно для проверки артефактов. Проверка таблицы векторов прерываний. Не использовать вызов сторонних утилит.

15*-- Написать на Си медианный фильтр. Причем так, чтобы не делать сортировку семплов на каждом шаге. То есть решить задачу 480. Sliding Window Median с LeetCode.

16*--Написать Delta-Sigma модулированный сигнал (PDM сигнал) на GPIO пине микроконтроллера. Это нужно для более плавного регулирования тока в DC моторе или LED нежели в случае с PWM сигналом.

17--Написать на языке программирования Си абстрактную структуру данных для BitFIFO. Чтобы хранить там только 0 или 1. При этом, чтобы экономить память семплы тоже хранить плотно. То есть на 1 семпл выделять только 1 бит памяти. Должны быть функции bit_fifo_push(...), bit_fifo_pull(....), bit_fifo_peak(....), bit_fifo_init(...). Память для FIFO выделять статическим образом при инициализации. В случае переполнения FIFO перезаписывать самый старый семпл и увеличивать счетчик ошибок на единицу. (Это нужно для программных реализаций интерфейсов SPI, UART, I2C и пр.)

18--Перед Вами 1280 двух битных семпла BPSK модуляции на частоте 8000 Hz. Частота несущей 2000 Hz. Битовая скорость 100 бит в сек. Определите значение word числа, которое тут передается.

0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;
0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;
0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;
0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;
0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;
0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
1;0;-1;0;1;0;-1;0;1;0;-1;0;1;
0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;
-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;
0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;0;1;0;-1;

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


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

Материал

URL

This file documents the use of the GNU compilers.

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

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Сколько раз вы участвовали в технических интервью на роль embedded программиста?
19.83%124
33.06%2....1040
10.74%11....4913
0%50..990
0.83%больше 1001
35.54%ни разу43
Проголосовал 121 пользователь. Воздержались 36 пользователей.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Вы знали все ответы на все вопросы сразу после прочтения текста?
9.8%да15
90.2%нет138
Проголосовали 153 пользователя. Воздержались 23 пользователя.