Files
Balsam_166/Doc/DAC167_limit_test_results.md
andrey 085b587167 Исправлена обработка фронтов START/STOP в 166
Добавлены локальные копии команд и обновлены файлы прошивки. Сохранены анализ слабых мест START/STOP и тесты воспроизведения ошибки ограничения ЦАП проекта 167.
2026-09-22 12:37:24 +03:00

7.8 KiB
Raw Blame History

Проверка ошибки ограничения DAC_stop в 167

Дата: 22.09.2026.

Результат

Выполнены 7 тестов, все прошли. Это тесты воспроизведения существующей ошибки: успешный результат означает, что описанные сценарии подтверждены расчётной моделью. Код прошивки не изменялся, проверки на устройстве не было.

Ошибка возникает при DAC_stop > 20 в момент захвата параметров на фронте START. В коде сначала вычисляется dac_stop = DAC_stop - 4, поэтому условие dac_stop > 16 впервые выполняется при DAC_stop = 21. Оно ошибочно присваивает dac_go = 16, отменяя ранее применённое ограничение начального значения до 5. Конечное значение не ограничивается.

Для неотрицательных значений DAC_stop проверен весь диапазон 0..32767 и 10 вариантов DAC_go: -100, 0, 4, 6, 8, 9, 10, 20, 100, 32767. Всего перебрано 327 680 пар. Отличие от варианта с исправленной строкой обнаруживается ровно при DAC_stop > 20.

Граничные примеры

DAC_go и DAC_stop — входные параметры, dac_go и dac_stop — внутренние значения после вычитания 4 и проверок. Таблица показывает именно внутренние значения, а не измеренный ток и не 12-битный код ЦАП.

DAC_go DAC_stop Сейчас: dac_go → dac_stop При исправлении опечатки Проявление
6 16 2 → 12 2 → 12 Штатные значения из Default_params(), ошибки нет
6 19 2 → 15 2 → 15 Ошибки нет
6 20 2 → 16 2 → 16 Верхняя граница без ошибки
6 21 16 → 17 2 → 16 Первый входной уровень, вызывающий ошибку
6 22 16 → 18 2 → 16 Начало поднято до 16, конец не ограничен
6 30 16 → 26 2 → 16 То же, с большим превышением
4 21 16 → 17 0 → 16 Начало 0 заменено на 16
9 21 16 → 17 5 → 16 Разрешённое начало 5 заменено на 16
20 21 16 → 17 5 → 16 Предварительное ограничение начала до 5 отменено

Под «исправлением» здесь понимается только замена if(dac_stop>16) dac_go=16; на if(dac_stop>16) dac_stop=16;. Другие правила расчёта не менялись.

Что получает Anal_output

Для DAC_go=6, DAC_stop=21, LOAD_TIME=30 и DAC_FREQ=200: time_dac = 6000. При запуске из состояния с обнулённым count_load первый расчёт выполняется при count_load=1.

Точка Текущий kod kod при исправлении maxx
Первый расчёт 6000 750 6000
Конец нарастания 6375 6000 6000

Таким образом, вместо начала с 12,5% шкалы интерполяции код сразу задаёт 100%, а в конце — 106,25%. Это аргументы функции Anal_output, не непосредственные значения, отправляемые в ЦАП.

Физический ток определяется калибровкой DAC_min()/DAC_max() и аппаратной схемой. Формула в Anal_output интерполирует между этими значениями; направление изменения численного кода ЦАП зависит от калибровки. В режиме cCalibrDac результат заменяется DAC_cal(), поэтому рассчитанное нарастание не определяет выход. Последующее out & 0xFFF маскирует число, а не насыщает его на границе диапазона; при выходе за 12 бит возможен переход через границу. Для утверждений о фактическом токе нужны реальные калибровочные параметры и измерения.

Как сценарий может возникнуть в работе

  1. В регистр modbus[0x51] (DAC_stop) записано 21 или больше; modbus[0x50] (DAC_go), например, равен 6.
  2. После завершения начальной паузы обработчик Load_runner наблюдает неактивный START, а затем активный: preStart=0 и cUMPstart=1.
  3. Параметры захватываются, выполняется ошибочное ограничение и начинается расчёт с завышенным начальным значением.

В ReceiveCommandModbus6 есть прямая запись значения регистра, а в приёме CAN — проверка адреса без ограничения значения DAC_stop до 20. Поэтому по этим путям код 167 сам не исключает такую настройку. Ограничения внешнего пульта/ПО и текущие параметры устройства не проверены.

Если изменить DAC_stop во время непрерывно активного START, локальные параметры не перечитываются на каждом вызове. Ошибка проявится при следующем захвате параметров. Стандартные значения DAC_go=6 и DAC_stop=16 эту ветку не вызывают.

Файлы и запуск

Тест: tests/test_dac167_limit.py в проекте 166. Он читает соседний 167/Source/Internal/DAC.c и проверяет совпадение моделируемого блока с исходником, чтобы изменение кода не осталось незамеченным.

Запуск из корня 166:

py -3 -B -m unittest discover -s tests -p test_dac167_limit.py -v

Модель проверяет ограничения параметров и выбранные точки формулы. Это не запуск скомпилированной прошивки и не эмуляция C2000. Перебор больших значений проверяет только блок ограничения: дальнейшее преобразование float в 16-битный int может выйти за диапазон и модель не делает прогнозов для такого выхода. Значения -32768..-32765 исключены из модели вычитания 4 из signed int из-за переполнения; это проверяется отдельным тестом. Конкурентные обновления CAN и временные характеристики прерываний этими тестами не моделируются.

В прошивке 166 рассматриваемого блока нет. Тест и отчёт сохранены здесь для анализа 167; изменения DAC.c из 167 в 166 не переносились.