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

По коду

--Зачем static?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

struct Foo {
    int iiii;
    char c;
};

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

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

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

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

--Зачем нужен сервер сборки Jenkins?

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

--Что для тебя значит рефакторинг?

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

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

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

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

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

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

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

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

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

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

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

Про ToolChain

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

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

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

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

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

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

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

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

--Какие файлы являются результатом работы разработчика MCU (артефакты)?

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

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

Про железо

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

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

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

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

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

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

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

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

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

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

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

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

--В чем отличие между ARM, PowerPC, MIPS и RICS-V?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Про heap память

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

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

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

Про загрузчики

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

int hysteresis(unsigned int input_percent);

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

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

Комментарии (114)


  1. gvtret
    09.07.2022 21:08
    +13

    Набор вопросов тянет не на "колобок", а на полноценный зачет. И для чего это, без ответов? Список вопросов можно и у себя оставить, а здесь народ ждет ответов, имхо....


    1. aabzel Автор
      09.07.2022 21:15
      -9

      Часть ответов можно в поиске найти.
      Часть в моих предыдущих текстах.
      Цель статьи- сфокусировать внимание на реальных вопросах.

      Предупрежден значит вооружен.


      1. gvtret
        09.07.2022 22:57
        +23

        Ну реально такое надо сопровождать ответами.... Так, статья, ни о чем. Connecto ad uno слабо?

        Вы статью для кого писали? Для преподавателей, так у нас и своих вопросов хватает.

        Для студентов? Так РАЗЪЯСНИТЕ вопросы ответами.

        Короче фу просто, а не статья!


        1. aabzel Автор
          10.07.2022 00:01
          -14

          Вы из какого ВУЗ(а)?


        1. aabzel Автор
          10.07.2022 00:02
          -5

          Эти вопросы из продакшена, не из академической среды.
          Целевая аудитория это те кто готовится к технический собеседованиям.


          1. Hlad
            10.07.2022 18:12
            +3

            Забавно. Вы задаёте вопросы из достаточно узкой области, а именно - программирование под ARM Cortex на языке Си. При этом тема сформулирована гораздо более глобально - "кто хочет программировать микроконтроллеры и заниматься разработкой элэлектроники". С тем же успехом я могу вас размотать вопросами по ассемблеру MSP430, ну и по железу заодно.


            1. aabzel Автор
              10.07.2022 19:25
              -3

              С тем же успехом я могу вас размотать вопросами по ассемблеру MSP430, ну и по железу заодно.


              Отлично. Пишете свои вопросы.


  1. Myclass
    09.07.2022 22:27
    +5

    кто хочет программировать микроконтроллеры и заниматься разработкой элэлектроникив

    Вы серьёзно? Те. не тот, кто себя будет бить в грудь и кричать на весь свет(как это делаете вы), что он король микроконтроллеров, а именно тот, кто хочет программировать? Просто хочет...


    1. aabzel Автор
      09.07.2022 23:53
      -13

      Вот так.
      Поделился ценнейшей инфой, добытой неимоверными усилиями и еще виноват.
      Нормально вообще.


      1. Fox_exe
        10.07.2022 10:48
        +6

        А где здесь "Информация"? Тут только вопросы без ответов. А "информация" - это в первую очередь - ответы.


        1. aabzel Автор
          10.07.2022 16:19
          -1

          без этого текста так бы и продолжали решать бессмысленные задачи из класса "инвертировать связанный список"


      1. milssky
        10.07.2022 15:06
        +1

        Это инфа ничего не стоит без ответов. Вообще.


        1. Hlad
          10.07.2022 18:17
          +5

          Ну, как минимум, она даёт понять, чем на самом деле занимается автор. А именно - пилит какие-то устройства для транспорта. Вероятно - электронные транспортные пломбы


  1. Fen1xL
    09.07.2022 23:06
    +1

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


  1. ArtG89
    09.07.2022 23:59
    +3

    Так задумывалось?
    uint16_t arr[4] = {0x04,0x03,0x02,0x01};
    uint32_t val;
    val =((uint32_t) (&arr[1]));
    printf("val=%08x \n", val);
    Или так?
    uint16_t arr[4] = {0x04,0x03,0x02,0x01};
    uint32_t * val;
    val =((uint32_t *) (&arr[1]));
    printf("val=%08x \n", *val);


    1. aabzel Автор
      10.07.2022 00:08

      В статье это место верно.


      1. ArtG89
        10.07.2022 00:09
        +2

        теперь да


      1. AlB80
        10.07.2022 18:00

        Так то UB, unaligned memory access.


    1. aabzel Автор
      10.07.2022 00:09

      Первое даже не соберётся без предупреждений


      1. ArtG89
        10.07.2022 00:15
        +3

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


  1. pwl
    10.07.2022 00:03
    +10

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

    Прям-таки интересно, каков по вашему правильный ответ? :)

    Вопросы про RTOS

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

    Каким боком тут RTOS?

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

    это точно "про железо"?

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


    1. F0iL
      10.07.2022 00:46
      +1

      процентов на 10 вопросов не существует однозначного ответа,

      Так в этом-то и смысл, это именно то что у нас в универе называли "вопрос с подвохом" и то, насколько уверенно и категорично отвечает на такой вопрос кандидат, тоже может сказать многое :)


  1. Xop
    10.07.2022 00:12
    +10

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

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

    Вы ведь учитываете, что это сильно зависит от архитектуры процессора?


  1. F0iL
    10.07.2022 01:06
    +17

    • Ставите ли вы -Wall -Wextra -Weverything в опции компилятора (и ещё пару десяток аналогичных опций из той оперы)? Если нет, то почему?

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

    • Зачем делают first stage bootloader и second stage bootloader - им что, одного загрузчика мало?

    • Какие методы разрешения конфликтов при слиянии кроме git push --force вы знаете?

    • Сразу в мастер без пулл-реквеста и ревью хоть раз коммитили? Ну признатесь, признайтесь. Ага, а почему у вас такое вообще было разрешено?

    • Возможно ли иметь динамическую память с предсказуемой фрагментацией и временем аллоцирования? А если подумать?

    • У SQLite юнит-тестов в 600 раз больше, чем самого кода основного функционала. Вам слабо так же?

    • MISRA читали? Какое у вас любимое правило оттуда? А какое нелюбимое?

    • Что такое алиасинг? Почему -f-no-strict-aliasing включают только слабаки?

    • Расскажите мне про тайминги в Modbus RTU (вместе посмеемся)

    • На каком языке вы пишите комментарии к коду?

    • Можно ли профилировать с помощью осциллографа?

    • Что такое "антипаттерн"? Какие из них вы регулярно видите в коде от коллег? Какие из них вы сами делаете, когда никто не видит?

    • Есть ли у вас в коде переменные с русскими словами латинскими буквами? А если найду?

    • Чем плохо глобальное состояние и чем хороши чистые функции?

    • Почему за прибитые гвоздями зависимости между модулями и за совмещение в одной функции бизнес-логики с низкоуровневой работой с железом нужно бить в жбан кипятильником и выгонять из профессии? Приведите примеры из жизни, к чему это приводило (совмещение и зависимости, а не кипятильник).

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


    1. iliasam
      10.07.2022 02:14
      +4

      И в статье, и здесь упоминается динамическое распределение памяти.
      Можете, пожалуйста, привести примеры практических задач, в которых оно требуется именно на микроконтроллерах?


      1. aabzel Автор
        10.07.2022 02:58

        Вы программируете аудио систему.

        Вам надо запрограммировать режим воспроизведения синуса для тестирования аудио тракта.

        Частота, фаза, амплитуда синуса и частота дискретизации задаются в run-time из UART-CLI.

        Вы хотите передавать семплы аудиодорожки по I2S циклически по DMA? чтобы был чисты звук.

        Для этого надо рассчитать пару периодов и положить в RAM. Неизвестно сколько получится семплов, ведь частота задается в run-time.

        Поэтому надо задействовать динамическую память для DMA, размер которой зависит от частоты дискретизации звука и периода синуса тестовой аудиодорожки.


        1. Mirn
          10.07.2022 06:50
          +7

          Если речь про I2S то у мк явно не единицы а как минимум десятки килобайт ОЗУ. Поэтому, что мешает рассчитать таблицу в четверть периода синуса с периодом скажем в одну секунду? И проходиться по нему с дробным шагом интерполируя например сплайнами промежуточные значения? А порой достаточно просто линейной интерполяции (для первичной пуско-наладки отладки схемотехники после первой сборки). Это делается в пару десятков строк кода на си же.


          1. aabzel Автор
            10.07.2022 15:36

            У нас там еще и chirp сигналы и PWM и пилы надо генерировать на выходе DAC.


        1. shiru8bit
          10.07.2022 09:34
          +5

          В таких случаях берётся наибольшее. Динамическое выделение памяти здесь ни к чему, т.к. экономия памяти никуда не пригодится (её или изначально хватит для параллельных процессов при наибольшем значении, или изначально не хватит), а постоянное перевыделение может привести к фрагментации, и в какой-то момент память не просто выделится. Собственно, по причине фрагментации и очень малого, но заранее однозначно известного объёма ОЗУ динамическое выделение памяти на МК и подобных системах с ограниченными фиксированными ресурсами используется редко. Оно больше подходит для загружаемого ПО, где один исполняемый файл запускается на разных, заранее неизвестных конфигурациях.


          1. Indemsys
            10.07.2022 11:44
            +3

            Ваша логики прямо подводит к ответу.
            А ответ такой - динамическая память нужна тогда, когда худший случай не помещается в памяти.
            Например в работе в BLE общее количество и разнообразие передаваемых и посылаемых объектов может сильно превысить объем памяти маленького контроллера на Cortex-M0.
            Поэтому в стеках BLE повсеместно используют динамическую память.
            Я бы даже сказал без динамической памяти нельзя сделать ни один развитый коммуникационный стек от ZigBee до TCP.
            Это еще не упоминая парсеров и прикладной уровень.


          1. aabzel Автор
            10.07.2022 15:31

            Можно написать custom реализацию malloc free и сборщик мусора для него прямо на С отдельной задачей или потоком. Это просто работа с массивами.


      1. aabzel Автор
        10.07.2022 15:20

        Второй пример. UART.

        Алгоритм отправки "ждать окончания-отправить".

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

        Данные которые мы хотим отправить лежат в стеке.
        Чтобы данные на стеке не покарраптились их надо перекопать из стека в кучу. И дать отмашку отправлять в UART из кучи.
        Сразу после побежать исполнять следующий код пока данный отправляются в UART.
        А в прерывании закончившейся отправки освободить память.

        Это оптимизирует производительность и избавит от антипаттерна Busy Wait при классическом алгоритме "отправить-ждать окончания".

        То же самое для I2C, SPI, I2S, SDIO.


        1. iliasam
          10.07.2022 16:10
          +3

          «Чтобы данные на стеке не покарраптились их надо перекопать из стека в кучу. И дать отмашку отправлять в UART из кучи.»
          Но часто же обычное FIFO используют для этих целей?


          1. aabzel Автор
            11.07.2022 01:04
            -1

            Но часто же обычное FIFO используют для этих целей?


            Спасибо за информацию.




        1. FGV
          10.07.2022 17:05
          +1

          Алгоритм отправки "ждать окончания-отправить".

          В свое время очень часто применял (во времена 8051, AVR), когда было делать лень на прерываниях и морочится с очередями или оставалось мало оперативки. Но, при этом вся логика функционирования девайса висела на прерывании от таймера. Т.е. получалось что все что нужно делается в обработчике прерывания каждый тик, а обмен с ПК - фоном висит.

          Сейчас, с десятками килобайтам ОЗУ на борту, для современных МК конечно так делать не надо. Но опять же, не сказаны условия в которых этот антипаттерн приводится.


      1. aabzel Автор
        10.07.2022 16:31

        Можете, пожалуйста, привести примеры практических задач, в которых динамическое распределение памяти требуется именно на микроконтроллерах?

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


      1. ProLimit
        10.07.2022 19:25
        +3

        Достаточно активно используем динамическое выделение памяти в микроконтроллере. Примеры: есть сложная система и поведение зависит от конфигурации, хранящейся в EEPROM. А памяти на все 40kb. Часть функционала не нужна, так зачем выделять буферы и статические переменные. Размер некоторых блоков зависит от выбора пользователя. ну и так далее. Единственное, что для МК логично только ВЫДЕЛЯТЬ, но не ОСВОБОЖДАТЬ, так как иначе приходится решать сложную проблему фрагментации.


    1. jakushev
      10.07.2022 08:44
      +3

      С последним вопросом не справился…


      1. edmus
        10.07.2022 12:01
        +1

        Легко же: у банкиров нет китайских конкурентов)


        1. F0iL
          10.07.2022 13:56
          +1

          Зато есть индусские индийские :)


          1. edmus
            11.07.2022 16:35

            Это не у банкиров, а у веб-формошлепов :)


    1. Indemsys
      10.07.2022 11:38
      +3

      А я бы спросил:

      • Как работает директива __packed для структур с одной переменной типа uint32_t. Можно ли это использовать для записи переменной uint32_t в невыровненные буферы?

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

      • Что такое интринсики, и почему они убивают переносимость кода и делают неправильными еще часть вопросов автора статьи.

      • Когда кэш - зло?

      • Почему в embedded полезно делать много прямых межмодульных связей и совмещать в одном месте бизнес-логику и обращение к железу. И никакие евангелисты чистого кода этому не могут воспрепятствовать?

      Эт не вопросы накопленные за 10 лет, а то что приходилось решать еще буквально вчера.


    1. aabzel Автор
      10.07.2022 15:49
      +3

      Как вы объясните ребенку разницу в зарплатах между разработчиками прошивок МК на производстве и веб-формошлепами в банках?

      В разработке прошивок в принципе не может быть монетизации как в Web Сайтах. Никто не будет платить 10$ в месяц за аккаунт в прошивке. Это просто смешно. Цена прошивки без физического устройства 0 рублей. Продажи прошивок ограничены продажами электронных устройств, которые крутят эти прошивки. А электронные устройства ограничены производственными возможностями для изделия. В России нет массового производства никакой электроники. HiTech промышленности нет. В российских электронных организациях как правило мелкая серия электроники 100..500 штучек чего-либо за весь жизненный цикл продукта. Большинство моих знакомых даже не подозревают, что в РФ вообще занимаются какой-то электроникой. Поэтому программисты микроконтроллеров самые низкооплачиваемые программисты в России, работающие в массе своей за идею.


      1. fk0
        11.07.2022 00:48
        +3

        Бывают и огромные серии, но зарплаты только меньше. Нет, дело не только в мелкосерийном производстве, хотя конечно это существенный фактор.


  1. HiSER
    10.07.2022 08:12
    +6

    Микроконтроллеры существуют только ARM и только STM32?


    1. HiSER
      10.07.2022 08:18

      Первая структура: 3, 4, 5, 8; какой ответ устроит?

      Во второй структуре ошибка.


      1. Whitech
        10.07.2022 09:53

        И где тут ошибка?


        1. buratino
          10.07.2022 10:24
          +1

          зависит от цомпилятора или его опций.


          1. alexzeed
            11.07.2022 01:33

            Не зависит. unsigned index это unsigned int index, без вариантов, и это вполне корректный код. Вот размер этой структуры — да, может быть разный и языком С не нормируется. От 5 до 19 на типичных архитектурах (вариант «10» в моей жизни тоже встречался :) )


        1. HiSER
          10.07.2022 10:37
          +1

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


          1. Whitech
            10.07.2022 10:48
            +3

            В первом примере вас эти обстоятельства не смущали и вы давали варианты ответов, а тут вдруг это стало ошибкой.


      1. sami777
        11.07.2022 13:31

        Это с подвохом! Что для текущей среды является типом по умолчанию. Зависит от среды. Обычно 4-х байтный int. Но компилятор должен выдать предупреждение.


    1. aabzel Автор
      10.07.2022 14:53

      Микроконтроллерные ядра бывают с 8051,ARM,AVR,RISC-V,STM8,Xtensa,PowerPC,PIC,MSP430,Microblaze, Nios.


      1. Hlad
        10.07.2022 18:18
        -1

        А вопросы только по ARM-ам...


  1. JackKatch
    10.07.2022 10:15
    +2

    Согласен с тем, что наличие ответов придало бы статье смысл. А так... Мало ли кто что спрашивает. P.S. Не обнаружил моего любимого вопроса от работодателей, "умение играть на баяне будет преимуществом".


  1. buratino
    10.07.2022 10:33
    +1

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

    минимум 8!, в среднем 8^8, практически - бесконечное число вариантов...


    1. FGV
      10.07.2022 11:13
      +1

      8^4 же. 4 провода на 8 клемм.


      1. buratino
        10.07.2022 14:46
        +1

        8*7*6*5*4*3*2*1 4 провода, 8 концов. Это если подключальщик будет подключать один конец в одну клемму. 8^8 - это если в одну клемму можно напихать до 8 концов. В практическом случае можно напихать не те провода и/или не в те клеммы или вообще оставить висеть в воздухе


        1. FGV
          10.07.2022 15:04
          -1

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

          Провода 4, так что максимум - 8^4. Правда тут хз что за клеммник, они тоже разные могут быть.


          1. buratino
            10.07.2022 15:12
            +1

            уф...Берем один конец первого провода. Его можно воткнуть в одну из 8 клемм. Берем другой конец - его можно воткнуть в одну из 7 оставшихся. Берем первый конец второго провода - есть 6 мест для втыкивания, для второго конца останется 5 вариантов....


            1. vicsoftware
              10.07.2022 16:50
              +1

              Вот только подключение 8-7 и 7-8 - это одно и то же подключение. Это учитывается?


              1. buratino
                10.07.2022 17:49

                виноват. Провода обычно не отличаются по концам и диоды внутрь враги не ставят.. Тогда вроде не факториал, а число сочетаний надо считать 8!/((8-2)!*2!) =28


            1. FGV
              10.07.2022 17:08

              О типе клеммника и типе проводов - в условии ничего не сказано. Считаю что клеммник - винтовой (что то типа DG305-5.0-02P-12-00AH), и 1,2,3,4 провода в одну клемму вполне влезут и зажмутся винтом.


      1. aabzel Автор
        10.07.2022 16:05
        -1

        По комбинаторному "правилу перемножения" получается 8*7*6*5=1680 способов.


        1. FGV
          10.07.2022 16:51
          +1

          Хз, я считаю что клеммник - винтовой (что то типа DG305-5.0-02P-12-00AH), и 4 провода в одну клемму вполне влезут и зажмутся винтом. О типе клеммника и типе проводов - в условии ничего не сказано.


  1. titbit
    10.07.2022 11:54
    +6

    Список вопросов странный, конечно.
    Половина наверное к контроллерам вообще отношения не имеет, это про тонкости C и применяется где угодно.

    Часть вопросов вообще не имеет однозначных ответов, потому что зависят от архитектуры (а их в контроллерах с десяток и все разные). Архитектура ес-но не указана в некоторых вопросах.

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

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


  1. DrGluck07
    10.07.2022 12:53
    +2

    У нас недавно один джун чуть с ветки не упал, когда его стали привлекать к проекту на железе. Его попросили посмотреть сколько в микроконтроллере памяти. Он посмотрел доку, увидел что там написано internal SRAM 8KB, и крепко задумался как с этим жить дальше )
    Ещё интересно наблюдать, как молодые программисты внезапно обнаруживают, что в одном старом проекте под техасовский DSP char, short и int внезапно имеют размер 16 бит.


  1. lamerok
    10.07.2022 14:06
    +5

    Вопросы конечно хорошие, но я бы учил студентов делать так, чтобы такого кода не было вообще в продукте.

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

    Ну зачем перемножать два раз именованных volatile указателя? Ну разве нельзя вообще без этого? Volatile вообще вон выкинуть хотят из С++, столько из за нее проблем, особенно если операции чтения не атомарная. Её использование уже намекает на то, что происходит что то не то.

    Тоже самое про DeadLock, если код так выглядит, то наверное стоит подумать об увольнении его написавшего.

    Кроме того на 99% любой статический анализатор кода найдёт всю эту фигню.


  1. buratino
    10.07.2022 15:27
    +2

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

    ээээээээээээээээ. Что-то я не помню, чтобы с шумом боролись таким оригинальным способом


    1. F0iL
      10.07.2022 15:45
      +1

      Кажется здесь имеется в виду не шум, а дребезг.


      1. buratino
        10.07.2022 17:26

        дребезг аналогового сигнала? Ээээээээ....Кажется автор зарапортовался... Или аналоговый сигнал с шумом, или дребезг дискретного сигнала. (Надо наверное победить лень и написать статью для Хабра про дребезг) Гистерезис обычно используют при включении дискретного сигнала (например, включение нагревателя) по хорошему, т.е. сглаженному аналоговому, чтобы это самое включение в момент перехода порога не изнасиловало конечное устройство. Тут же судя по картинке и последним изменениям предлагается какой-то гибрид... Скрестить ужа и ежа и программным способом сделать из говна конфетку


        1. Indemsys
          10.07.2022 17:56
          +1

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


          1. buratino
            10.07.2022 19:05

            эээээ... ну если не расслабляться при написании комментов, то надо бы уточнять, что под дребезгом обычно понимают дребезг контактов и даже Википедия только про такой дребезг упоминает https://ru.wikipedia.org/w/index.php?title=Дребезг_контактов&stable=0&redirect=no а что там в сигма-дельте я как-то не сильно соображаю


    1. aabzel Автор
      10.07.2022 19:22

      Считайте что на цифровой фильтр просто нет ресурсов памяти.


      1. buratino
        10.07.2022 21:31
        +1

        на самый лапидарный фильтр никакой памяти не нужно

        	X = (X + ReadADC())/2;

        С тремя или 5 точками нужно память на эти 3 или 5 точек

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


        1. fk0
          11.07.2022 00:41
          +3

          Это называется exponentially weighted moving average фильтр. Он на самом деле не очень, как и обычное скользящее среднее: ВЧ компоненты сигнала подавляются так себе, как и АЧХ может оказаться неудобной. КИХ/БИХ фильтр может оказаться лучше (но вычислительная сложность выше).

          И не обязательно делить на два. В общем случае такой фильтр записывается как y = (x + K*y[-1]) / (2^N). Умножение обычно сейчас все МК умеют буквально за такт, а деление -- сдвигами. Варьируя K и N можно получать разную АЧХ.

          Если задача отфильтровать узкополосную помеху с известными характеристиками (например, характерную помеху от GSM-телефона), то лучше гребенчатый фильтр, где y = x + K*x[-N]. Т.е. сигнал суммируется со своей задержанной версией домноженной на какой-то коэффициент.


          1. buratino
            11.07.2022 10:30

            И не обязательно делить на два

            лениво просто было писать X = (X*M +ReadADC()*N)/(M+N); и там добавляется умножение(я) и следить за нюансами с возможным переполнением надо. С ацп обычно читают меньше 16 бит, поэтому сложить и поделить на два - самое лапидарное и кондовое


      1. Hlad
        10.07.2022 22:02
        +1

        На БИХ-фильтр нет памяти????


        1. fk0
          11.07.2022 00:42

          На него нужна плавающая точка или достаточно высокая разрядность с фиксированной точкой. Иначе все пойдет вразнос.


    1. COKPOWEHEU
      11.07.2022 10:00

      ээээээээээээээээ. Что-то я не помню, чтобы с шумом боролись таким оригинальным способом
      А почему нет? Скажем, если надо сигнал вывести на индикатор, и чтобы младшие разряды не мигали постоянно. Градусник там уличный, например.


      1. buratino
        11.07.2022 10:11

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

        2. от "больших" всплесков/выбросов это никак не спасает


        1. COKPOWEHEU
          11.07.2022 13:29

          1. выводить среднее за допустим минуту, ну и раз в минуту мигнуть — не проблема.
          2. от «больших» всплесков/выбросов это никак не спасает
          Вот вы сами и описали преимущество использования гистерезиса: менять показания именно тогда, когда меняется само значение, а не тупо по времени. Пусть и ценой потери пары младших разрядов.


          1. buratino
            11.07.2022 13:49

            я это не описывал. Более того, нет никакого смысла выводить показания, когда меняется само значение. АЦП может выдавать вам 100 тысяч измерений в секунду, шум/наводки там могут быть намного больше 2 младших разрядов, а глазки человеческие в лучшем случае заметят 10 раз за секунду, а сообразят - раз в секунду, а раздражать не будет при изменении раз в десять секунд. А простое осреднение вам наоборот добавит пару разрядов в точности измерения, а с фильтрацией - еще пару...


            1. COKPOWEHEU
              11.07.2022 15:44
              +1

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

              А простое осреднение вам наоборот добавит пару разрядов в точности измерения, а с фильтрацией — еще пару...
              Но от мигания все равно не избавятся.
              К тому же эти способы друг друга не исключают: вы можете накопить 100500 измерений (и поднять точность), использовать их для каких-то расчетов, а потом прогнать через гистерезис и отобразить на экране. Автоматике-то, понятное дело, мигание на ±1 по барабану, оно только человеку мешает.
              АЦП может выдавать вам 100 тысяч измерений в секунду, шум/наводки там могут быть намного больше 2 младших разрядов
              Если шумов столько, что пробивают фильтры измерителя, такое мигание даст понять пользователю, что точность просела ниже допустимого и на показания полагаться в любом случае нельзя.
              P.S. я не понимаю, что вы пытаетесь доказать. Что гистерезис на аналоговых сигналах всегда бесполезен?


              1. buratino
                11.07.2022 23:19

                Но от мигания все равно не избавятся.

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

                Если шумов столько, что пробивают фильтры измерителя,

                какие такие фильтры в условиях задачи? В условиях задачи сигнал зашумлен, но про характеристики этого шума ничего не сказано. Можно конечно потеоретизировать насчет этого шума, а можно взять в руки осциллограф и посмотреть на сигнал. Особенно хорошо на него смотреть разговаривая по мобильнику..

                такое мигание даст понять пользователю,

                ничего оно ему не даст, потому что пользователь его просто не увидит. Например, типичная ситуация с наводкой 50 Гц. Словили такую помеху и ваш гистерезис будет успешно моргать с этой частотой, которая глазом не заметна....

                P.S. я не понимаю, что вы пытаетесь доказать.

                я пытаюсь доказать что неплохо бы изредка читать учебники по обработке сигналов


                1. COKPOWEHEU
                  12.07.2022 09:12

                  Выше вам было сказано что логично осреднять одну минуту и выводить результат
                  Что ж вы ответ-то на это высказывание не процитировали заодно? Вам было сказано, что резкие изменения гистерезис пропускает в отличие от простого усреднения.
                  какие такие фильтры в условиях задачи?
                  Угу, учитывая что конкретной задачи у нас и нет.
                  ничего оно ему не даст, потому что пользователь его просто не увидит. Например, типичная ситуация с наводкой 50 Гц. Словили такую помеху и ваш гистерезис будет успешно моргать с этой частотой, которая глазом не заметна....
                  50 Гц незаметна? Это вы явно динамическую индикацию никогда не делали. Там минимум 100 Гц надо, а лучше еще больше чтобы не было бесячего мерцания сегментов.
                  А уж если цифры сменяются 50 раз в секунду то это невозможно НЕ заметить.
                  Впрочем, в реальности сменять цифры на индикаторе чаще 10 Гц смысла нет. И тут становится видна разница: либо значение быстро-быстро прыгает между 999 и 1000, либо нет.


                  1. buratino
                    12.07.2022 10:19

                    Что ж вы ответ-то на это высказывание не процитировали заодно? Вам было сказано, что резкие изменения гистерезис пропускает в отличие от простого усреднения.

                    Внимательно смотрим на приведенную в условии картинку. Там предлагается гистерезис в 5% от максимума аналогового сигнала. Если у нас максимум 3.3 В, то 5% это 0.165 В. Как-то на резкое изменение не тянет.

                    50 Гц незаметна? Это вы явно динамическую индикацию никогда не делали.

                    а нафиг такие индикаторы, на которых 50 гц заметно? И наверняка не сами 50 гц, а какие нибудь биения. Тем более борьба с этим программными средствами? (тут надо бы поставить картинку с пальцами в растопырку ;-)

                    Опять же, замечу, что это было предложено не для какого-нить шибко умного прибора с теплой ламповой неоновой индикацией времен когда водка была слаще а девки толще, а для градусника на окошке


                    1. COKPOWEHEU
                      12.07.2022 13:22

                      Внимательно смотрим на приведенную в условии картинку.
                      А вы не хотите сначала озвучить ваше конкретное условие и только потом его обсуждать? 5% откуда-то взялось…
                      5% от максимума аналогового сигнала. Если у нас максимум 3.3 В, то 5% это 0.165 В. Как-то на резкое изменение не тянет.
                      Изменение более чем на 0.165 В не тянет на резкое изменение? То ли у вас весьма оригинальные представления о скорости изменения сигналов, то ли о способе формулировки мыслей.
                      Не говоря уж о том, что вы, похоже, рассматриваете какую-то свою задачу, формулировку которой забыли написать.
                      а нафиг такие индикаторы, на которых 50 гц заметно?
                      Я вам задам встречный вопрос: как реализовать динамическую индикацию на индикаторах, на которых даже 50 Гц незаметно? Она как бы частые переключения предполагает, и остаточное свечение предыдущего разряда будет здорово мешать.
                      Опять же, замечу, что это было предложено не для какого-нить шибко умного прибора с теплой ламповой неоновой индикацией времен когда водка была слаще а девки толще, а для градусника на окошке
                      А что, вас удивляет, что достаточно простую задачу решают простыми способами без извращений? Может, вместо семисегментника вы хотите на плазменную панель показания выводить?


                      1. buratino
                        12.07.2022 13:47
                        +1

                        5% откуда-то взялось…

                        Повторяю, внимательно смотрим на

                        https://hsto.org/r/w1560/getpro/habr/upload_files/9c5/1db/90a/9c51db90aa3b17fd4a60fb7243e2a04d.png


                      1. COKPOWEHEU
                        12.07.2022 18:21
                        +1

                        Повторяю: прежде чем обсуждать какую-то свою задачу, ее было бы неплохо сформулировать. Откуда эта картинка, к чему она относится?


  1. Albert2009ru
    11.07.2022 00:33
    +2

    А мне понравилось. Работаю в эмбеддед, но с PIC и AVR старыми, пока успешно. Процентов 70% вопросов для меня новые и непонятные, даже по железу.

    Однако, как заметили многие, было бы супер дать ответы. Даже ценой объёма нескольких статей. ????????????


    1. Demonter
      11.07.2022 11:39
      +3

      Коллега, не надо так. Переходите на свежие камни, хотя бы на хобби проектах. Аппаратные ресурсы и периферия совершенно несопоставимы. Сложность в освоении тоже, но она оправдана.


      1. Albert2009ru
        12.07.2022 10:27
        +1

        Спасибо большое. Видимо Вселенная услышала Вас, однако весьма специфично. Вчера шеф решил прикрепить меня к одному гуру трассировки плат и FPGA эксперту в качестве разработчика-подмастерья для Cortex A9 ядер. Но, ёлки-палки, под Altera Cyclone 5 :(((((

        Я было начал, а почему не Xilinx Zynq, ведь так я смогу быстрее быть в теме нюансов, да и домой платку китайскую для экспериментов менее проблематично приобрести? Сказали нет...

        Будем осваивать :)


  1. Myclass
    11.07.2022 00:42
    +1

    У меня в закладках лежит статья Артура Тележкина от 2016-го года. Думаю, не помешает на неё вновь указать. Хоть в ней и большей частью упор на начинающих был.

    Советы начинающим программистам микроконтроллеров


  1. alexzeed
    11.07.2022 01:47
    +3

    А я не согласен с требующими ответов (и тем более не понимаю, за что автору минусов накидали). Хороший список, обсуждаемые вопросы. Если мне бы их дали на собесе лет в 20 — на больше половины бы не ответил, но очень порадовался и пошел бы искать остальные ответы. Если дать сейчас — отвечу на почти все, сделаю несколько замечаний по формулировкам и почему так не надо делать и пошлю нафиг такую контору :).
    Замечание 1: вопрос «Какие есть способы передачи переменных в С функцию» режет слух. Имелась в виду передача аргументов? Или таки адресов переменных? (А если мы про С, то там же даже ссылок нет, только указателем и можно передать адрес переменной).


    1. aabzel Автор
      11.07.2022 12:19

      Передать можно через регистры, регистры процессора, RAM, Flash.


      1. iliasam
        11.07.2022 20:48

        "Месье знает толк в извращениях!"


  1. kolyandex
    11.07.2022 06:03
    +1

    Что делать в случае плохого контакта в отладочном разъёме?


    1. aabzel Автор
      11.07.2022 12:15

      Помазать ртутью Hg. )


      1. Albert2009ru
        11.07.2022 12:37
        +1

        Предварительно побрызгав святой водой ;)


    1. aabzel Автор
      11.07.2022 15:51

      Можно передавать данные по радио или по инфракрасному интерфейсу. Там нет контактов.


  1. Kelbon
    11.07.2022 06:22
    +5

    От статьи прямо веет духом микроконтроллеров

    На все вопросы ответ либо не стандарт, либо УБ, либо не делайте так никогда, что вы творите.

    --Как делать инкапсуляцию в C?

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

    используйте уже С++, в самом деле, хватит издеваться над языком


    1. aabzel Автор
      11.07.2022 15:53

      В С++ нельзя взять адрес функции main(). Запрещено стандартом.
      Поэтому не сделаешь авто тест на корректность загрузки приложения, первичного загрузчика, вторичного загрузчика.

      Поэтому С++ плохо подходит для программирования микроконтроллеров.


      1. Kelbon
        11.07.2022 16:14
        +2

        ... Вы в статье творите такое, что взятие адреса main и рядом не стояло. Да и объективно тесты всё ещё возможны, любые


      1. buratino
        12.07.2022 10:25
        +1

        а нефиг при программировании микроконтроллеров пользовать STL и прочую подобную дребедень. Ну и во многих случаях в микроконтроллерах есть какой-нибудь startup_xxx.s


  1. ViacheslavMezentsev
    11.07.2022 07:30
    +1

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

    По последовательной линии приходит знаковое целое значение с количеством битов не кратным 8, т.е. не укладывающееся в стандартные типы intN_t. Каким способом можно привести такие сырые данные к стандартному знаковому целому типу?
    К примеру, int12 сохранён как есть в uint16 с 12-м знаковым битом и нужно получить число в виде int16.
    Варианты ответов (8 в 16 для удобства визуализации): https://godbolt.org/z/5Y57d61ET


    1. arlleex
      11.07.2022 21:03

      Со сдвигом - не универсальный вариант, т.к. implementation-defined behavior.


  1. ViacheslavMezentsev
    11.07.2022 18:55

    Между прочим, существуют подобные "тесты" для математиков, т.е. минимум, который народ должен понимать, если причисляет себя к математикам.

    Математический тривиум (В. И. Арнольд)

    Так что если и существует некий уровень культуры проектирования в области встраиваемых систем, то не плохо было бы по аналогии иметь похожий набор из 100 задач. То, что есть разные архитектуры, компиляторы и прочее - даже хорошо. И в математике возможны разные варианты решения одной задачи.

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

    По поводу секций и компоновки я мог бы интересную задачку задать, но, к сожалению, она частная. Вот попался мне 2-х ядерный ассиметричный отечественный 1901ВЦ1Т. Ведущее там Cortex-M3 ядро, ведомое - TMS320C546 (выше упоминался 16-битный char, он там такой). Так вот мой вопрос бы был в плане практики: как настроить скрипты компоновщиков обоих компиляторов, чтобы удобнее было бы загрузить и запустить на исполнение код DSP-ядра.
    Если с Cortex'ом ещё более менее понятно, то в старом техасском компиляторе придётся существенно помучится, чтобы получить прошивку, которая сама себя правильно восстановит, будучи запущенной. В DSP программа на C++.


  1. arlleex
    11.07.2022 19:16
    +1

    Много вопросов имеют несколько ответов, но что имел ввиду автор там весьма понятно для того, кто в теме.


  1. IgorPie
    12.07.2022 03:38
    +2

    Автор топит за кортекс м4, похоже.

    Для динамического выделения памяти - нужна операционочка. Если ее не, то и динамическое выделение - не нужно. Можно сделать буфер, который то кэш датафлэша или fatfs, то еще для каких нужд.

    Для генерации синуса он не нужен, на хабре 100500 статей по теме sin x= x, при малых x, на котором в пару умножений делается генерация синуса, что на мк, что на dsp.

    Чтобы разобраться с си, имхо хватит Кернигана и Ритчи. Полемизировать нечего, все легко и понятно.

    Из алгоритмов и сниппетов, которые лучше знать - это как фильтровать АЦП. Это есть в даташитах. Да и в целом, hpf/bpf/hpf резонансные и обычные надо уметь набрасывать.

    Как измерять производительность (у arm есть dwt, но есть и другие способы).

    Каскадное включение таймеров и измерение частоты часто пригождается.

    Линейная свертка. Как подразогнать.

    USB.

    Раз уж рисанулись про таймауты модбаса, рисанитесь уж и про tcp/ip/rip/arp, там местами тоже с таймингами весело.

    Надеюсь, сомневающийся прочтет эту ветку, и пойдет учить node js, чем нырять в эмбед. Там попроще, библиотеки все готовы, там аудитория, деньги, карьерный рост, работа в нормальных проектах, а не только с советской организацией труда.


    1. Myclass
      12.07.2022 08:15

      Браво. Все точно сказано. Особенно последний абзац. И дополнение к нему - а если уж сильно руки будут чесаться на микроконтроллеры, то дома всегда это можно как хобби иметь. Для удовольствия.


  1. Albert2009ru
    12.07.2022 08:48

    Ещё убила постановка вопроса - какие регистры есть у Cortex M4 или что-то типа того... Ну тогда в вдогонку задайте вопрос: "Назовите номера страниц мануала, где описаны функции HAL по работе с SPI?" Если не ответит, то всё, нечего такому в профессии делать... Немного абсурдно, или ?


    1. LennyB
      12.07.2022 11:52

      Ну это очень простой вопрос) Ни в референс мануале, ни в даташите функции HAL не описываются)


    1. aabzel Автор
      12.07.2022 11:55
      +2

      Этот вопрос задают на собеседовании программиста телематической платы в Яндекс.Драйв.