Как стать автором
Обновить

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

Уровень сложностиСложный
Время на прочтение13 мин
Количество просмотров15K
Всего голосов 40: ↑18 и ↓22-4
Комментарии126

Комментарии 126

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

дружище, не слушай их. Статья Ох уе нн ая!) Кому реально надо, кто реально заинтересован в своей специальности и становлении себя, как спеца, оценит и поймет пользу этой статьи. все, что я выискивал в течение не одного года, шарясь по разным источникам, формулируя запросы ( и не на одном языке), ты собрал в одном месте! Респект!

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

Так задумывалось?
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);

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

теперь да

Так то UB, unaligned memory access.

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

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

И так, и эдак выход за границу массива, нет?

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

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

Вопросы про RTOS

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

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

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

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

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

НЛО прилетело и опубликовало эту надпись здесь

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

НЛО прилетело и опубликовало эту надпись здесь

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

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

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

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

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

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

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

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

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

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

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

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

Как по мне самое ценное правило из MISRA это
14.7 (req) A function shall have a single point of exit at the end of the
function.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

НЛО прилетело и опубликовало эту надпись здесь

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

USB.

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

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

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

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

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

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

Яндекс.Драйв вообще презирает STM HAL там предпочитают SPL.

И вообще HAL используют подавляющее меньшинство компаний в РФ.
Все сидят на SPL или и вовсе используют только CMSIS.

Так что не беспокойтесь, про HAL вас точно никто спрашивать не будет.

Автор, давай вторую статью с ответами и Бог тебя простит)))

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

Ждем продолжения статьи с ответами.

Спасибо за статью!

Вдогонку

Вопрос для любителей алгоритмических секции технических интервью:

Вам вручили PCB плату с микроконтроллером, чтобы прошить чип. 

Вы подключаетесь программатором по SWD и с удивлением обнаруживаете, что нет link(а) с микроконтроллером. Программатор просто "не видит" Target

Ваши действия? Что вы предпримете, чтобы таки прошить микроконтроллер?

Вот еще хорошие вопросы про troubleshooting:


1--На микроконтроллер подали питание и прошивка не стартует. Ваши действия?

2--У вас прошивка зависла и свалилась в HardFault_Handler().
Что вы предпримете, чтобы понять почему это произошло и как починить?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории