Добавлены локальные копии команд и обновлены файлы прошивки. Сохранены анализ слабых мест START/STOP и тесты воспроизведения ошибки ограничения ЦАП проекта 167.
7.8 KiB
Проверка ошибки ограничения 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 бит
возможен переход через границу. Для утверждений о фактическом токе
нужны реальные калибровочные параметры и измерения.
Как сценарий может возникнуть в работе
- В регистр modbus[0x51] (DAC_stop) записано 21 или больше; modbus[0x50] (DAC_go), например, равен 6.
- После завершения начальной паузы обработчик Load_runner наблюдает неактивный START, а затем активный: preStart=0 и cUMPstart=1.
- Параметры захватываются, выполняется ошибочное ограничение и начинается расчёт с завышенным начальным значением.
В 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 не переносились.