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

271 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GAS ↔ Modbus: карта регистров Бальзам 167
Профиль: **GAS 167/v1**. Соответствие проверено по исходникам проекта на **9 октября 2026 года**.
УКСС выделен сквозной диапазон **0…11999** с блоком **1000 ID** на номер узла: [GAS_ADDRESS_ALLOCATION.md](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](../Source/Internal/Include/eeprom_config.h) по умолчанию задано `0` — сборка для AT25256B, в которой GAS-окна отсутствуют. Фактическая сборка может переопределять этот параметр.
## Правило соответствия
```text
Для штатного адреса 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](../Source/Internal/Include/package.h), [measure.c](../Source/Internal/measure.c), [ADC.c](../Source/Internal/ADC.c) и [DAC.c](../Source/Internal/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](../Source/Internal/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](GAS_167_M95M02.md).
Другие расширения Modbus — регистратор `0x1000…0x117B`, паспорт `0x1200…0x120B`, защита `0x1300…0x1307` и EEPROM `0x8000…0xFFFF` — имеют собственные обработчики. Формула `GAS = 0x5000 + Modbus` применяется только к штатным **128 технологическим словам**.
## Источники
- [gas167.h](../Source/Internal/Include/gas167.h) — базы, размеры, версия и лимит GAS.
- [gas167.c](../Source/Internal/gas167.c) — прямое соответствие `modbus[]`, информация профиля и ограничения записи.
- [package.h](../Source/Internal/Include/package.h) — группы регистров, имена и маски команд.
- [message.c](../Source/Internal/message.c) — FC03/FC06, инициализация и сохранение параметров.
- [measure.c](../Source/Internal/measure.c), [ADC.c](../Source/Internal/ADC.c), [DAC.c](../Source/Internal/DAC.c) — значения измерений и особенности LOAD.
- [GAS_167_M95M02.md](GAS_167_M95M02.md) — включение GAS, форматы транспорта и проверки реализации.