Перейти к содержимому

Курс BeeFC: ответы на контрольные вопросы уровня «Старт» … ↩

Курс BeeFC: ответы на контрольные вопросы уровня «Старт» mod. Четверг, 15 октября 2026 22:55 . См. 1

BeeFC · Справочные материалы · Уровень «Старт»

Развёрнутые ответы на контрольные вопросы десяти уроков уровня «Старт». Сверяться с ответами рекомендуется только после того, как собственный ответ сформулирован.

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

Содержание

1. Урок S1. Беспилотная авиационная система и место полётного контроллера в ней

1. Из каких пяти частей состоит беспилотная авиационная система? — Из беспилотного воздушного судна, аппаратуры управления, канала связи, наземной станции управления и внешнего пилота.

2. Перечислите пять шагов цикла управления полётного контроллера. — Чтение гироскопа и акселерометра, фильтрация, расчёт управляющего воздействия регулятором, распределение воздействия по двигателям в микшере, передача команд регуляторам частоты вращения.

3. Почему частота цикла в Betaflight выше, чем в ArduCopter? — Betaflight рассчитан на пилотажные аппараты с малой инерцией, для которых важна минимальная задержка. ArduPilot расходует время процессора также на оценку состояния и навигацию, а для большинства его аппаратов частоты 400 Гц достаточно.

4. Чем запускается регулятор угловой скорости в PX4? — Появлением нового сообщения vehicle_angular_velocity: модуль подписан на это сообщение и выполняет метод Run() при каждом новом отсчёте.

5. Почему ядро BeeFC можно проверять тестами на компьютере? — Потому что ядро и драйверы не обращаются к регистрам микроконтроллера напрямую, а работают через уровень аппаратных абстракций, у которого есть поддельная реализация для тестов.

↑ К оглавлению

2. Урок S2. Инструменты разработки и первая прошивка

1. Почему запись в регистр MODER не действует, если не установлен бит в RCC->AHB1ENR? — После сброса тактирование порта выключено, и блок порта не принимает запись. Сначала необходимо включить тактирование порта битом в регистре RCC->AHB1ENR.

2. Чем файл формата ELF отличается от файла формата BIN? — ELF содержит код вместе с адресами секций и отладочной информацией, его понимают отладчик и OpenOCD. BIN — побайтный образ памяти без служебной информации, его записывает утилита dfu-util по указанному адресу.

3. Как запустить встроенный загрузчик STM32F405 на полётном контроллере? — Удерживать кнопку BOOT в момент подачи питания по USB: высокий уровень на выводе BOOT0 при сбросе запускает загрузчик из постоянной памяти.

4. Почему описание платы хранится отдельно от основного кода прошивки? — Микроконтроллер одинаковый, а подключение периферии у каждой платы своё. Отдельное описание позволяет поддерживать сотни плат одним исходным кодом.

5. Почему проверка в Renode не измеряет период мигания для пустого цикла задержки? — Модель выполняет инструкции не с той скоростью, что настоящий микроконтроллер, поэтому длительность программной задержки в модели не совпадает с реальной.

↑ К оглавлению

3. Урок S3. Устройство ядра Cortex-M4F: тактирование, память и запуск программы

1. Какие два слова читает ядро Cortex-M4 из начала флеш-памяти после сброса? — Начальное значение указателя стека и адрес обработчика сброса Reset_Handler.

2. Почему в функции SystemInit нельзя сохранять значения в глобальные переменные? — В файле запуска производителя SystemInit вызывается до копирования начальных значений переменных и до обнуления неинициализированных переменных, поэтому записанное значение будет затёрто.

3. Рассчитайте коэффициенты умножителя частоты для кварца 8 МГц и частоты ядра 168 МГц. — M = 4, вход генератора 2 МГц; N = 168, генератор 336 МГц; P = 2, ядро 168 МГц; Q = 7, USB 48 МГц.

4. Почему буфер приёма с прямым доступом к памяти нельзя размещать в CCM? — Память CCM подключена только к шине данных ядра, контроллер прямого доступа к памяти к ней доступа не имеет, поэтому передача не выполнится.

5. С какой частотой тактируются таймеры шины APB1 при частоте шины 42 МГц и почему? — С частотой 84 МГц: если делитель шины больше единицы, таймеры шины тактируются удвоенной частотой шины.

6. Как найти строку кода, вызвавшую аварийную остановку? — В обработчике HardFault_Handler прочитать сохранённый в стеке регистр PC и командой отладчика info line *адрес найти строку исходного кода.

↑ К оглавлению

4. Урок S4. Язык C для встраиваемых систем и архитектура BeeFC

1. Почему в BeeFC используются типы из stdint.h, а не int и long? — Разрядность int и long стандартом не фиксирована, а регистры и протоколы имеют точно заданную разрядность. Типы uint8_t, uint32_t и подобные имеют одинаковый размер на любом компиляторе.

2. Делает ли квалификатор volatile операцию counter++ атомарной? — Нет. Квалификатор запрещает компилятору кэшировать значение, но операция по-прежнему состоит из чтения, сложения и записи, и прерывание между ними может потерять изменение.

3. Почему запись уровня вывода выполняется через BSRR, а не через ODR? — Запись в BSRR выполняется одной инструкцией и затрагивает только выбранный вывод. Изменение ODR требует чтения, изменения и записи, и прерывание между ними может испортить состояние других выводов порта.

4. Какой заголовочный файл нельзя включать в модули каталога core и почему? — Заголовочные файлы микроконтроллера stm32f4xx.h и core_cm4.h. Иначе модуль перестанет собираться для компьютера и его нельзя будет проверить модульными тестами.

5. Почему константа 0.5 без суффикса замедляет вычисления на Cortex-M4F? — Константа без суффикса имеет тип double, и всё выражение вычисляется в двойной точности программно, потому что сопроцессор работает только с одинарной точностью.

↑ К оглавлению

5. Урок S5. Порты ввода-вывода, прерывания и контроллер прерываний NVIC

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

2. Можно ли одновременно использовать внешние прерывания на выводах PA4 и PC4? — Нельзя: оба вывода обслуживаются линией EXTI4, а линия подключается только к одному порту через регистр SYSCFG_EXTICR.

3. Что произойдёт, если в обработчике не сбросить флаг в регистре EXTI->PR? — Ядро сразу вызовет обработчик снова, и основная программа перестанет выполняться.

4. Когда для чтения общей переменной нужна критическая секция? — Когда переменная не помещается в одно выровненное 32-битное слово, например структура или значение типа uint64_t: её чтение занимает несколько инструкций и может быть прервано.

5. Что делает драйвер ICM-42688-P в PX4, если прерывание готовности данных не пришло? — Срабатывает резервный запуск, запланированный через удвоенный интервал; драйвер увеличивает счётчик пропущенных прерываний и читает количество измерений в очереди датчика напрямую.

↑ К оглавлению

6. Урок S6. Системное время и планировщик задач

1. Почему для системного времени выбран таймер TIM5, а не SysTick? — TIM5 32-битный и при отсчёте 1 мкс переполняется примерно через 71,6 минуты, работая без прерываний. SysTick 24-битный и требует обработчика прерывания для продолжения счёта.

2. Почему интервал вычисляется как now - start, а не сравнением now >= deadline? — Вычитание беззнаковых чисел выполняется по модулю \( 2^{32} \) и даёт верный интервал при переходе счётчика через ноль, а прямое сравнение моментов времени в этот момент ошибается.

3. Почему следующий срок задачи отсчитывается от предыдущего срока, а не от момента фактического запуска? — Иначе каждая задержка запуска добавлялась бы к периоду, и средняя частота задачи оказалась бы ниже заданной.

4. Почему задача с высоким приоритетом опаздывает, если задача с низким приоритетом выполняется дольше её периода? — Кооперативный планировщик не прерывает выполняющуюся задачу; приоритет влияет только на выбор следующей задачи.

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

↑ К оглавлению

7. Урок S7. Последовательный порт, прямой доступ к памяти и консоль

1. Сколько времени занимает передача одного байта в формате 8N1 на скорости 115 200 бод? — Кадр состоит из десяти битов, поэтому передаётся 11 520 байт в секунду, один байт примерно за 87 мкс.

2. Почему кольцевой буфер с одним производителем и одним потребителем работает без запрета прерываний? — Индекс записи изменяет только производитель, индекс чтения — только потребитель, и каждый индекс записывается одной инструкцией, поэтому стороны не мешают друг другу.

3. Зачем в функции rb_push нужен барьер компилятора? — Чтобы компилятор не перенёс запись байта в массив за изменение индекса head: иначе потребитель может прочитать ячейку раньше, чем в неё записан байт.

4. Как определить позицию записи DMA в кольцевом режиме? — Вычесть значение регистра NDTR, то есть число байт до конца буфера, из размера буфера.

5. Почему буфер приёма DMA нельзя размещать в CCM? — У контроллера прямого доступа к памяти нет доступа к CCM, поэтому передача в такой буфер не выполнится.

↑ К оглавлению

8. Урок S8. Таймеры и широтно-импульсная модуляция: первый запуск двигателя

1. Рассчитайте предделитель и период для частоты 50 Гц при отсчёте 1 мкс на таймере 84 МГц. — PSC = 83, частота отсчётов 1 МГц; ARR = 19 999, период 20 000 отсчётов, то есть 20 мс.

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

3. Почему BeeFC после запуска не выдаёт на двигатели импульсов вовсе? — Импульс с длительностью больше минимальной при включении питания может перевести регулятор в режим калибровки или запустить двигатель, а отсутствие импульсов регулятор воспринимает как безопасное состояние.

4. Зачем включается буферизация регистров CCR и ARR? — Чтобы новое значение вступало в силу с начала следующего периода; иначе запись в середине периода может дать один импульс неправильной длительности.

5. Как Betaflight выбирает драйвер протокола двигателей? — По настройке motorProtocol; модуль motor.c обращается к выбранному драйверу через таблицу функций motorDevice.vTable.

↑ К оглавлению

9. Урок S9. Аналого-цифровой преобразователь: напряжение и ток аккумуляторной батареи

1. Почему для входа делителя напряжения выбирается наибольшее время выборки АЦП? — Делитель имеет сопротивление порядка килоом, и за короткое время выборки внутренний конденсатор АЦП не успевает зарядиться до напряжения входа, показания получаются заниженными.

2. Какое напряжение попадёт на вход АЦП от заряженной батареи из шести элементов через делитель 1:11? — 25,2 В, делённые на 11, — примерно 2,29 В, что меньше опорного напряжения 3,3 В.

3. Почему автоматическое определение числа элементов ошибается на разряженной батарее? — Число элементов оценивается делением напряжения на наибольшее напряжение элемента; у сильно разряженной батареи из четырёх элементов частное оказывается меньше трёх, и она определяется как батарея из трёх элементов.

4. Чему равна постоянная времени фильтра первого порядка с частотой среза 10 Гц и что она означает? — \( \tau = 1/(2\pi \cdot 10) \approx 15{,}9 \) мс; за это время выход фильтра проходит 63,2 % пути к новому значению входа.

5. Зачем предупреждению о разряде гистерезис? — Под нагрузкой напряжение снижается и восстанавливается; без гистерезиса состояние переключалось бы туда и обратно при каждом изменении газа.

↑ К оглавлению

10. Урок S10. Итоговая работа уровня «Старт»: тяговый стенд, версия 1

1. Как HX711 сообщает о готовности данных и как выбирается усиление? — Низким уровнем на линии DOUT. Усиление и канал для следующего преобразования выбираются числом дополнительных импульсов после 24 бит данных: один — канал A с усилением 128, два — канал B с усилением 32, три — канал A с усилением 64.

2. Почему в драйвере HX711 от прерываний защищается каждый импульс, а не всё чтение? — Импульс длиннее 60 мкс переводит HX711 в режим пониженного энергопотребления, поэтому импульс защищается. Всё чтение длится около 50 мкс, и запрет прерываний на это время привёл бы к потере байтов последовательного порта.

3. Как рассчитывается цена кода тензодатчика? — Масса эталонного груза делится на разность усреднённого показания с грузом и показания без нагрузки.

4. Почему первые 0,5 секунды каждой ступени не учитываются при обработке? — В это время двигатель разгоняется до новой частоты вращения, и тяга с током ещё не установились.

5. Почему в Betaflight значения из вкладки двигателей действуют только при заблокированных двигателях? — Обработчик MSP_SET_MOTOR записывает их в массив motor_disarmed[], который используется только в заблокированном состоянии; так проверка двигателей не может вмешаться в полёт.

↑ К оглавлению
  • мод. : Четверг, 15 октября 2026