Files
Balsam_167/Doc/GAS_MODBUS_MAP.md
Andrey 1e911e5250 Обновить логгер УМП и исправить запуск UART и EEPROM
Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
2026-10-12 12:25:41 +03:00

24 KiB
Raw Blame History

GAS ↔ Modbus: карта регистров Бальзам 167

Профиль: GAS 167/v1. Соответствие проверено по исходникам проекта на 9 октября 2026 года.

УКСС выделен сквозной диапазон 0…11999 с блоком 1000 ID на номер узла: GAS_ADDRESS_ALLOCATION.md. В полной таблице приведены текущие адреса прошивки 167/v1 и новые назначенные ID УМП 1/2. Новая нумерация пока не перенесена в прошивку.

GAS предоставляет доступ к тем же значениям modbus[], что и штатные адреса Modbus. В Modbus RTU можно обращаться как по прежнему адресу 0x0000…0x007F, так и по GAS-адресу 0x5000…0x507F. Это два адреса одного слова RAM; отдельной копии параметров нет.

GAS доступен только при EEPROM_M95M02=1. В текущем eeprom_config.h по умолчанию задано 0 — сборка для AT25256B, в которой GAS-окна отсутствуют. Фактическая сборка может переопределять этот параметр.

Правило соответствия

Для штатного адреса n = 0…127:
    GAS-адрес          = 0x5000 + n
    Штатный Modbus     = GAS-адрес - 0x5000
    Источник значения  = modbus[n]

Пример: modbus[0x52] → штатный адрес 0x0052 (82)
                    → GAS-адрес     0x5052 (20562)

Новая сквозная карта (десятичные ID):
    УМП 1, номер 5: GAS_ID = 5000 + n
    УМП 2, номер 6: GAS_ID = 6000 + n
    modbus[0x52] → УМП 1: 5082; УМП 2: 6082

Столбцы Modbus и GAS 167/v1 содержат нулевые адреса из поля запроса, без прибавления единицы и без префикса 4xxxx. Столбцы «Новый ID УМП 1/2» содержат назначенные ID новой сквозной карты; текущая прошивка ещё не обслуживает их как новые GAS-адреса. Каждый адрес обозначает одно 16-битное слово raw. Знаковость, единицы и масштаб зависят от параметра и типа платы Desk; GAS передаёт исходное слово.

Область Штатный Modbus GAS / адрес обращения через Modbus RTU Слова Доступ
Технологические регистры 0x0000…0x007F 0x5000…0x507F 128 RW с исключениями LOAD
Информация GAS-профиля Нет штатного аналога 0x5F00…0x5F07 8 RO

RW в документе означает, что обработчик разрешает FC06. Измерения и статусы могут затем обновляться прошивкой; разрешение записи само по себе не делает такой регистр уставкой. RO означает, что обработчик отклоняет запись.

Полное соответствие 128 технологических регистров

Имена взяты из package.h, measure.c, ADC.c и DAC.c. Индексы sens_* начинаются с нуля. Конкретное назначение каналов зависит от платы; таблица не назначает всем платам одинаковые физические каналы.

Перекрывающиеся имена относятся к одному слову и используются в разных режимах. Например, 0x0052 входит в общий диапазон sens_lo_edge[], а на LOAD служит LOAD_CAN_TIMEOUT.

Modbus, hex Modbus, dec GAS 167/v1, hex GAS 167/v1, dec Новый ID УМП 1, dec Новый ID УМП 2, dec Имя / источник Доступ
0x0000 0 0x5000 20480 5000 6000 sens_error[0]; InputRep0/1/2 — биты A/B/C RW
0x0001 1 0x5001 20481 5001 6001 sens_error[1] RW
0x0002 2 0x5002 20482 5002 6002 sens_error[2] RW
0x0003 3 0x5003 20483 5003 6003 sens_error[3] RW
0x0004 4 0x5004 20484 5004 6004 sens_error[4] RW
0x0005 5 0x5005 20485 5005 6005 sens_error[5] RW
0x0006 6 0x5006 20486 5006 6006 sens_error[6] RW
0x0007 7 0x5007 20487 5007 6007 sens_error[7] RW
0x0008 8 0x5008 20488 5008 6008 sens_error[8] RW
0x0009 9 0x5009 20489 5009 6009 sens_error[9] RW
0x000A 10 0x500A 20490 5010 6010 sens_error[10] RW
0x000B 11 0x500B 20491 5011 6011 sens_error[11] RW
0x000C 12 0x500C 20492 5012 6012 sens_error[12] RW
0x000D 13 0x500D 20493 5013 6013 sens_error[13] RW
0x000E 14 0x500E 20494 5014 6014 sens_error[14] RW
0x000F 15 0x500F 20495 5015 6015 sens_error[15] RW
0x0010 16 0x5010 20496 5016 6016 sens_error[16]; Inputs RW
0x0011 17 0x5011 20497 5017 6017 sens_error[17] RW
0x0012 18 0x5012 20498 5018 6018 sens_error[18] RW
0x0013 19 0x5013 20499 5019 6019 sens_error[19] RW
0x0014 20 0x5014 20500 5020 6020 sens_error[20] RW
0x0015 21 0x5015 20501 5021 6021 sens_error[21] RW
0x0016 22 0x5016 20502 5022 6022 sens_error[22]; Buttons RW
0x0017 23 0x5017 20503 5023 6023 sens_error[23]; Jumpers RW
0x0018 24 0x5018 20504 5024 6024 sens_data[0] RW
0x0019 25 0x5019 20505 5025 6025 sens_data[1] RW
0x001A 26 0x501A 20506 5026 6026 sens_data[2] RW
0x001B 27 0x501B 20507 5027 6027 sens_data[3] RW
0x001C 28 0x501C 20508 5028 6028 sens_data[4]; LOAD: расчётный выход 4–20 мА, raw ×10 RW
0x001D 29 0x501D 20509 5029 6029 sens_data[5]; LOAD: измеренный вход 4–20 мА, raw ×10 RW
0x001E 30 0x501E 20510 5030 6030 sens_data[6] RW
0x001F 31 0x501F 20511 5031 6031 sens_data[7] RW
0x0020 32 0x5020 20512 5032 6032 sens_data[8] RW
0x0021 33 0x5021 20513 5033 6033 sens_data[9] RW
0x0022 34 0x5022 20514 5034 6034 sens_data[10] RW
0x0023 35 0x5023 20515 5035 6035 sens_data[11] RW
0x0024 36 0x5024 20516 5036 6036 sens_data[12] RW
0x0025 37 0x5025 20517 5037 6037 sens_data[13] RW
0x0026 38 0x5026 20518 5038 6038 sens_data[14] RW
0x0027 39 0x5027 20519 5039 6039 sens_data[15] RW
0x0028 40 0x5028 20520 5040 6040 sens_data[16] RW
0x0029 41 0x5029 20521 5041 6041 sens_data[17] RW
0x002A 42 0x502A 20522 5042 6042 sens_data[18] RW
0x002B 43 0x502B 20523 5043 6043 sens_data[19] RW
0x002C 44 0x502C 20524 5044 6044 sens_data[20] RW
0x002D 45 0x502D 20525 5045 6045 sens_data[21] RW
0x002E 46 0x502E 20526 5046 6046 sens_data[22] RW
0x002F 47 0x502F 20527 5047 6047 sens_data[23] RW
0x0030 48 0x5030 20528 5048 6048 sens_hi_edge[0] RW
0x0031 49 0x5031 20529 5049 6049 sens_hi_edge[1] RW
0x0032 50 0x5032 20530 5050 6050 sens_hi_edge[2] RW
0x0033 51 0x5033 20531 5051 6051 sens_hi_edge[3] RW
0x0034 52 0x5034 20532 5052 6052 sens_hi_edge[4] RW
0x0035 53 0x5035 20533 5053 6053 sens_hi_edge[5] RW
0x0036 54 0x5036 20534 5054 6054 sens_hi_edge[6] RW
0x0037 55 0x5037 20535 5055 6055 sens_hi_edge[7] RW
0x0038 56 0x5038 20536 5056 6056 sens_hi_edge[8] RW
0x0039 57 0x5039 20537 5057 6057 sens_hi_edge[9] RW
0x003A 58 0x503A 20538 5058 6058 sens_hi_edge[10] RW
0x003B 59 0x503B 20539 5059 6059 sens_hi_edge[11] RW
0x003C 60 0x503C 20540 5060 6060 sens_hi_edge[12] RW
0x003D 61 0x503D 20541 5061 6061 sens_hi_edge[13] RW
0x003E 62 0x503E 20542 5062 6062 sens_hi_edge[14] RW
0x003F 63 0x503F 20543 5063 6063 sens_hi_edge[15] RW
0x0040 64 0x5040 20544 5064 6064 sens_hi_edge[16] RW
0x0041 65 0x5041 20545 5065 6065 sens_hi_edge[17] RW
0x0042 66 0x5042 20546 5066 6066 sens_hi_edge[18] RW
0x0043 67 0x5043 20547 5067 6067 sens_hi_edge[19] RW
0x0044 68 0x5044 20548 5068 6068 sens_hi_edge[20] RW
0x0045 69 0x5045 20549 5069 6069 sens_hi_edge[21] RW
0x0046 70 0x5046 20550 5070 6070 sens_hi_edge[22] RW
0x0047 71 0x5047 20551 5071 6071 sens_hi_edge[23] RW
0x0048 72 0x5048 20552 5072 6072 sens_lo_edge[0] RW
0x0049 73 0x5049 20553 5073 6073 sens_lo_edge[1] RW
0x004A 74 0x504A 20554 5074 6074 sens_lo_edge[2] RW
0x004B 75 0x504B 20555 5075 6075 sens_lo_edge[3] RW
0x004C 76 0x504C 20556 5076 6076 sens_lo_edge[4] RW
0x004D 77 0x504D 20557 5077 6077 sens_lo_edge[5] RW
0x004E 78 0x504E 20558 5078 6078 sens_lo_edge[6] RW
0x004F 79 0x504F 20559 5079 6079 sens_lo_edge[7] RW
0x0050 80 0x5050 20560 5080 6080 sens_lo_edge[8]; LOAD: DAC_go — параметр начала рампы RW
0x0051 81 0x5051 20561 5081 6081 sens_lo_edge[9]; LOAD: DAC_stop — параметр конца рампы RW
0x0052 82 0x5052 20562 5082 6082 sens_lo_edge[10]; LOAD: LOAD_CAN_TIMEOUT, мс RW; LOAD: 1…60000
0x0053 83 0x5053 20563 5083 6083 sens_lo_edge[11] RW
0x0054 84 0x5054 20564 5084 6084 sens_lo_edge[12] RW
0x0055 85 0x5055 20565 5085 6085 sens_lo_edge[13] RW
0x0056 86 0x5056 20566 5086 6086 sens_lo_edge[14] RW
0x0057 87 0x5057 20567 5087 6087 sens_lo_edge[15] RW
0x0058 88 0x5058 20568 5088 6088 sens_lo_edge[16] RW
0x0059 89 0x5059 20569 5089 6089 sens_lo_edge[17] RW
0x005A 90 0x505A 20570 5090 6090 sens_lo_edge[18] RW
0x005B 91 0x505B 20571 5091 6091 sens_lo_edge[19] RW
0x005C 92 0x505C 20572 5092 6092 sens_lo_edge[20] RW
0x005D 93 0x505D 20573 5093 6093 sens_lo_edge[21] RW
0x005E 94 0x505E 20574 5094 6094 sens_lo_edge[22] RW
0x005F 95 0x505F 20575 5095 6095 sens_lo_edge[23] RW
0x0060 96 0x5060 20576 5096 6096 Cancount[m_FAST] — пауза быстрых посылок CAN RW
0x0061 97 0x5061 20577 5097 6097 Cancount[m_SLOW] — пауза медленных посылок CAN RW
0x0062 98 0x5062 20578 5098 6098 Brightness / Bright[0] — яркость RW
0x0063 99 0x5063 20579 5099 6099 Owncount / Bright[1]; LOAD: исходное значение АЦП RW
0x0064 100 0x5064 20580 5100 6100 Bright[2]; Current_count: исходное значение канала 0 RW
0x0065 101 0x5065 20581 5101 6101 Bright[3]; Current_count: исходное значение канала 1 RW
0x0066 102 0x5066 20582 5102 6102 Bright[4]; Current_count: исходное значение канала 2 RW
0x0067 103 0x5067 20583 5103 6103 Bright[5]; Current_count: исходное значение канала 3 RW
0x0068 104 0x5068 20584 5104 6104 lev_count[], запись из Current_count; назначение по режиму RW
0x0069 105 0x5069 20585 5105 6105 lev_count[], запись из Current_count; назначение по режиму RW
0x006A 106 0x506A 20586 5106 6106 lev_count[], запись из Current_count; назначение по режиму RW
0x006B 107 0x506B 20587 5107 6107 lev_count[], запись из Current_count; назначение по режиму RW
0x006C 108 0x506C 20588 5108 6108 lev_count[], запись из Current_count; назначение по режиму RW
0x006D 109 0x506D 20589 5109 6109 lev_count[], запись из Current_count; назначение по режиму RW
0x006E 110 0x506E 20590 5110 6110 DAC_20 — калибровка входа 20 мА RW
0x006F 111 0x506F 20591 5111 6111 DAC_04 — калибровка входа 4 мА RW
0x0070 112 0x5070 20592 5112 6112 Zero_lev[0] — нулевой уровень канала тока 0 RW
0x0071 113 0x5071 20593 5113 6113 Zero_lev[1] — нулевой уровень канала тока 1 RW
0x0072 114 0x5072 20594 5114 6114 Zero_lev[2] — нулевой уровень канала тока 2 RW
0x0073 115 0x5073 20595 5115 6115 Zero_lev[3] — нулевой уровень канала тока 3 RW
0x0074 116 0x5074 20596 5116 6116 Caliber[0]: K380_1 / KPOW_1 RW
0x0075 117 0x5075 20597 5117 6117 Caliber[1]: K380_2 / KPOW_2 RW
0x0076 118 0x5076 20598 5118 6118 Caliber[2]: KPOW_3 RW
0x0077 119 0x5077 20599 5119 6119 Caliber[3]: KPOW_4 RW
0x0078 120 0x5078 20600 5120 6120 Caliber[4] / TCaliber[0]; LOAD: DAC_max() RW
0x0079 121 0x5079 20601 5121 6121 Caliber[5] / TCaliber[1]; LOAD: DAC_min() RW
0x007A 122 0x507A 20602 5122 6122 Caliber[6] / TCaliber[2]; LOAD: DAC_cal() RW
0x007B 123 0x507B 20603 5123 6123 Caliber[7] / TCaliber[3]; LOAD: текущий 12-битный код ЦАП RW
0x007C 124 0x507C 20604 5124 6124 NormaU = Caliber[8]; LOAD: LOAD_STATUS RO для LOAD; иначе RW
0x007D 125 0x507D 20605 5125 6125 DeltaU = Caliber[9]; LOAD: LOAD_MAX_ATTEMPTS, лимит пусков RW; для LOAD 1…65535
0x007E 126 0x507E 20606 5126 6126 LastMode RW
0x007F 127 0x507F 20607 5127 6127 Commands — битовая маска команд RW

Слово modbus[128] в массиве используется для CRC сохраняемых параметров и не входит в эту карту. 0x5080 не является допустимым GAS-адресом.

Информация GAS-профиля

Эти слова читаются через FC03 непосредственно по адресам 0x5F00…0x5F07. Для них нет соответствующих штатных регистров 0x0000…0x007F.

GAS = адрес Modbus, hex Адрес, dec Значение Назначение
0x5F00 24320 0x4741 Сигнатура GA
0x5F01 24321 0x5331 Сигнатура S1
0x5F02 24322 1 Версия контракта GAS
0x5F03 24323 167 Профиль устройства
0x5F04 24324 0x5000 База технологических GAS-регистров
0x5F05 24325 128 Число технологических регистров
0x5F06 24326 0x0007 Возможности: бит 0 — RTU, бит 1 — служебный CAN, бит 2 — FC06
0x5F07 24327 1 Аппаратный вариант EEPROM M95M02

Все восемь слов — RO. В сборке AT25256B GAS-адреса, включая этот блок, отклоняются с кодом недопустимого адреса.

Маски команд и состояния LOAD

Регистр Commands: штатный Modbus 0x007F, GAS 0x507F. Операция FC06 записывает всё слово; обработчик вызывает ump_log_rs(). Смысл и выполнение команд определяет прошивка.

Бит Маска Имя в исходниках
0 0x0001 cTestLamp
1 0x0002 cDefParam
2 0x0004 cSaveParam
3 0x0008 cLoadParam
4 0x0010 cTermoCal
5 0x0020 cKoefCalc
6 0x0040 cUMPreset
7 0x0080 cUMPstart
8 0x0100 cInitDac
9 0x0200 cCalibrDac
10 0x0400 cSecretBt
11 0x0800 cLiteFire
12 0x1000 cRawMeat
13 0x2000 Имя команды в package.h не задано
14 0x4000 Имя команды в package.h не задано
15 0x8000 cReset

Для Desk == dsk_LOAD регистр LOAD_STATUS (0x007C / 0x507C) формируется в DAC.c:

Бит Маска Смысл
0 0x0001 Состояние LOAD_FAULT: ошибка после исчерпания настроенного лимита пусков
1 0x0002 Нет свежего напряжения ЗПТ
2 0x0004 Состояние LOAD_RELOAD: сброс перед повторным пуском
3 0x0008 Состояние LOAD_RUN: работа рампы
4 0x0010 Имитация потери ЗПТ: приём напряжения из CAN игнорируется
5 0x0020 Имитация 0 В для защиты; реальные значения CAN в логгере сохраняются

LOAD_MAX_ATTEMPTS (0x007D / 0x507D) содержит записываемый лимит общего числа пусков: 1…65535, по умолчанию 5. Первый START входит в лимит. Ноль отклоняется кодом 3; изменение сохраняется штатной командой Save. Текущий счётчик читается в слове 5 диагностического блока FC03(0x1300, 8). Только LOAD_STATUS остаётся RO для LOAD.

Запросы и ограничения

Операция Штатные адреса 0x0000…0x007F GAS-адреса
FC03 1…125 слов в пределах 128 регистров 1…124 слова; весь блок внутри одного GAS-региона
FC06 Одно 16-битное слово Одно 16-битное слово; ответ сохраняет GAS-адрес
FC04 / FC16 Не используются этими обработчиками для данной карты GAS-provider поддерживает функции 3 и 6
LOAD: запись LOAD_STATUS Код 2 Код 2
LOAD: запись нуля в LOAD_MAX_ATTEMPTS Код 3 Код 3
LOAD: запись LOAD_CAN_TIMEOUT вне 1…60000 мс Код 3 Код 3

GAS-provider возвращает код 1 для неподдерживаемой функции, код 2 для недопустимого адреса, пересечения границы или записи RO-блока; код 3 — для количества слов 0 или >124 и недопустимого LOAD-timeout. В RTU запросы к этой карте маршрутизируются обработчиками FC03/FC06.

В RTU данные одного слова передаются старшим байтом вперёд. Формат ответа GAS-расширения отличается от исторического ответа низких адресов: у GAS нет дополнительных хвостовых нулей.

Примеры ниже задают функцию, адрес и количество/значение; это параметры запроса, без адреса устройства и CRC:

Действие Штатный Modbus Через GAS
Прочитать информацию профиля Нет аналога FC03(0x5F00, 8)
Прочитать слово 0 FC03(0x0000, 1) FC03(0x5000, 1)
Прочитать все 128 слов FC03(0x0000, 125) + FC03(0x007D, 3) FC03(0x5000, 124) + FC03(0x507C, 4)
Прочитать timeout LOAD FC03(0x0052, 1) FC03(0x5052, 1)
Задать timeout LOAD = 1000 мс FC06(0x0052, 1000) FC06(0x5052, 1000)
Прочитать статус и лимит пусков LOAD FC03(0x007C, 2) FC03(0x507C, 2)
Задать лимит LOAD = 5 пусков FC06(0x007D, 5) FC06(0x507D, 5)
Прочитать защиту и текущий счётчик LOAD FC03(0x1300, 8) Штатный диагностический блок

Два запроса на чтение всей карты дают два отдельных снимка. FC06 меняет RAM; сохранение параметров в EEPROM выполняется штатным механизмом прошивки.

Эти же GAS-адреса доступны через служебный CAN УМП с маркером 0x1F00, token и функцией 3/6. CAN-чтение принимает чётное количество 2…124 слова; каждый фрагмент ответа содержит два слова. Формат запроса приведён в GAS_167_M95M02.md.

Другие расширения Modbus — регистратор 0x1000…0x117B, паспорт 0x1200…0x120B, защита 0x1300…0x1307 и EEPROM 0x8000…0xFFFF — имеют собственные обработчики. Формула GAS = 0x5000 + Modbus применяется только к штатным 128 технологическим словам.

Источники

  • gas167.h — базы, размеры, версия и лимит GAS.
  • gas167.c — прямое соответствие modbus[], информация профиля и ограничения записи.
  • package.h — группы регистров, имена и маски команд.
  • message.c — FC03/FC06, инициализация и сохранение параметров.
  • measure.c, ADC.c, DAC.c — значения измерений и особенности LOAD.
  • GAS_167_M95M02.md — включение GAS, форматы транспорта и проверки реализации.