Compare commits
30 Commits
e4fcfd11d7
...
v1.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
910bf0a585 | ||
|
|
502046091c | ||
|
|
e99de603e6 | ||
|
|
788ad19464 | ||
|
|
96496a0256 | ||
|
|
f89aff1b1c | ||
|
|
6830743477 | ||
|
|
171f176d63 | ||
|
|
f2c4b7b3cd | ||
|
|
c94a7e711c | ||
|
|
5be6343c33 | ||
|
|
043359fe66 | ||
|
|
c55f38ef1c | ||
|
|
ae2c90160e | ||
|
|
4de53090a1 | ||
|
|
742c4e9e1b | ||
|
|
369cfa808c | ||
|
|
c32dc161f8 | ||
|
|
abfc507e4e | ||
|
|
cb496bca0f | ||
|
|
7b720cbdf4 | ||
|
|
6428e523df | ||
|
|
c738acd871 | ||
|
|
05bde87c38 | ||
|
|
02f3124224 | ||
|
|
21082a38e0 | ||
|
|
42ac3eb65d | ||
|
|
69c0bf1574 | ||
|
|
4f949e9854 | ||
|
|
0d54031dd5 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,3 +5,5 @@
|
|||||||
/DebugVarEdit_GUI.build
|
/DebugVarEdit_GUI.build
|
||||||
/DebugVarEdit_GUI.dist
|
/DebugVarEdit_GUI.dist
|
||||||
/DebugVarEdit_GUI.onefile-build
|
/DebugVarEdit_GUI.onefile-build
|
||||||
|
/parse_xml/build/
|
||||||
|
/parse_xml/Src/__pycache__/
|
||||||
|
|||||||
BIN
DebugVarEdit.exe
BIN
DebugVarEdit.exe
Binary file not shown.
BIN
DebugVarTerminal.exe
Normal file
BIN
DebugVarTerminal.exe
Normal file
Binary file not shown.
282
README.md
Normal file
282
README.md
Normal file
@@ -0,0 +1,282 @@
|
|||||||
|
# DebugTools - Просмотр переменных по указателям
|
||||||
|
## Содержание
|
||||||
|
1. [Описание модуля](#программный-модуль-debugtools)
|
||||||
|
2. [Описание приложения для настройки](#debugvaredit---настройка-переменных)
|
||||||
|
3. [Описание терминалки для считывания](#debugvarterminal---считывание-переменных-для-tms)
|
||||||
|
4. [Для разработчиков](#для-разработчиков)
|
||||||
|
|
||||||
|
# Программный модуль DebugTools
|
||||||
|
Модуль состоит из трех файлов:
|
||||||
|
- **debug_tools.c** - реализация считывания переменных
|
||||||
|
- **debug_tools.h** - объявление всякого для считывания переменных
|
||||||
|
- **debug_vars.c** - определение массива считываемых переменных
|
||||||
|
|
||||||
|
Этот модуль предоставляет функциональность для чтения значений переменных во встроенной системе, включая работу с IQ-форматами, защиту доступа и проверку диапазонов памяти.
|
||||||
|
|
||||||
|
Для чтения переменных можно использовать функции:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* Читает значение переменной по индексу */
|
||||||
|
int Debug_ReadVar(int var_ind, int32_t *return_long);
|
||||||
|
/* Читает имя переменной по индексу */
|
||||||
|
int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr, int *length);
|
||||||
|
/* Читает возвращаемый тип (IQ) переменной по индексу */
|
||||||
|
int Debug_ReadVarReturnType(int var_ind, int *vartype);
|
||||||
|
/* Читает тип переменной по индексу */
|
||||||
|
int Debug_ReadVarType(int var_ind, int *vartype);
|
||||||
|
|
||||||
|
|
||||||
|
/* Читает значение переменной с нижнего уровня */
|
||||||
|
int Debug_LowLevel_ReadVar(int32_t *return_long);
|
||||||
|
/* Инициализирует отладку нижнего уровня */
|
||||||
|
int Debug_LowLevel_Initialize(DateTime_t *external_date);
|
||||||
|
/* Читает возвращаемый тип (IQ) низкоуровнено заданной переменной */
|
||||||
|
int Debug_LowLevel_ReadVarReturnType(int *vartype);
|
||||||
|
/* Читает тип низкоуровнено заданной переменной.*/
|
||||||
|
int Debug_LowLevel_ReadVarType(int *vartype);
|
||||||
|
```
|
||||||
|
|
||||||
|
Переменные доступные для чтения определяются в **debug_vars.c** (их можно прописывать вручную или генерировать через **DebugVarEdit**):
|
||||||
|
|
||||||
|
```c
|
||||||
|
// Определение массива с указателями на переменные для отладки
|
||||||
|
int DebugVar_Qnt = 5;
|
||||||
|
#pragma DATA_SECTION(dbg_vars,".dbgvar_info")
|
||||||
|
// pointer_type iq_type return_iq_type short_name
|
||||||
|
DebugVar_t dbg_vars[] = {\
|
||||||
|
{(uint8_t *)&freqTerm, pt_float, t_iq_none, t_iq10, "freqT" }, \
|
||||||
|
{(uint8_t *)&ADC_sf[0][0], pt_int16, t_iq_none, t_iq_none, "ADC_sf00" }, \
|
||||||
|
{(uint8_t *)&ADC_sf[0][1], pt_int16, t_iq_none, t_iq_none, "ADC_sf01" }, \
|
||||||
|
{(uint8_t *)&ADC_sf[0][2], pt_int16, t_iq_none, t_iq_none, "ADC_sf02" }, \
|
||||||
|
{(uint8_t *)&ADC_sf[0][3], pt_int16, t_iq_none, t_iq_none, "ADC_sf03" }, \
|
||||||
|
{(uint8_t *)&Bender[0].KOhms, pt_uint16, t_iq, t_iq10, "Bend0.KOhm" }, \
|
||||||
|
{(uint8_t *)&Bender[0].Times, pt_uint16, t_iq_none, t_iq_none, "Bend0.Time" }, \
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## LowLevel - Просмотр абсолютно любых переменных
|
||||||
|
Также присутствует утилита `parse_xml.exe`, которая генерирует `.xml` файл с всеми переменными в программе и их адрессами
|
||||||
|
Для её подключения:
|
||||||
|
- В Pre-Build Steps добавить следующую команду. Это удаление `debug_tools.obj` файла для его перекомпиялции с актуальной датой компиляции
|
||||||
|
```
|
||||||
|
cmd /c del /Q "${CWD}\Src\DebugTools\debug_tools.obj"
|
||||||
|
```
|
||||||
|
- В Post-Build Steps добавить следующую команду. Это:
|
||||||
|
- формирование с помощью утилиты компилятора `ofd2000` `.xml` файла с полной отладочной информацией.
|
||||||
|
- формирование отладочной информации в текстовом файле (для получения таймштампа)
|
||||||
|
- запуск утилиты `parse_xml.exe` для формирования итогового `<projname>_allVars.xml` с информацией о переменных и адресах
|
||||||
|
|
||||||
|
```
|
||||||
|
"${CG_TOOL_ROOT}/bin/ofd2000" --obj_display=symbols --dwarf --dwarf_display=all --xml --xml_indent=1 --output="${BuildArtifactFileBaseName}_ofd_dump.xml" "${BuildArtifactFilePath}"
|
||||||
|
"${CG_TOOL_ROOT}/bin/ofd2000" "${BuildArtifactFilePath}" > ${CCS_PROJECT_DIR}/bin/temp.txt
|
||||||
|
"${CCS_PROJECT_DIR}/Src/DebugTools/parse_xml/parse_xml.exe" ${BuildArtifactFileBaseName}_ofd_dump.xml ${CCS_PROJECT_DIR}/bin/temp.txt ${BuildArtifactFileBaseName}_allVars.xml"
|
||||||
|
```
|
||||||
|
После, с использованием терминалки можно прочитать любые переменные по адресам. (должен совпадать таймштапм в прошивке и `.xml` файла, иначе контроллер ответит ошибкой)
|
||||||
|
|
||||||
|
|
||||||
|
# DebugVarEdit - Настройка переменных
|
||||||
|
**DebugVarEdit** — графическое приложение для Windows, предназначенное для настройки и генерации отладочных переменных (`debug_vars.c`) на основе исходного C-проекта. Работает с `makefile` проекта, сохраняет изменения в XML и позволяет удобно редактировать переменные и их типы через интерфейс.
|
||||||
|
|
||||||
|
Программа — один исполняемый файл `DebugVarEdit.exe`, не требующий установки и дополнительных зависимостей.
|
||||||
|
|
||||||
|
> Требуется Windows 7 или новее.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как использовать приложение
|
||||||
|
|
||||||
|
1. Запустите **DebugVarEdit.exe.**
|
||||||
|
|
||||||
|
2. Укажите пути и контроллер:
|
||||||
|
- **Путь к XML** — новый или существующий файл настроек переменных;
|
||||||
|
- **Путь к проекту** — путь к корню проека (папка, которая является корнем для проекта в Code Composer);
|
||||||
|
- **Путь к makefile** — путь к `makefile` относительно корня проекта;
|
||||||
|
- **Путь для debug_vars.c** — папка, куда будет сгенерирован файл `debug_vars.c` с переменными.
|
||||||
|
- **МК** — TMS или STM. Они отличаются размером int, и также принятыми кодировками файлов (utf-8/cp1251)
|
||||||
|
|
||||||
|
3. Нажмите **Сканировать переменные**:
|
||||||
|
- Программа проанализирует исходники, указанные в makefile, и найдёт все переменные.
|
||||||
|
- Результат сохранится в двух XML-файлах:
|
||||||
|
- `structs.xml` — информация обо всех структурах и typedef;
|
||||||
|
- `<ваш_файл>.xml` — список всех найденных переменных.
|
||||||
|
|
||||||
|
4. Нажмите **Добавить переменные**:
|
||||||
|
- В **левой таблице** отображаются все найденные переменные.
|
||||||
|
Для добавления переменной в проект дважды кликните по ней или нажмите кнопку `>`, чтобы переместить в правую таблицу.
|
||||||
|
- В **правой таблице** находятся переменные, выбранные для использования.
|
||||||
|
Чтобы убрать переменную из проекта, переместите её обратно в левую таблицу двойным кликом или кнопкой `<`.
|
||||||
|
- После выбора переменных нажмите **Применить**, чтобы обновить основной список переменных и включить их в проект.
|
||||||
|
|
||||||
|
5. Настройте параметры выбранных переменных:
|
||||||
|
- **En** — включение или отключение переменной для генерации;
|
||||||
|
- **Base Type** — базовый тип переменной (например, int8, uint16 и т.д.);
|
||||||
|
- **IQ Type** — формат IQ, если применимо;
|
||||||
|
- **Return Type** — формат возвращаемого значения (IQ-тип или целочисленный);
|
||||||
|
- **Shortname** — короткое имя переменной для для терминалки.
|
||||||
|
|
||||||
|
Все параметры выбираются из выпадающих списков, которые можно настроить, чтобы отображались только нужные опции.
|
||||||
|
|
||||||
|
6. Нажмите **Сгенерировать файл** для создания файла `debug_vars.c` с выбранными переменными.
|
||||||
|
---
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
|
||||||
|
- Загрузка и сохранение настроек переменных в XML-файлах.
|
||||||
|
- Автоматическое определение исходных файлов с переменными для удобства работы.
|
||||||
|
- Редактирование переменных: включение, короткого имени и типов через удобные списки.
|
||||||
|
- Подсветка ошибок при вводе (неправильные имена, слишком длинные короткие имена).
|
||||||
|
- Быстрая фильтрация переменных по столбцам.
|
||||||
|
- Автоматическая генерация файла debug_vars.c с выбранными переменными.
|
||||||
|
- Возможность сразу открыть сгенерированный файл в редакторе.
|
||||||
|
- Умное автодополнение имён переменных и полей структур.
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Пример XML-файла
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<project proj_path="C:/myproj" makefile_path="Debug/Makefile" structs_path="Src/DebugTools/structs.xml">
|
||||||
|
<variables>
|
||||||
|
<var name="g_myvar">
|
||||||
|
<enable>true</enable>
|
||||||
|
<show_var>true</show_var>
|
||||||
|
<shortname>myv</shortname>
|
||||||
|
<pt_type>pt_float</pt_type>
|
||||||
|
<iq_type>t_iq24</iq_type>
|
||||||
|
<return_type>t_iq24</return_type>
|
||||||
|
<type>float</type>
|
||||||
|
<file>Src/main/main.c</file>
|
||||||
|
<extern>true</extern>
|
||||||
|
<static>false</static>
|
||||||
|
</var>
|
||||||
|
</variables>
|
||||||
|
</project>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
# DebugVarTerminal - Считывание переменных (для TMS)
|
||||||
|
**DebugVarTerminal** — терминалка для считывания переменных по RS-232 протоколу RS_Functions.
|
||||||
|
Программа — один исполняемый файл `DebugVarTerminal.exe`, не требующий установки и дополнительных зависимостей.
|
||||||
|
> Требуется Windows 7 или новее.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Как использовать приложение
|
||||||
|
|
||||||
|
1. Запустите **DebugVarTerminal.exe.**
|
||||||
|
|
||||||
|
2. Выберите COM Port и скорость Baud. Нажмиите **Open**
|
||||||
|
|
||||||
|
3. Для считывания переменных заданных в `*debug_vars.c`:
|
||||||
|
- Откройте вкладку **Watch**.
|
||||||
|
- Выберите стартовый индекс переменной и количество переменных для считывания.
|
||||||
|
- Нажмите одну из кнопок:
|
||||||
|
- **Update Service** - считывает информацию об именах и возвращаемых IQ типах переемнных
|
||||||
|
- **Read Value(s)** - считывает и форматирует значения переменных в соответствии с IQ типами
|
||||||
|
- **Start Polling** - начать опрос выбранных переменных с заданным интервалом. При старте опроса, имя и тип переменных считываются автоматически
|
||||||
|
|
||||||
|
4. Для считывания переменных по адресам:
|
||||||
|
- Откройте вкладку **LowLevel**.
|
||||||
|
- Выберите `projname_allVars.xml` в папке bin рядом с бинарником. Из него подгрузятся все доступные для считывания переменные
|
||||||
|
- Выберите переменные кнопкной **Выбрать переменные**
|
||||||
|
- Задайте IQ тип и возвращаемый IQ тип если требуется
|
||||||
|
- Нажмите одну из кнопок:
|
||||||
|
- **Read Once** - считывает выбранные переменные один раз
|
||||||
|
- **Start Polling** - начать опрос выбранных переменных с заданным интервалом
|
||||||
|
|
||||||
|
5. Запись в CSV:
|
||||||
|
- Можно записывавать считываемые переменные в CSV файл, с разделителем `;`
|
||||||
|
- Нажмите кнопку **Начать запись в CSV**
|
||||||
|
- Когда нужная выборка будет накоплена нажмите **Остаовить запись в CSV**
|
||||||
|
- Нажмите **Выбрать файл CSV** для выбора пути для сохранения файла и нажмите **Сохранить данные в CSV** чтобы сохранить
|
||||||
|
- Генерируется совместимый с LogView `.csv` файл
|
||||||
|
|
||||||
|
Все параметры выбираются из выпадающих списков, которые можно настроить, чтобы отображались только нужные опции.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Возможности
|
||||||
|
Режим "Watch":
|
||||||
|
- Быстрое и удобное чтение одной или нескольких переменных по их индексу.
|
||||||
|
- Автоматическое получение имен, типов и параметров масштабирования (IQ) переменных.
|
||||||
|
- Запуск постоянного опроса для отслеживания изменений значений в реальном времени.
|
||||||
|
- Наглядное представление данных в таблице с отображением как сырых, так и масштабированных значений.
|
||||||
|
Режим "LowLevel":
|
||||||
|
- Прямое чтение данных из памяти по заданным адресам.
|
||||||
|
- Возможность указания типов указателей, IQ-масштабирования и форматов возвращаемых данных.
|
||||||
|
- Аналогично режиму "Watch", поддерживается постоянный опрос выбранных низкоуровневых переменных.
|
||||||
|
- Умное автодополнение имён переменных и полей структур.
|
||||||
|
Логирование в CSV
|
||||||
|
- Записывайте все полученные значения в файл формата CSV для последующего анализа.
|
||||||
|
- Легкое управление записью: запуск, остановка и сохранение данных в любой момент.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Для разработчиков
|
||||||
|
|
||||||
|
### Структура проекта:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Src
|
||||||
|
├── build/
|
||||||
|
│ └── build_and_clean.py # Билдинг проекта в .exe (через nuitka или pyinstaller)
|
||||||
|
├── DebugVarEdit_GUI.py # Главное окно
|
||||||
|
├── tms_debugvar_term.py # Терминал DebugVarTerminal
|
||||||
|
├── tms_debugvar_lowlevel.py # Виджет для выбора переменных для LowLevel Watch
|
||||||
|
├── var_table.py # Таблица выбранных переменных
|
||||||
|
├── var_selector_window.py # Окно выбора переменных
|
||||||
|
├── var_selector_table.py # Таблица переменных в окне выбора переменных
|
||||||
|
├── scan_progress_gui.py # Отображение процесса сканирования переменных
|
||||||
|
├── scan_vars.py # Сканирование переменных среди .c/.h файлов
|
||||||
|
├── generate_debug_vars.py # Генерация debug_vars.c
|
||||||
|
├── allvars_xml_parser.py # Парсинг XML со всеми переменными и структурами
|
||||||
|
├── csv_logger.py # Логирование переменных в CSV
|
||||||
|
├── myXML.py # Утилиты для XML
|
||||||
|
├── makefile_parser.py # Парсинг makefile на .c/.h файлы
|
||||||
|
├── var_setup.py # Подготовка переменных для окна выбора переменных
|
||||||
|
├── path_hints.py # Подсказки для автодополнения путей переменных
|
||||||
|
├── libclang.dll # Бибилиотека clang
|
||||||
|
├── icon.ico # Иконка
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Зависимости
|
||||||
|
|
||||||
|
Для запуска приложения:
|
||||||
|
- **Python 3.7+**
|
||||||
|
- **clang** — используется для парсинга C-кода (требуется `libclang.dll`, лежит в папке Src)
|
||||||
|
- **PySide2** — GUI-фреймворк
|
||||||
|
- **lxml** — работа с XML
|
||||||
|
> Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7
|
||||||
|
|
||||||
|
Для сборки `.exe`:
|
||||||
|
- **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей
|
||||||
|
- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен для запуска `.exe`)
|
||||||
|
|
||||||
|
|
||||||
|
### Сборка:
|
||||||
|
Если вы хотите собрать `DebugVarEdit.exe` самостоятельно из исходников, используйте скрипт **build/build_and_clean.py**. Он автоматически собирает проект с помощью Nuitka или PyInstaller:
|
||||||
|
- Собирает проект в `DebugVarEdit.exe` в корневой папке.
|
||||||
|
- Включает:
|
||||||
|
- все необходимые `.dll` (например, `libclang.dll`),
|
||||||
|
- иконку (`icon.ico`),
|
||||||
|
- плагины PySide2.
|
||||||
|
- Очищает временные папки после сборки:
|
||||||
|
- `build_temp`
|
||||||
|
- `__pycache__`
|
||||||
|
- `<MAIN_SCRIPT_NAME>.*`
|
||||||
|
|
||||||
|
> Все пути, имена файлов, временные папки и выбор между Nuitka и PyInstaller можно настроить в начале файла `build_and_clean.py`.
|
||||||
|
|
||||||
|
### Установка зависимостей
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install clang PySide2 lxml nuitka pyinstaller
|
||||||
|
```
|
||||||
@@ -1,28 +1,31 @@
|
|||||||
# build command
|
# build command
|
||||||
# pyinstaller --onefile --name DebugVarEdit --add-binary "build/libclang.dll;build" --distpath ./ --workpath ./build_temp --specpath ./build_temp setupVars_GUI.py
|
# pyinstaller --onefile --name DebugVarEdit --add-binary "build/libclang.dll;build" --distpath ./ --workpath ./build_temp --specpath ./build_temp var_setup_GUI.py
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import xml.etree.ElementTree as ET
|
import lxml.etree as ET
|
||||||
from generateVars import type_map
|
from generate_debug_vars import type_map, choose_type_map
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
from tms_debugvar_term import _DemoWindow
|
||||||
import threading
|
import threading
|
||||||
from generateVars import run_generate
|
from generate_debug_vars import run_generate
|
||||||
import setupVars
|
import var_setup
|
||||||
from VariableSelector import VariableSelectorDialog
|
from var_selector_window import VariableSelectorDialog
|
||||||
from VariableTable import VariableTableWidget, rows
|
from var_table import VariableTableWidget, rows
|
||||||
from scanVarGUI import ProcessOutputWindow
|
from scan_progress_gui import ProcessOutputWindow
|
||||||
import scanVars
|
import scan_vars
|
||||||
import myXML
|
import myXML
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
from PySide2.QtWidgets import (
|
from PySide2.QtWidgets import (
|
||||||
QApplication, QWidget, QTableWidget, QTableWidgetItem,
|
QApplication, QWidget, QTableWidget, QTableWidgetItem,
|
||||||
QCheckBox, QComboBox, QLineEdit, QVBoxLayout, QHBoxLayout, QPushButton,
|
QCheckBox, QComboBox, QLineEdit, QVBoxLayout, QHBoxLayout, QPushButton,
|
||||||
QCompleter, QAbstractItemView, QLabel, QMessageBox, QFileDialog, QTextEdit,
|
QCompleter, QAbstractItemView, QLabel, QMessageBox, QFileDialog, QTextEdit,
|
||||||
QDialog, QTreeWidget, QTreeWidgetItem, QSizePolicy, QHeaderView
|
QDialog, QTreeWidget, QTreeWidgetItem, QSizePolicy, QHeaderView,
|
||||||
)
|
QMenuBar, QMenu, QAction
|
||||||
|
)
|
||||||
from PySide2.QtGui import QTextCursor, QKeyEvent, QIcon, QFont
|
from PySide2.QtGui import QTextCursor, QKeyEvent, QIcon, QFont
|
||||||
from PySide2.QtCore import Qt, QProcess, QObject, Signal, QSettings
|
from PySide2.QtCore import Qt, QProcess, QObject, Signal, QSettings
|
||||||
|
|
||||||
@@ -31,12 +34,18 @@ var_edit_title = "Редактор переменных для отладки"
|
|||||||
xml_path_title = "Путь к XML:"
|
xml_path_title = "Путь к XML:"
|
||||||
proj_path_title = "Путь к проекту:"
|
proj_path_title = "Путь к проекту:"
|
||||||
makefile_path_title = "Пусть к makefile (относительно проекта)"
|
makefile_path_title = "Пусть к makefile (относительно проекта)"
|
||||||
output_path_title = "Папка для debug_vars.c:"
|
output_path_title = "Путь для для debug_vars.c:"
|
||||||
scan_title = "Сканировать переменные"
|
scan_title = "Сканировать переменные"
|
||||||
build_title = "Сгенерировать файл"
|
build_title = "Сгенерировать файл"
|
||||||
add_vars_title = "Добавить переменные"
|
add_vars_title = "Добавить переменные"
|
||||||
open_output_title = "Открыть файл"
|
open_output_title = "Открыть файл"
|
||||||
|
|
||||||
|
def set_sub_elem_text(parent, tag, text):
|
||||||
|
el = parent.find(tag)
|
||||||
|
if el is None:
|
||||||
|
el = ET.SubElement(parent, tag)
|
||||||
|
el.text = str(text)
|
||||||
|
|
||||||
# 3. UI: таблица с переменными
|
# 3. UI: таблица с переменными
|
||||||
class VarEditor(QWidget):
|
class VarEditor(QWidget):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -52,12 +61,13 @@ class VarEditor(QWidget):
|
|||||||
self.output_path = None
|
self.output_path = None
|
||||||
self._updating = False # Флаг блокировки рекурсии
|
self._updating = False # Флаг блокировки рекурсии
|
||||||
self._resizing = False # флаг блокировки повторного вызова
|
self._resizing = False # флаг блокировки повторного вызова
|
||||||
|
self.target = 'TMS'
|
||||||
self.initUI()
|
self.initUI()
|
||||||
|
|
||||||
def initUI(self):
|
def initUI(self):
|
||||||
self.setWindowTitle(var_edit_title)
|
self.setWindowTitle(var_edit_title)
|
||||||
|
|
||||||
base_path = scanVars.get_base_path()
|
base_path = scan_vars.get_base_path()
|
||||||
icon_path = os.path.join(base_path, "icon.ico")
|
icon_path = os.path.join(base_path, "icon.ico")
|
||||||
if os.path.exists(icon_path):
|
if os.path.exists(icon_path):
|
||||||
self.setWindowIcon(QIcon(icon_path))
|
self.setWindowIcon(QIcon(icon_path))
|
||||||
@@ -116,6 +126,43 @@ class VarEditor(QWidget):
|
|||||||
self.btn_update_vars = QPushButton(scan_title)
|
self.btn_update_vars = QPushButton(scan_title)
|
||||||
self.btn_update_vars.clicked.connect(self.update_vars_data)
|
self.btn_update_vars.clicked.connect(self.update_vars_data)
|
||||||
|
|
||||||
|
# Добавляем чекбокс для выбора типовой карты
|
||||||
|
# --- Создаем верхнее меню ---
|
||||||
|
menubar = QMenuBar(self)
|
||||||
|
menubar.setToolTip('Разные размеры int и кодировки файлов')
|
||||||
|
self.target_menu = QMenu("МК:", menubar)
|
||||||
|
# Создаем действия для выбора Target
|
||||||
|
self.action_tms = QAction("TMS", self, checkable=True)
|
||||||
|
self.action_stm = QAction("STM", self, checkable=True)
|
||||||
|
# Инициализируем QSettings с именем организации и приложения
|
||||||
|
self.settings = QSettings("SET", "DebugVarEdit_MainWindow")
|
||||||
|
# Восстанавливаем сохранённое состояние, если есть
|
||||||
|
mcu = self.settings.value("mcu_choosen", True, type=str)
|
||||||
|
self.on_target_selected(mcu)
|
||||||
|
|
||||||
|
self.target_menu.setToolTip(f'TMS: Размер int 16 бит. Кодировка cp1251\nSTM: Размер int 32 бита. Кодировка utf-8')
|
||||||
|
# Группируем действия чтобы выбирался только один
|
||||||
|
self.action_tms.triggered.connect(lambda: self.on_target_selected("TMS"))
|
||||||
|
self.action_tms.setToolTip('Размер int 16 бит. Кодировка cp1251')
|
||||||
|
self.action_stm.triggered.connect(lambda: self.on_target_selected("STM"))
|
||||||
|
self.action_stm.setToolTip('Размер int 32 бита. Кодировка utf-8')
|
||||||
|
|
||||||
|
self.target_menu.addAction(self.action_tms)
|
||||||
|
self.target_menu.addAction(self.action_stm)
|
||||||
|
|
||||||
|
self.terminal_menu = QMenu("Открыть Терминал", menubar)
|
||||||
|
|
||||||
|
self.action_terminal_tms = QAction("TMS DemoTerminal", self)
|
||||||
|
self.action_terminal_modbus = QAction("Modbus DemoTerminal", self)
|
||||||
|
self.action_terminal_tms.triggered.connect(lambda: self.open_terminal("TMS"))
|
||||||
|
self.action_terminal_modbus.triggered.connect(lambda: self.open_terminal("MODBUS"))
|
||||||
|
|
||||||
|
self.terminal_menu.addAction(self.action_terminal_tms)
|
||||||
|
#self.terminal_menu.addAction(self.action_terminal_modbus)
|
||||||
|
|
||||||
|
menubar.addMenu(self.target_menu)
|
||||||
|
menubar.addMenu(self.terminal_menu)
|
||||||
|
|
||||||
# Кнопка сохранения
|
# Кнопка сохранения
|
||||||
btn_save = QPushButton(build_title)
|
btn_save = QPushButton(build_title)
|
||||||
btn_save.clicked.connect(self.save_build)
|
btn_save.clicked.connect(self.save_build)
|
||||||
@@ -131,6 +178,7 @@ class VarEditor(QWidget):
|
|||||||
self.table = VariableTableWidget()
|
self.table = VariableTableWidget()
|
||||||
# Основной layout
|
# Основной layout
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
|
layout.setMenuBar(menubar) # прикрепляем menubar в layout сверху
|
||||||
layout.addLayout(xml_layout)
|
layout.addLayout(xml_layout)
|
||||||
layout.addLayout(proj_layout)
|
layout.addLayout(proj_layout)
|
||||||
layout.addLayout(makefile_layout)
|
layout.addLayout(makefile_layout)
|
||||||
@@ -144,6 +192,53 @@ class VarEditor(QWidget):
|
|||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
|
||||||
|
def open_terminal(self, target):
|
||||||
|
target = target.lower()
|
||||||
|
|
||||||
|
if target == "tms":
|
||||||
|
exe_name = "DebugVarTerminal.exe"
|
||||||
|
# Путь к exe в текущей директории запуска программы
|
||||||
|
exe_path = os.path.join(os.getcwd(), exe_name)
|
||||||
|
|
||||||
|
if not os.path.isfile(exe_path):
|
||||||
|
# Файл не найден — попросим пользователя выбрать путь к exe
|
||||||
|
msg = QMessageBox()
|
||||||
|
msg.setIcon(QMessageBox.Warning)
|
||||||
|
msg.setWindowTitle("Файл не найден")
|
||||||
|
msg.setText(f"Файл {exe_name} не найден в текущей папке.\nВыберите путь к {exe_name}.")
|
||||||
|
msg.exec_()
|
||||||
|
|
||||||
|
# Открываем диалог выбора файла
|
||||||
|
selected_path, _ = QFileDialog.getOpenFileName(
|
||||||
|
None, "Выберите файл " + exe_name, os.getcwd(), "Executable Files (*.exe)"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not selected_path:
|
||||||
|
# Пользователь отменил выбор — ничего не делаем
|
||||||
|
return
|
||||||
|
|
||||||
|
exe_path = selected_path
|
||||||
|
|
||||||
|
# Запускаем exe (отдельное окно терминала)
|
||||||
|
subprocess.Popen([exe_path], creationflags=subprocess.CREATE_NEW_CONSOLE)
|
||||||
|
|
||||||
|
elif target == "modbus":
|
||||||
|
a = 1
|
||||||
|
|
||||||
|
|
||||||
|
def on_target_selected(self, target):
|
||||||
|
self.target_menu.setTitle(f'МК: {target}')
|
||||||
|
self.settings.setValue("mcu_choosen", target)
|
||||||
|
self.target = target.lower()
|
||||||
|
if self.target == "stm":
|
||||||
|
choose_type_map(True)
|
||||||
|
self.action_stm.setChecked(True)
|
||||||
|
self.action_tms.setChecked(False)
|
||||||
|
else:
|
||||||
|
choose_type_map(False)
|
||||||
|
self.action_tms.setChecked(True)
|
||||||
|
self.action_stm.setChecked(False)
|
||||||
|
|
||||||
|
|
||||||
def get_xml_path(self):
|
def get_xml_path(self):
|
||||||
xml_path = self.xml_output_edit.text().strip()
|
xml_path = self.xml_output_edit.text().strip()
|
||||||
@@ -202,7 +297,7 @@ class VarEditor(QWidget):
|
|||||||
|
|
||||||
# Создаём окно с кнопкой "Готово"
|
# Создаём окно с кнопкой "Готово"
|
||||||
self.proc_win = ProcessOutputWindow(self.proj_path, self.makefile_path, self.xml_path,
|
self.proc_win = ProcessOutputWindow(self.proj_path, self.makefile_path, self.xml_path,
|
||||||
on_done_callback=self.__after_scanvars_finished)
|
self.__after_scan_vars_finished, self)
|
||||||
self.proc_win.start_scan()
|
self.proc_win.start_scan()
|
||||||
|
|
||||||
|
|
||||||
@@ -222,8 +317,8 @@ class VarEditor(QWidget):
|
|||||||
var_data = {
|
var_data = {
|
||||||
'name': name_edit.text(),
|
'name': name_edit.text(),
|
||||||
'type': 'pt_' + pt_type_combo.currentText(),
|
'type': 'pt_' + pt_type_combo.currentText(),
|
||||||
'iq_type': iq_combo.currentText(),
|
'iq_type': 't_' + iq_combo.currentText(),
|
||||||
'return_type': ret_combo.currentText() if ret_combo.currentText() else 'int',
|
'return_type': 't_' + ret_combo.currentText() if ret_combo.currentText() else 't_iq_none',
|
||||||
'short_name': short_name_edit.text(),
|
'short_name': short_name_edit.text(),
|
||||||
}
|
}
|
||||||
vars_out.append(var_data)
|
vars_out.append(var_data)
|
||||||
@@ -235,15 +330,15 @@ class VarEditor(QWidget):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
run_generate(self.proj_path, self.xml_path, self.output_path)
|
run_generate(self.proj_path, self.xml_path, self.output_path, self.table._shortname_size)
|
||||||
QMessageBox.information(self, "Готово", "Файл debug_vars.c успешно сгенерирован.")
|
QMessageBox.information(self, "Готово", "Файл debug_vars.c успешно сгенерирован.")
|
||||||
self.update()
|
self.update()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.critical(self, "Ошибка при генерации", str(e))
|
QMessageBox.critical(self, "Ошибка при генерации", str(e))
|
||||||
|
|
||||||
|
|
||||||
def update(self):
|
def update(self, force=0):
|
||||||
if self._updating:
|
if self._updating and (force==0):
|
||||||
return # Уже в процессе обновления — выходим, чтобы избежать рекурсии
|
return # Уже в процессе обновления — выходим, чтобы избежать рекурсии
|
||||||
self._updating = True
|
self._updating = True
|
||||||
|
|
||||||
@@ -296,11 +391,11 @@ class VarEditor(QWidget):
|
|||||||
structs_path_full = myXML.make_absolute_path(structs_path, self.proj_path)
|
structs_path_full = myXML.make_absolute_path(structs_path, self.proj_path)
|
||||||
if structs_path_full and os.path.isfile(structs_path_full):
|
if structs_path_full and os.path.isfile(structs_path_full):
|
||||||
self.structs_path = structs_path_full
|
self.structs_path = structs_path_full
|
||||||
self.structs, self.typedef_map = setupVars.parse_structs(structs_path_full)
|
self.structs, self.typedef_map = var_setup.parse_structs(structs_path_full)
|
||||||
else:
|
else:
|
||||||
self.structs_path = None
|
self.structs_path = None
|
||||||
|
|
||||||
self.vars_list = setupVars.parse_vars(self.xml_path, self.typedef_map)
|
self.vars_list = var_setup.parse_vars(self.xml_path, self.typedef_map)
|
||||||
self.table.populate(self.vars_list, self.structs, self.write_to_xml)
|
self.table.populate(self.vars_list, self.structs, self.write_to_xml)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
QMessageBox.warning(self, "Ошибка", f"Ошибка при чтении XML:\n{e}")
|
QMessageBox.warning(self, "Ошибка", f"Ошибка при чтении XML:\n{e}")
|
||||||
@@ -352,10 +447,20 @@ class VarEditor(QWidget):
|
|||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
def __browse_makefile(self):
|
def __browse_makefile(self):
|
||||||
file_path, _ = QFileDialog.getOpenFileName(
|
if self.target == 'stm':
|
||||||
self, "Выберите Makefile", filter="Makefile (makefile);;All Files (*)"
|
file_filter = "Makefile или Keil-проект (*.uvprojx *.uvproj makefile);;Все файлы (*)"
|
||||||
)
|
dialog_title = "Выберите Makefile или Keil-проект"
|
||||||
if file_path and self.proj_path:
|
else: # 'TMS' или по умолчанию
|
||||||
|
file_filter = "Makefile (makefile);;Все файлы (*)"
|
||||||
|
dialog_title = "Выберите Makefile"
|
||||||
|
|
||||||
|
file_path, _ = QFileDialog.getOpenFileName(
|
||||||
|
self,
|
||||||
|
dialog_title,
|
||||||
|
filter=file_filter
|
||||||
|
)
|
||||||
|
if file_path:
|
||||||
|
if self.proj_path:
|
||||||
path = myXML.make_relative_path(file_path, self.proj_path)
|
path = myXML.make_relative_path(file_path, self.proj_path)
|
||||||
else:
|
else:
|
||||||
path = file_path
|
path = file_path
|
||||||
@@ -398,37 +503,42 @@ class VarEditor(QWidget):
|
|||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
def __after_scanvars_finished(self):
|
def __after_scan_vars_finished(self):
|
||||||
self.update_all_paths()
|
|
||||||
if not os.path.isfile(self.xml_path):
|
if not os.path.isfile(self.xml_path):
|
||||||
|
self.makefile_path = None
|
||||||
|
self.structs_path = None
|
||||||
|
self.proj_path = None
|
||||||
QMessageBox.critical(self, "Ошибка", f"Файл не найден: {self.xml_path}")
|
QMessageBox.critical(self, "Ошибка", f"Файл не найден: {self.xml_path}")
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
self.update(1)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
self.makefile_path = None
|
self.makefile_path = None
|
||||||
self.structs_path = None
|
self.structs_path = None
|
||||||
self.proj_path = None
|
self.proj_path = None
|
||||||
self.update()
|
|
||||||
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
QMessageBox.critical(self, "Ошибка", f"Не удалось загрузить переменные:\n{e}")
|
QMessageBox.critical(self, "Ошибка", f"Не удалось загрузить переменные:\n{e}")
|
||||||
|
|
||||||
|
|
||||||
def delete_selected_rows(self):
|
def delete_selected_rows(self):
|
||||||
selected_rows = sorted(set(index.row() for index in self.table.selectedIndexes()), reverse=True)
|
# Получаем имена всех выбранных переменных из первого столбца
|
||||||
if not selected_rows:
|
selected_names = self.table.get_selected_var_names()
|
||||||
|
|
||||||
|
if not selected_names:
|
||||||
return
|
return
|
||||||
|
|
||||||
for row in selected_rows:
|
# Меняем флаг show_var по имени
|
||||||
if 0 <= row < len(self.vars_list):
|
for var in self.vars_list:
|
||||||
# Меняем флаг show_var для переменной с этим индексом
|
if var.get('name') in selected_names:
|
||||||
self.vars_list[row]['show_var'] = 'false'
|
var['show_var'] = 'false'
|
||||||
|
|
||||||
self.table.populate(self.vars_list, self.structs, self.write_to_xml)
|
self.table.populate(self.vars_list, self.structs, self.write_to_xml)
|
||||||
self.write_to_xml()
|
self.write_to_xml()
|
||||||
|
|
||||||
|
|
||||||
def __open_variable_selector(self):
|
def __open_variable_selector(self):
|
||||||
|
self.update()
|
||||||
if not self.vars_list:
|
if not self.vars_list:
|
||||||
QMessageBox.warning(self, "Нет переменных", f"Сначала загрузите переменные ({scan_title}).")
|
QMessageBox.warning(self, "Нет переменных", f"Сначала загрузите переменные ({scan_title}).")
|
||||||
return
|
return
|
||||||
@@ -438,9 +548,20 @@ class VarEditor(QWidget):
|
|||||||
self.write_to_xml()
|
self.write_to_xml()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
|
||||||
def write_to_xml(self, dummy=None):
|
def write_to_xml(self, dummy=None):
|
||||||
|
t0 = time.time()
|
||||||
self.update_all_paths()
|
self.update_all_paths()
|
||||||
|
def get_val(name, default=''):
|
||||||
|
return str(v_table[name] if v_table and name in v_table else v.get(name, default))
|
||||||
|
|
||||||
|
def element_differs(elem, values: dict):
|
||||||
|
for tag, new_val in values.items():
|
||||||
|
current_elem = elem.find(tag)
|
||||||
|
current_val = (current_elem.text or '').strip()
|
||||||
|
new_val_str = str(new_val or '').strip()
|
||||||
|
if current_val != new_val_str:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
if not self.xml_path or not os.path.isfile(self.xml_path):
|
if not self.xml_path or not os.path.isfile(self.xml_path):
|
||||||
print("XML файл не найден или путь пустой")
|
print("XML файл не найден или путь пустой")
|
||||||
@@ -465,7 +586,6 @@ class VarEditor(QWidget):
|
|||||||
|
|
||||||
if self.makefile_path and os.path.isfile(self.makefile_path):
|
if self.makefile_path and os.path.isfile(self.makefile_path):
|
||||||
rel_makefile = myXML.make_relative_path(self.makefile_path, self.proj_path)
|
rel_makefile = myXML.make_relative_path(self.makefile_path, self.proj_path)
|
||||||
root.set("makefile_path", rel_makefile)
|
|
||||||
# Если результат — абсолютный путь, не записываем
|
# Если результат — абсолютный путь, не записываем
|
||||||
if not os.path.isabs(rel_makefile):
|
if not os.path.isabs(rel_makefile):
|
||||||
root.set("makefile_path", rel_makefile)
|
root.set("makefile_path", rel_makefile)
|
||||||
@@ -476,6 +596,7 @@ class VarEditor(QWidget):
|
|||||||
if not os.path.isabs(rel_struct):
|
if not os.path.isabs(rel_struct):
|
||||||
root.set("structs_path", rel_struct)
|
root.set("structs_path", rel_struct)
|
||||||
|
|
||||||
|
t1 = time.time()
|
||||||
|
|
||||||
vars_elem = root.find('variables')
|
vars_elem = root.find('variables')
|
||||||
if vars_elem is None:
|
if vars_elem is None:
|
||||||
@@ -490,6 +611,7 @@ class VarEditor(QWidget):
|
|||||||
'extern': var_elem.findtext('extern', ''),
|
'extern': var_elem.findtext('extern', ''),
|
||||||
'static': var_elem.findtext('static', '')
|
'static': var_elem.findtext('static', '')
|
||||||
}
|
}
|
||||||
|
var_elements_by_name = {ve.attrib.get('name'): ve for ve in vars_elem.findall('var')}
|
||||||
|
|
||||||
# Читаем переменные из таблицы (активные/изменённые)
|
# Читаем переменные из таблицы (активные/изменённые)
|
||||||
table_vars = {v['name']: v for v in self.table.read_data()}
|
table_vars = {v['name']: v for v in self.table.read_data()}
|
||||||
@@ -498,59 +620,73 @@ class VarEditor(QWidget):
|
|||||||
|
|
||||||
# Объединённый список переменных для записи
|
# Объединённый список переменных для записи
|
||||||
all_names = list(all_vars_by_name.keys())
|
all_names = list(all_vars_by_name.keys())
|
||||||
|
t2 = time.time()
|
||||||
for name in all_names:
|
for name in all_names:
|
||||||
v = all_vars_by_name[name]
|
v = all_vars_by_name[name]
|
||||||
v_table = table_vars.get(name)
|
v_table = table_vars.get(name)
|
||||||
var_elem = None
|
var_elem = None
|
||||||
|
|
||||||
# Ищем уже существующий <var> в XML
|
pt_type_val = get_val('pt_type').lower()
|
||||||
for ve in vars_elem.findall('var'):
|
if 'arr' in pt_type_val or 'struct' in pt_type_val or 'union' in pt_type_val:
|
||||||
if ve.attrib.get('name') == name:
|
continue
|
||||||
var_elem = ve
|
|
||||||
break
|
|
||||||
if var_elem is None:
|
|
||||||
var_elem = ET.SubElement(vars_elem, 'var', {'name': name})
|
|
||||||
|
|
||||||
def set_sub_elem_text(parent, tag, text):
|
|
||||||
el = parent.find(tag)
|
|
||||||
if el is None:
|
|
||||||
el = ET.SubElement(parent, tag)
|
|
||||||
el.text = str(text)
|
|
||||||
|
|
||||||
show_var_val = str(v.get('show_var', 'false')).lower()
|
show_var_val = str(v.get('show_var', 'false')).lower()
|
||||||
enable_val = str(v_table['enable'] if v_table and 'enable' in v_table else v.get('enable', 'false')).lower()
|
enable_val = get_val('enable').lower()
|
||||||
|
|
||||||
set_sub_elem_text(var_elem, 'show_var', show_var_val)
|
|
||||||
set_sub_elem_text(var_elem, 'enable', enable_val)
|
|
||||||
|
|
||||||
# Тут подтягиваем из таблицы, если есть, иначе из v
|
# Тут подтягиваем из таблицы, если есть, иначе из v
|
||||||
shortname_val = v_table['shortname'] if v_table and 'shortname' in v_table else v.get('shortname', '')
|
shortname_val = get_val('shortname')
|
||||||
pt_type_val = v_table['pt_type'] if v_table and 'pt_type' in v_table else v.get('pt_type', '')
|
iq_type_val = get_val('iq_type')
|
||||||
iq_type_val = v_table['iq_type'] if v_table and 'iq_type' in v_table else v.get('iq_type', '')
|
ret_type_val = get_val('return_type')
|
||||||
ret_type_val = v_table['return_type'] if v_table and 'return_type' in v_table else v.get('return_type', '')
|
|
||||||
|
|
||||||
set_sub_elem_text(var_elem, 'shortname', shortname_val)
|
|
||||||
set_sub_elem_text(var_elem, 'pt_type', pt_type_val)
|
|
||||||
set_sub_elem_text(var_elem, 'iq_type', iq_type_val)
|
|
||||||
set_sub_elem_text(var_elem, 'return_type', ret_type_val)
|
|
||||||
set_sub_elem_text(var_elem, 'type', v.get('type', ''))
|
|
||||||
|
|
||||||
# file/extern/static: из original_info, либо из v
|
# file/extern/static: из original_info, либо из v
|
||||||
file_val = v.get('file') or original_info.get(name, {}).get('file', '')
|
file_val = v.get('file') or original_info.get(name, {}).get('file', '')
|
||||||
extern_val = v.get('extern') or original_info.get(name, {}).get('extern', '')
|
extern_val = v.get('extern') or original_info.get(name, {}).get('extern', '')
|
||||||
static_val = v.get('static') or original_info.get(name, {}).get('static', '')
|
static_val = v.get('static') or original_info.get(name, {}).get('static', '')
|
||||||
|
|
||||||
set_sub_elem_text(var_elem, 'file', file_val)
|
values_to_write = {
|
||||||
set_sub_elem_text(var_elem, 'extern', extern_val)
|
'show_var': show_var_val,
|
||||||
set_sub_elem_text(var_elem, 'static', static_val)
|
'enable': enable_val,
|
||||||
|
'shortname': shortname_val,
|
||||||
|
'pt_type': pt_type_val,
|
||||||
|
'iq_type': iq_type_val,
|
||||||
|
'return_type': ret_type_val,
|
||||||
|
'type': v.get('type', ''),
|
||||||
|
'file': file_val,
|
||||||
|
'extern': extern_val,
|
||||||
|
'static': static_val
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ищем уже существующий <var> в XML
|
||||||
|
var_elem = var_elements_by_name.get(name)
|
||||||
|
# Если элемента нет, это новая переменная — сразу пишем
|
||||||
|
if var_elem is None:
|
||||||
|
var_elem = ET.SubElement(vars_elem, 'var', {'name': name})
|
||||||
|
var_elements_by_name[name] = var_elem
|
||||||
|
write_all = True # обязательно записать все поля
|
||||||
|
else:
|
||||||
|
write_all = element_differs(var_elem, values_to_write)
|
||||||
|
|
||||||
|
if not write_all:
|
||||||
|
continue # Пропускаем, если нет изменений
|
||||||
|
|
||||||
|
for tag, text in values_to_write.items():
|
||||||
|
set_sub_elem_text(var_elem, tag, text)
|
||||||
|
|
||||||
|
t3 = time.time()
|
||||||
# Преобразуем дерево в строку
|
# Преобразуем дерево в строку
|
||||||
self.table.check()
|
|
||||||
myXML.fwrite(root, self.xml_path)
|
myXML.fwrite(root, self.xml_path)
|
||||||
|
self.table.check()
|
||||||
|
t4 = time.time()
|
||||||
|
'''print(f"[T1] parse + set paths: {t1 - t0:.3f} сек")
|
||||||
|
print(f"[T2] prepare variables: {t2 - t1:.3f} сек")
|
||||||
|
print(f"[T3] loop + updates: {t3 - t2:.3f} сек")
|
||||||
|
print(f"[T4] write to file: {t4 - t3:.3f} сек")
|
||||||
|
print(f"[TOTAL] write_to_xml total: {t4 - t0:.3f} сек")'''
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Ошибка при сохранении XML: {e}")
|
print(f"Ошибка при сохранении XML: {e}")
|
||||||
|
|
||||||
|
|
||||||
def __open_output_file_with_program(self):
|
def __open_output_file_with_program(self):
|
||||||
output_path = self.get_output_path()
|
output_path = self.get_output_path()
|
||||||
if not output_path:
|
if not output_path:
|
||||||
|
|||||||
62
Src/README_DEVELOP.md
Normal file
62
Src/README_DEVELOP.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
# Для разработчиков
|
||||||
|
|
||||||
|
### Структура проекта:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Src
|
||||||
|
├── build/
|
||||||
|
│ └── build_and_clean.py # Билдинг проекта в .exe (через nuitka или pyinstaller)
|
||||||
|
├── DebugVarEdit_GUI.py # Главное окно
|
||||||
|
├── tms_debugvar_term.py # Терминал DebugVarTerminal
|
||||||
|
├── tms_debugvar_lowlevel.py # Виджет для выбора переменных для LowLevel Watch
|
||||||
|
├── var_table.py # Таблица выбранных переменных
|
||||||
|
├── var_selector_window.py # Окно выбора переменных
|
||||||
|
├── var_selector_table.py # Таблица переменных в окне выбора переменных
|
||||||
|
├── scan_progress_gui.py # Отображение процесса сканирования переменных
|
||||||
|
├── scan_vars.py # Сканирование переменных среди .c/.h файлов
|
||||||
|
├── generate_debug_vars.py # Генерация debug_vars.c
|
||||||
|
├── allvars_xml_parser.py # Парсинг XML со всеми переменными и структурами
|
||||||
|
├── csv_logger.py # Логирование переменных в CSV
|
||||||
|
├── myXML.py # Утилиты для XML
|
||||||
|
├── makefile_parser.py # Парсинг makefile на .c/.h файлы
|
||||||
|
├── var_setup.py # Подготовка переменных для окна выбора переменных
|
||||||
|
├── path_hints.py # Подсказки для автодополнения путей переменных
|
||||||
|
├── libclang.dll # Бибилиотека clang
|
||||||
|
├── icon.ico # Иконка
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### Зависимости
|
||||||
|
|
||||||
|
Для запуска приложения:
|
||||||
|
- **Python 3.7+**
|
||||||
|
- **clang** — используется для парсинга C-кода (требуется `libclang.dll`, лежит в папке Src)
|
||||||
|
- **PySide2** — GUI-фреймворк
|
||||||
|
- **lxml** — работа с XML
|
||||||
|
> Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7
|
||||||
|
|
||||||
|
Для сборки `.exe`:
|
||||||
|
- **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей
|
||||||
|
- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен для запуска `.exe`)
|
||||||
|
|
||||||
|
|
||||||
|
### Сборка:
|
||||||
|
Если вы хотите собрать `DebugVarEdit.exe` самостоятельно из исходников, используйте скрипт **build/build_and_clean.py**. Он автоматически собирает проект с помощью Nuitka или PyInstaller:
|
||||||
|
- Собирает проект в `DebugVarEdit.exe` в корневой папке.
|
||||||
|
- Включает:
|
||||||
|
- все необходимые `.dll` (например, `libclang.dll`),
|
||||||
|
- иконку (`icon.ico`),
|
||||||
|
- плагины PySide2.
|
||||||
|
- Очищает временные папки после сборки:
|
||||||
|
- `build_temp`
|
||||||
|
- `__pycache__`
|
||||||
|
- `<MAIN_SCRIPT_NAME>.*`
|
||||||
|
|
||||||
|
> Все пути, имена файлов, временные папки и выбор между Nuitka и PyInstaller можно настроить в начале файла `build_and_clean.py`.
|
||||||
|
|
||||||
|
### Установка зависимостей
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install clang PySide2 lxml nuitka pyinstaller
|
||||||
|
```
|
||||||
@@ -1,698 +0,0 @@
|
|||||||
import re
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
from PySide2.QtWidgets import (
|
|
||||||
QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton,
|
|
||||||
QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout
|
|
||||||
)
|
|
||||||
from PySide2.QtGui import QKeySequence, QKeyEvent
|
|
||||||
from PySide2.QtCore import Qt, QStringListModel, QSettings
|
|
||||||
import VariableTable
|
|
||||||
import setupVars
|
|
||||||
import myXML
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
array_re = re.compile(r'^(\w+)\[(\d+)\]$')
|
|
||||||
|
|
||||||
class VariableSelectorDialog(QDialog):
|
|
||||||
def __init__(self, table, all_vars, structs, typedefs, xml_path=None, parent=None):
|
|
||||||
super().__init__(parent)
|
|
||||||
self.setWindowTitle("Выбор переменных")
|
|
||||||
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
||||||
self.resize(600, 500)
|
|
||||||
self.selected_names = []
|
|
||||||
self._bckspc_pressed = False # флаг подавления добавления разделителя
|
|
||||||
self.table = table
|
|
||||||
self.all_vars = all_vars
|
|
||||||
self.structs = structs
|
|
||||||
self.typedefs = typedefs
|
|
||||||
self.expanded_vars = []
|
|
||||||
self.var_map = {v['name']: v for v in all_vars}
|
|
||||||
self.node_index = {}
|
|
||||||
self.xml_path = xml_path # сохраняем путь к xml
|
|
||||||
self.manual_completion_active = False
|
|
||||||
|
|
||||||
# --- Добавляем чекбокс для автодополнения ---
|
|
||||||
self.autocomplete_checkbox = QCheckBox("Включить автодополнение")
|
|
||||||
self.autocomplete_checkbox.setChecked(True)
|
|
||||||
|
|
||||||
# Инициализируем QSettings с именем организации и приложения
|
|
||||||
self.settings = QSettings("SET", "DebugVarEdit_VarsSelector")
|
|
||||||
# Восстанавливаем сохранённое состояние чекбокса, если есть
|
|
||||||
checked = self.settings.value("autocomplete_enabled", True, type=bool)
|
|
||||||
self.autocomplete_checkbox.setChecked(checked)
|
|
||||||
# При изменении состояния чекбокса сохраняем его
|
|
||||||
self.autocomplete_checkbox.stateChanged.connect(self.save_checkbox_state)
|
|
||||||
|
|
||||||
self.search_input = QLineEdit()
|
|
||||||
self.search_input.setPlaceholderText("Поиск по имени переменной...")
|
|
||||||
self.search_input.textChanged.connect(self.on_search_text_changed)
|
|
||||||
|
|
||||||
self.tree = QTreeWidget()
|
|
||||||
self.tree.setHeaderLabels(["Имя переменной", "Тип"])
|
|
||||||
self.tree.setSelectionMode(QTreeWidget.ExtendedSelection)
|
|
||||||
self.tree.setRootIsDecorated(True)
|
|
||||||
self.tree.setUniformRowHeights(True)
|
|
||||||
|
|
||||||
self.tree.setStyleSheet("""
|
|
||||||
QTreeWidget::item:selected {
|
|
||||||
background-color: #87CEFA;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
QTreeWidget::item:hover {
|
|
||||||
background-color: #D3D3D3;
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
|
|
||||||
self.btn_add = QPushButton("Добавить выбранные")
|
|
||||||
self.btn_add.clicked.connect(self.on_add_clicked)
|
|
||||||
|
|
||||||
self.btn_delete = QPushButton("Удалить выбранные")
|
|
||||||
self.btn_delete.clicked.connect(self.on_delete_clicked)
|
|
||||||
|
|
||||||
self.completer = QCompleter()
|
|
||||||
self.completer.setCompletionMode(QCompleter.PopupCompletion) # важно!
|
|
||||||
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
|
||||||
self.completer.setFilterMode(Qt.MatchContains)
|
|
||||||
self.completer.setWidget(self.search_input)
|
|
||||||
|
|
||||||
|
|
||||||
self.search_input.installEventFilter(self)
|
|
||||||
|
|
||||||
# Создаем горизонтальный layout для "Поиск:" и чекбокса справа
|
|
||||||
search_layout = QHBoxLayout()
|
|
||||||
label_search = QLabel("Поиск:")
|
|
||||||
search_layout.addWidget(label_search, alignment=Qt.AlignLeft)
|
|
||||||
search_layout.addStretch() # чтобы чекбокс прижался вправо
|
|
||||||
search_layout.addWidget(self.autocomplete_checkbox, alignment=Qt.AlignRight)
|
|
||||||
self.completer.activated[str].connect(self.insert_completion)
|
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
|
||||||
layout.addLayout(search_layout) # заменили label и чекбокс
|
|
||||||
layout.addWidget(self.search_input)
|
|
||||||
layout.addWidget(self.tree)
|
|
||||||
layout.addWidget(self.btn_add)
|
|
||||||
layout.addWidget(self.btn_delete)
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
self.expanded_vars = setupVars.expand_vars(self.all_vars, self.structs, self.typedefs)
|
|
||||||
self.build_completion_list()
|
|
||||||
self.populate_tree()
|
|
||||||
|
|
||||||
|
|
||||||
def get_full_item_name(self, item):
|
|
||||||
names = []
|
|
||||||
while item:
|
|
||||||
names.append(item.text(0))
|
|
||||||
item = item.parent()
|
|
||||||
return '.'.join(reversed(names))
|
|
||||||
|
|
||||||
def build_completion_list(self):
|
|
||||||
# Собираем список полных имён всех переменных и вложенных полей
|
|
||||||
completions = []
|
|
||||||
|
|
||||||
def recurse(var, prefix=''):
|
|
||||||
fullname = f"{prefix}.{var['name']}" if prefix else var['name']
|
|
||||||
completions.append(fullname)
|
|
||||||
for child in var.get('children', []):
|
|
||||||
recurse(child, fullname)
|
|
||||||
|
|
||||||
for v in self.expanded_vars:
|
|
||||||
recurse(v)
|
|
||||||
|
|
||||||
self.all_completions = completions
|
|
||||||
|
|
||||||
def add_tree_item_recursively(self, parent, var):
|
|
||||||
"""
|
|
||||||
Рекурсивно добавляет переменную и её дочерние поля в дерево.
|
|
||||||
Если parent == None, добавляет на верхний уровень.
|
|
||||||
"""
|
|
||||||
name = var['name']
|
|
||||||
type_str = var.get('type', '')
|
|
||||||
show_var = var.get('show_var', 'false') == 'true'
|
|
||||||
|
|
||||||
item = QTreeWidgetItem([name, type_str])
|
|
||||||
item.setData(0, Qt.UserRole, name)
|
|
||||||
full_name = self.get_full_item_name(item)
|
|
||||||
self.node_index[full_name.lower()] = item
|
|
||||||
|
|
||||||
# Делаем bitfield-поля неактивными
|
|
||||||
if "(bitfield:" in type_str:
|
|
||||||
item.setDisabled(True)
|
|
||||||
self.set_tool(item, "Битовые поля недоступны для выбора")
|
|
||||||
|
|
||||||
for i, attr in enumerate(['file', 'extern', 'static']):
|
|
||||||
item.setData(0, Qt.UserRole + 1 + i, var.get(attr))
|
|
||||||
|
|
||||||
if show_var:
|
|
||||||
item.setForeground(0, Qt.gray)
|
|
||||||
item.setForeground(1, Qt.gray)
|
|
||||||
self.set_tool(item, "Уже добавлена")
|
|
||||||
|
|
||||||
if parent is None:
|
|
||||||
self.tree.addTopLevelItem(item)
|
|
||||||
else:
|
|
||||||
parent.addChild(item)
|
|
||||||
|
|
||||||
for child in var.get('children', []):
|
|
||||||
self.add_tree_item_recursively(item, child)
|
|
||||||
|
|
||||||
|
|
||||||
def populate_tree(self, vars_list=None):
|
|
||||||
if vars_list is None:
|
|
||||||
vars_list = self.expanded_vars
|
|
||||||
self.tree.clear()
|
|
||||||
self.node_index.clear()
|
|
||||||
for var in vars_list:
|
|
||||||
self.add_tree_item_recursively(None, var)
|
|
||||||
|
|
||||||
header = self.tree.header()
|
|
||||||
header.setSectionResizeMode(QHeaderView.Interactive) # вручную можно менять
|
|
||||||
self.tree.setColumnWidth(0, 400)
|
|
||||||
self.tree.resizeColumnToContents(1)
|
|
||||||
|
|
||||||
def expand_to_level(self, item, level, current_level=0):
|
|
||||||
"""
|
|
||||||
Рекурсивно раскрывает узлы до заданного уровня.
|
|
||||||
"""
|
|
||||||
if current_level < level:
|
|
||||||
item.setExpanded(True)
|
|
||||||
else:
|
|
||||||
item.setExpanded(False)
|
|
||||||
|
|
||||||
for i in range(item.childCount()):
|
|
||||||
self.expand_to_level(item.child(i), level, current_level + 1)
|
|
||||||
|
|
||||||
def filter_tree(self):
|
|
||||||
text = self.search_input.text().strip().lower()
|
|
||||||
path_parts = text.split('.') if text else []
|
|
||||||
filtered_vars = filter_vars(self.expanded_vars, path_parts)
|
|
||||||
|
|
||||||
# Сначала перерисовываем дерево
|
|
||||||
self.populate_tree(filtered_vars)
|
|
||||||
|
|
||||||
# Теперь node_index уже пересоздан — можно работать
|
|
||||||
expand_level = len(path_parts) - 1 if path_parts else 0
|
|
||||||
for i in range(self.tree.topLevelItemCount()):
|
|
||||||
item = self.tree.topLevelItem(i)
|
|
||||||
self.expand_to_level(item, expand_level)
|
|
||||||
|
|
||||||
# Раскрываем путь до точного совпадения
|
|
||||||
if path_parts:
|
|
||||||
fullname = '.'.join(path_parts)
|
|
||||||
node = self.node_index.get(fullname.lower())
|
|
||||||
if node:
|
|
||||||
parent = node.parent()
|
|
||||||
while parent:
|
|
||||||
parent.setExpanded(True)
|
|
||||||
parent = parent.parent()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def find_node_by_path(self, root_vars, path_list):
|
|
||||||
current_level = root_vars
|
|
||||||
node = None
|
|
||||||
for part in path_list:
|
|
||||||
node = None
|
|
||||||
for var in current_level:
|
|
||||||
if var['name'] == part:
|
|
||||||
node = var
|
|
||||||
break
|
|
||||||
if node is None:
|
|
||||||
return None
|
|
||||||
current_level = node.get('children', [])
|
|
||||||
return node
|
|
||||||
|
|
||||||
def update_completions(self, text=None):
|
|
||||||
if text is None:
|
|
||||||
text = self.search_input.text().strip()
|
|
||||||
else:
|
|
||||||
text = text.strip()
|
|
||||||
|
|
||||||
parts = self.split_path(text)
|
|
||||||
path_parts = parts[:-1] if parts else []
|
|
||||||
prefix = parts[-1].lower() if parts else ''
|
|
||||||
ends_with_sep = text.endswith('.') or text.endswith('->') or text.endswith('[')
|
|
||||||
is_index_suggestion = text.endswith('[')
|
|
||||||
|
|
||||||
completions = []
|
|
||||||
|
|
||||||
def find_exact_node(parts):
|
|
||||||
# Ищем точный узел по полному пути, используя node_index
|
|
||||||
# Постепенно собираем fullname из parts
|
|
||||||
if not parts:
|
|
||||||
return None
|
|
||||||
fullname = parts[0]
|
|
||||||
for p in parts[1:]:
|
|
||||||
fullname += '.' + p
|
|
||||||
return self.node_index.get(fullname.lower())
|
|
||||||
|
|
||||||
if is_index_suggestion:
|
|
||||||
base_text = text[:-1] # убираем '['
|
|
||||||
parent_node = self.find_node_by_fullname(base_text)
|
|
||||||
if not parent_node:
|
|
||||||
# если base_text может содержать индекс типа foo[12], попробуем очистить
|
|
||||||
base_text_clean = re.sub(r'\[\d+\]$', '', base_text)
|
|
||||||
parent_node = self.find_node_by_fullname(base_text_clean)
|
|
||||||
if parent_node:
|
|
||||||
seen = set()
|
|
||||||
for i in range(parent_node.childCount()):
|
|
||||||
child = parent_node.child(i)
|
|
||||||
cname = child.text(0)
|
|
||||||
m = re.match(rf'^{re.escape(base_text)}\[(\d+)\]$', cname)
|
|
||||||
if m and cname not in seen:
|
|
||||||
completions.append(cname)
|
|
||||||
seen.add(cname)
|
|
||||||
self.completer.setModel(QStringListModel(completions))
|
|
||||||
return completions
|
|
||||||
|
|
||||||
if ends_with_sep:
|
|
||||||
# Путь завершен, показываем детей узла
|
|
||||||
node = self.find_node_by_fullname(text[:-1])
|
|
||||||
if node:
|
|
||||||
completions.extend(node.child(i).text(0) for i in range(node.childCount()))
|
|
||||||
elif not path_parts:
|
|
||||||
# Первый уровень — по вхождению
|
|
||||||
for i in range(self.tree.topLevelItemCount()):
|
|
||||||
item = self.tree.topLevelItem(i)
|
|
||||||
name = item.text(0).lower()
|
|
||||||
if prefix in name:
|
|
||||||
completions.append(item.text(0))
|
|
||||||
else:
|
|
||||||
node = find_exact_node(path_parts)
|
|
||||||
if node:
|
|
||||||
for i in range(node.childCount()):
|
|
||||||
child = node.child(i)
|
|
||||||
name = child.text(0)
|
|
||||||
# Оптимизируем split_path - кэширование
|
|
||||||
name_parts = child.data(0, Qt.UserRole + 10)
|
|
||||||
if name_parts is None:
|
|
||||||
name_parts = self.split_path(name)
|
|
||||||
child.setData(0, Qt.UserRole + 10, name_parts)
|
|
||||||
if not name_parts:
|
|
||||||
continue
|
|
||||||
last_part = name_parts[-1].lower()
|
|
||||||
if prefix == '' or prefix in last_part: # здесь изменено
|
|
||||||
completions.append(name)
|
|
||||||
|
|
||||||
|
|
||||||
self.completer.complete()
|
|
||||||
return completions
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Функция для поиска узла с полным именем
|
|
||||||
def find_node_by_fullname(self, name):
|
|
||||||
return self.node_index.get(name.lower())
|
|
||||||
|
|
||||||
def insert_completion(self, text):
|
|
||||||
node = self.find_node_by_fullname(text)
|
|
||||||
if node and node.childCount() > 0 and not (text.endswith('.') or text.endswith('->') or text.endswith('[')):
|
|
||||||
# Определяем разделитель по имени первого ребёнка
|
|
||||||
child_name = node.child(0).text(0)
|
|
||||||
if child_name.startswith(text + '->'):
|
|
||||||
text += '->'
|
|
||||||
elif child_name.startswith(text + '.'):
|
|
||||||
text += '.'
|
|
||||||
elif '[' in child_name:
|
|
||||||
text += '[' # для массивов
|
|
||||||
else:
|
|
||||||
text += '.' # fallback
|
|
||||||
|
|
||||||
if not self._bckspc_pressed:
|
|
||||||
self.search_input.setText(text)
|
|
||||||
self.search_input.setCursorPosition(len(text))
|
|
||||||
|
|
||||||
self.run_completions(text)
|
|
||||||
else:
|
|
||||||
self.search_input.setText(text)
|
|
||||||
self.search_input.setCursorPosition(len(text))
|
|
||||||
|
|
||||||
def eventFilter(self, obj, event):
|
|
||||||
if obj == self.search_input and isinstance(event, QKeyEvent):
|
|
||||||
if event.key() == Qt.Key_Space and event.modifiers() & Qt.ControlModifier:
|
|
||||||
self.manual_completion_active = True
|
|
||||||
text = self.search_input.text().strip()
|
|
||||||
self.run_completions(text)
|
|
||||||
elif event.key() == Qt.Key_Escape:
|
|
||||||
# Esc — выключаем ручной режим и скрываем подсказки, если autocomplete выключен
|
|
||||||
if not self.autocomplete_checkbox.isChecked():
|
|
||||||
self.manual_completion_active = False
|
|
||||||
self.completer.popup().hide()
|
|
||||||
return True
|
|
||||||
|
|
||||||
if event.key() == Qt.Key_Backspace:
|
|
||||||
self._bckspc_pressed = True
|
|
||||||
else:
|
|
||||||
self._bckspc_pressed = False
|
|
||||||
|
|
||||||
return super().eventFilter(obj, event)
|
|
||||||
|
|
||||||
def run_completions(self, text):
|
|
||||||
completions = self.update_completions(text)
|
|
||||||
|
|
||||||
if not self.autocomplete_checkbox.isChecked() and self._bckspc_pressed:
|
|
||||||
text = text[:-1]
|
|
||||||
|
|
||||||
if len(completions) == 1 and completions[0].lower() == text.lower():
|
|
||||||
# Найдем узел с таким именем
|
|
||||||
def find_exact_item(name):
|
|
||||||
stack = [self.tree.topLevelItem(i) for i in range(self.tree.topLevelItemCount())]
|
|
||||||
while stack:
|
|
||||||
node = stack.pop()
|
|
||||||
if node.text(0).lower() == name.lower():
|
|
||||||
return node
|
|
||||||
for i in range(node.childCount()):
|
|
||||||
stack.append(node.child(i))
|
|
||||||
return None
|
|
||||||
|
|
||||||
node = find_exact_item(completions[0])
|
|
||||||
if node and node.childCount() > 0:
|
|
||||||
# Используем первую подсказку, чтобы определить нужный разделитель
|
|
||||||
completions = self.update_completions(text + '.')
|
|
||||||
suggestion = completions[0]
|
|
||||||
|
|
||||||
# Ищем, какой символ идёт после текущего текста
|
|
||||||
separator = '.'
|
|
||||||
if suggestion.startswith(text):
|
|
||||||
rest = suggestion[len(text):]
|
|
||||||
if rest.startswith(text + '->'):
|
|
||||||
separator += '->'
|
|
||||||
elif rest.startswith(text + '.'):
|
|
||||||
separator += '.'
|
|
||||||
elif '[' in rest:
|
|
||||||
separator += '[' # для массивов
|
|
||||||
else:
|
|
||||||
separator += '.' # fallback
|
|
||||||
|
|
||||||
if not self._bckspc_pressed:
|
|
||||||
self.search_input.setText(text + separator)
|
|
||||||
completions = self.update_completions(text)
|
|
||||||
self.completer.setModel(QStringListModel(completions))
|
|
||||||
self.completer.complete()
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Иначе просто показываем подсказки
|
|
||||||
self.completer.setModel(QStringListModel(completions))
|
|
||||||
if completions:
|
|
||||||
self.completer.complete()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def on_search_text_changed(self, text):
|
|
||||||
self.filter_tree()
|
|
||||||
if text == None:
|
|
||||||
text = self.search_input.text().strip()
|
|
||||||
if self.autocomplete_checkbox.isChecked():
|
|
||||||
self.run_completions(text)
|
|
||||||
else:
|
|
||||||
# Если выключено, показываем подсказки только если флаг ручного вызова True
|
|
||||||
if self.manual_completion_active:
|
|
||||||
self.run_completions(text)
|
|
||||||
else:
|
|
||||||
self.completer.popup().hide()
|
|
||||||
|
|
||||||
def on_add_clicked(self):
|
|
||||||
self.selected_names = []
|
|
||||||
self.tree.setFocus()
|
|
||||||
|
|
||||||
for item in self.tree.selectedItems():
|
|
||||||
name = item.text(0) # имя переменной (в колонке 1)
|
|
||||||
type_str = item.text(1) # тип переменной (в колонке 2)
|
|
||||||
|
|
||||||
if not name:
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.selected_names.append((name, type_str))
|
|
||||||
|
|
||||||
if name in self.var_map:
|
|
||||||
# Если переменная уже есть, просто включаем её и показываем
|
|
||||||
var = self.var_map[name]
|
|
||||||
var['show_var'] = 'true'
|
|
||||||
var['enable'] = 'true'
|
|
||||||
else:
|
|
||||||
# Создаём новый элемент переменной
|
|
||||||
# Получаем родительские параметры
|
|
||||||
file_val = item.data(0, Qt.UserRole + 1)
|
|
||||||
extern_val = item.data(0, Qt.UserRole + 2)
|
|
||||||
static_val = item.data(0, Qt.UserRole + 3)
|
|
||||||
|
|
||||||
new_var = {
|
|
||||||
'name': name,
|
|
||||||
'type': type_str,
|
|
||||||
'show_var': 'true',
|
|
||||||
'enable': 'true',
|
|
||||||
'shortname': name,
|
|
||||||
'pt_type': '',
|
|
||||||
'iq_type': '',
|
|
||||||
'return_type': 'iq_none',
|
|
||||||
'file': file_val,
|
|
||||||
'extern': str(extern_val).lower() if extern_val else 'false',
|
|
||||||
'static': str(static_val).lower() if static_val else 'false',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Добавляем в список переменных
|
|
||||||
self.all_vars.append(new_var)
|
|
||||||
self.var_map[name] = new_var # Чтобы в будущем не добавлялось повторно
|
|
||||||
|
|
||||||
self.done(QDialog.Accepted)
|
|
||||||
|
|
||||||
|
|
||||||
def on_delete_clicked(self):
|
|
||||||
selected_names = self._get_selected_var_names()
|
|
||||||
if not selected_names:
|
|
||||||
print("nothing selected")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Обновляем var_map и all_vars
|
|
||||||
for name in selected_names:
|
|
||||||
if name in self.var_map:
|
|
||||||
self.var_map[name]['show_var'] = 'false'
|
|
||||||
self.var_map[name]['enable'] = 'false'
|
|
||||||
|
|
||||||
for v in self.all_vars:
|
|
||||||
if v['name'] == name:
|
|
||||||
v['show_var'] = 'false'
|
|
||||||
v['enable'] = 'false'
|
|
||||||
break
|
|
||||||
|
|
||||||
# Проверка пути к XML
|
|
||||||
if not hasattr(self, 'xml_path') or not self.xml_path:
|
|
||||||
from PySide2.QtWidgets import QMessageBox
|
|
||||||
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.")
|
|
||||||
return
|
|
||||||
|
|
||||||
root, tree = myXML.safe_parse_xml(self.xml_path)
|
|
||||||
if root is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
vars_section = root.find('variables')
|
|
||||||
if vars_section is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
for var_elem in vars_section.findall('var'):
|
|
||||||
name = var_elem.attrib.get('name')
|
|
||||||
if name in selected_names:
|
|
||||||
def set_text(tag, value):
|
|
||||||
el = var_elem.find(tag)
|
|
||||||
if el is None:
|
|
||||||
el = ET.SubElement(var_elem, tag)
|
|
||||||
el.text = value
|
|
||||||
set_text('show_var', 'false')
|
|
||||||
set_text('enable', 'false')
|
|
||||||
|
|
||||||
myXML.fwrite(root, self.xml_path)
|
|
||||||
|
|
||||||
self.done(QDialog.Accepted)
|
|
||||||
|
|
||||||
|
|
||||||
def set_tool(self, item, text):
|
|
||||||
item.setToolTip(0, text)
|
|
||||||
item.setToolTip(1, text)
|
|
||||||
|
|
||||||
|
|
||||||
def keyPressEvent(self, event):
|
|
||||||
if event.key() == Qt.Key_Delete:
|
|
||||||
self.delete_selected_vars()
|
|
||||||
else:
|
|
||||||
super().keyPressEvent(event)
|
|
||||||
|
|
||||||
def delete_selected_vars(self):
|
|
||||||
selected_names = self._get_selected_var_names()
|
|
||||||
if not selected_names:
|
|
||||||
print("nothing selected")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Обновляем var_map и all_vars
|
|
||||||
for name in selected_names:
|
|
||||||
if name in self.var_map:
|
|
||||||
self.var_map[name]['show_var'] = 'false'
|
|
||||||
self.var_map[name]['enable'] = 'false'
|
|
||||||
|
|
||||||
for v in self.all_vars:
|
|
||||||
if v['name'] == name:
|
|
||||||
v['show_var'] = 'false'
|
|
||||||
v['enable'] = 'false'
|
|
||||||
break
|
|
||||||
|
|
||||||
# Проверка пути к XML
|
|
||||||
if not hasattr(self, 'xml_path') or not self.xml_path:
|
|
||||||
from PySide2.QtWidgets import QMessageBox
|
|
||||||
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.")
|
|
||||||
return
|
|
||||||
|
|
||||||
root, tree = myXML.safe_parse_xml(self.xml_path)
|
|
||||||
if root is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
vars_section = root.find('variables')
|
|
||||||
if vars_section is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
for var_elem in vars_section.findall('var'):
|
|
||||||
name = var_elem.attrib.get('name')
|
|
||||||
if name in selected_names:
|
|
||||||
def set_text(tag, value):
|
|
||||||
el = var_elem.find(tag)
|
|
||||||
if el is None:
|
|
||||||
el = ET.SubElement(var_elem, tag)
|
|
||||||
el.text = value
|
|
||||||
set_text('show_var', 'false')
|
|
||||||
set_text('enable', 'false')
|
|
||||||
|
|
||||||
myXML.fwrite(root, self.xml_path)
|
|
||||||
|
|
||||||
self.table.populate(self.all_vars, self.structs, None)
|
|
||||||
|
|
||||||
# Проверка пути к XML
|
|
||||||
if not hasattr(self, 'xml_path') or not self.xml_path:
|
|
||||||
from PySide2.QtWidgets import QMessageBox
|
|
||||||
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно удалить переменные.")
|
|
||||||
return
|
|
||||||
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
root, tree = myXML.safe_parse_xml(self.xml_path)
|
|
||||||
if root is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
vars_section = root.find('variables')
|
|
||||||
if vars_section is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
removed_any = False
|
|
||||||
for var_elem in list(vars_section.findall('var')):
|
|
||||||
name = var_elem.attrib.get('name')
|
|
||||||
if name in selected_names:
|
|
||||||
vars_section.remove(var_elem)
|
|
||||||
removed_any = True
|
|
||||||
self.var_map.pop(name, None)
|
|
||||||
|
|
||||||
# Удаляем из all_vars (глобально)
|
|
||||||
self.all_vars[:] = [v for v in self.all_vars if v['name'] not in selected_names]
|
|
||||||
|
|
||||||
# Удаляем из expanded_vars (тоже глобально)
|
|
||||||
def filter_out_selected(vars_list):
|
|
||||||
filtered = []
|
|
||||||
for v in vars_list:
|
|
||||||
if v['name'] not in selected_names:
|
|
||||||
# Рекурсивно фильтруем детей, если есть
|
|
||||||
if 'children' in v:
|
|
||||||
v = v.copy()
|
|
||||||
v['children'] = filter_out_selected(v['children'])
|
|
||||||
filtered.append(v)
|
|
||||||
return filtered
|
|
||||||
|
|
||||||
self.expanded_vars[:] = filter_out_selected(self.expanded_vars)
|
|
||||||
if removed_any:
|
|
||||||
myXML.fwrite(root, self.xml_path)
|
|
||||||
|
|
||||||
self.filter_tree()
|
|
||||||
|
|
||||||
def _get_selected_var_names(self):
|
|
||||||
self.tree.setFocus()
|
|
||||||
return [item.text(0) for item in self.tree.selectedItems() if item.text(0)]
|
|
||||||
|
|
||||||
|
|
||||||
def save_checkbox_state(self):
|
|
||||||
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def split_path(self, path):
|
|
||||||
"""
|
|
||||||
Разбивает путь на компоненты:
|
|
||||||
- 'foo[2].bar[1]->baz' → ['foo', [2]', 'bar', '[1]' 'baz']
|
|
||||||
"""
|
|
||||||
tokens = []
|
|
||||||
token = ''
|
|
||||||
i = 0
|
|
||||||
while i < len(path):
|
|
||||||
c = path[i]
|
|
||||||
# Разделители: '->' и '.'
|
|
||||||
if c == '-' and path[i:i+2] == '->':
|
|
||||||
if token:
|
|
||||||
tokens.append(token)
|
|
||||||
token = ''
|
|
||||||
i += 2
|
|
||||||
continue
|
|
||||||
elif c == '.':
|
|
||||||
if token:
|
|
||||||
tokens.append(token)
|
|
||||||
token = ''
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
elif c == '[':
|
|
||||||
# Заканчиваем текущий токен, если есть
|
|
||||||
if token:
|
|
||||||
tokens.append(token)
|
|
||||||
token = ''
|
|
||||||
# Собираем индекс [N]
|
|
||||||
idx = ''
|
|
||||||
while i < len(path) and path[i] != ']':
|
|
||||||
idx += path[i]
|
|
||||||
i += 1
|
|
||||||
if i < len(path) and path[i] == ']':
|
|
||||||
idx += ']'
|
|
||||||
i += 1
|
|
||||||
tokens.append(idx)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
token += c
|
|
||||||
i += 1
|
|
||||||
if token:
|
|
||||||
tokens.append(token)
|
|
||||||
return tokens
|
|
||||||
|
|
||||||
|
|
||||||
def filter_vars(vars_list, path_parts):
|
|
||||||
"""Рекурсивно фильтруем vars_list по path_parts и возвращаем только подходящие."""
|
|
||||||
filtered = []
|
|
||||||
|
|
||||||
def matches_path(name, search_parts):
|
|
||||||
name_parts = name.lower().split('.')
|
|
||||||
if len(name_parts) < len(search_parts):
|
|
||||||
return False
|
|
||||||
for sp, np in zip(search_parts, name_parts):
|
|
||||||
if not np.startswith(sp):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
for var in vars_list:
|
|
||||||
fullname = var.get('fullname', var['name']) # желательно иметь полное имя
|
|
||||||
# Если фильтра нет — берем всё
|
|
||||||
if not path_parts or matches_path(fullname, path_parts):
|
|
||||||
# Копируем узел с рекурсией по детям
|
|
||||||
new_var = var.copy()
|
|
||||||
if 'children' in var:
|
|
||||||
new_var['children'] = filter_vars(var['children'], path_parts)
|
|
||||||
filtered.append(new_var)
|
|
||||||
else:
|
|
||||||
# Но даже если этот узел не подходит, может подойти его потомок
|
|
||||||
if 'children' in var:
|
|
||||||
child_filtered = filter_vars(var['children'], path_parts)
|
|
||||||
if child_filtered:
|
|
||||||
new_var = var.copy()
|
|
||||||
new_var['children'] = child_filtered
|
|
||||||
filtered.append(new_var)
|
|
||||||
|
|
||||||
return filtered
|
|
||||||
@@ -1,271 +0,0 @@
|
|||||||
from PySide2.QtWidgets import (
|
|
||||||
QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter,
|
|
||||||
QAbstractItemView, QHeaderView, QLabel
|
|
||||||
)
|
|
||||||
from PySide2.QtGui import QColor, QBrush, QPalette
|
|
||||||
from PySide2.QtCore import Qt
|
|
||||||
from enum import IntEnum
|
|
||||||
from generateVars import type_map
|
|
||||||
|
|
||||||
class rows(IntEnum):
|
|
||||||
No = 0
|
|
||||||
include = 1
|
|
||||||
name = 2
|
|
||||||
type = 3
|
|
||||||
pt_type = 4
|
|
||||||
iq_type = 5
|
|
||||||
ret_type = 6
|
|
||||||
short_name = 7
|
|
||||||
|
|
||||||
|
|
||||||
class VariableTableWidget(QTableWidget):
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super().__init__(0, 8, parent)
|
|
||||||
# Таблица переменных
|
|
||||||
self.setHorizontalHeaderLabels([
|
|
||||||
'№', # новый столбец
|
|
||||||
'En',
|
|
||||||
'Name',
|
|
||||||
'Origin Type',
|
|
||||||
'Pointer Type',
|
|
||||||
'IQ Type',
|
|
||||||
'Return Type',
|
|
||||||
'Short Name'
|
|
||||||
])
|
|
||||||
self.setEditTriggers(QAbstractItemView.AllEditTriggers)
|
|
||||||
self.var_list = []
|
|
||||||
|
|
||||||
self.type_options = list(dict.fromkeys(type_map.values()))
|
|
||||||
self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
|
|
||||||
self.iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
|
|
||||||
|
|
||||||
header = self.horizontalHeader()
|
|
||||||
# Для остальных колонок — растяжение (Stretch), чтобы они заняли всю оставшуюся ширину
|
|
||||||
|
|
||||||
for col in range(self.columnCount()):
|
|
||||||
if col == self.columnCount() - 1:
|
|
||||||
header.setSectionResizeMode(col, QHeaderView.Stretch)
|
|
||||||
else:
|
|
||||||
header.setSectionResizeMode(col, QHeaderView.Interactive)
|
|
||||||
|
|
||||||
parent_widget = self.parentWidget()
|
|
||||||
# Сделаем колонки с номерами фиксированной ширины
|
|
||||||
self.setColumnWidth(rows.No, 30)
|
|
||||||
self.setColumnWidth(rows.include, 30)
|
|
||||||
self.setColumnWidth(rows.pt_type, 85)
|
|
||||||
self.setColumnWidth(rows.iq_type, 85)
|
|
||||||
self.setColumnWidth(rows.ret_type, 85)
|
|
||||||
|
|
||||||
self.setColumnWidth(rows.name, 300)
|
|
||||||
self.setColumnWidth(rows.type, 100)
|
|
||||||
self._resizing = False
|
|
||||||
self.horizontalHeader().sectionResized.connect(self.on_section_resized)
|
|
||||||
|
|
||||||
|
|
||||||
def populate(self, vars_list, structs, on_change_callback):
|
|
||||||
self.var_list = vars_list
|
|
||||||
self.type_options = list(dict.fromkeys(type_map.values()))
|
|
||||||
self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
|
|
||||||
iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
|
|
||||||
|
|
||||||
# --- ДО: удаляем отображение структур и union-переменных
|
|
||||||
for var in vars_list:
|
|
||||||
pt_type = var.get('pt_type', '')
|
|
||||||
if 'struct' in pt_type or 'union' in pt_type:
|
|
||||||
var['show_var'] = 'false'
|
|
||||||
var['enable'] = 'false'
|
|
||||||
|
|
||||||
|
|
||||||
filtered_vars = [v for v in vars_list if v.get('show_var', 'false') == 'true']
|
|
||||||
self.setRowCount(len(filtered_vars))
|
|
||||||
self.verticalHeader().setVisible(False)
|
|
||||||
style_with_padding = "padding-left: 5px; padding-right: 5px; font-size: 14pt; font-family: 'Segoe UI';"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for row, var in enumerate(filtered_vars):
|
|
||||||
# №
|
|
||||||
no_item = QTableWidgetItem(str(row))
|
|
||||||
no_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
|
||||||
self.setItem(row, rows.No, no_item)
|
|
||||||
|
|
||||||
# Enable
|
|
||||||
cb = QCheckBox()
|
|
||||||
cb.setChecked(var.get('enable', 'false') == 'true')
|
|
||||||
cb.stateChanged.connect(on_change_callback)
|
|
||||||
cb.setStyleSheet(style_with_padding)
|
|
||||||
self.setCellWidget(row, rows.include, cb)
|
|
||||||
|
|
||||||
# Name
|
|
||||||
name_edit = QLineEdit(var['name'])
|
|
||||||
if var['type'] in structs:
|
|
||||||
completer = QCompleter(structs[var['type']].keys())
|
|
||||||
completer.setCaseSensitivity(Qt.CaseInsensitive)
|
|
||||||
name_edit.setCompleter(completer)
|
|
||||||
name_edit.textChanged.connect(on_change_callback)
|
|
||||||
name_edit.setStyleSheet(style_with_padding)
|
|
||||||
self.setCellWidget(row, rows.name, name_edit)
|
|
||||||
|
|
||||||
# Origin Type (readonly)
|
|
||||||
origin_item = QTableWidgetItem(var.get('type', ''))
|
|
||||||
origin_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
|
||||||
origin_item.setToolTip(var.get('type', '')) # Всплывающая подсказка
|
|
||||||
origin_item.setForeground(QBrush(Qt.black))
|
|
||||||
self.setItem(row, rows.type, origin_item)
|
|
||||||
|
|
||||||
# pt_type
|
|
||||||
pt_combo = QComboBox()
|
|
||||||
pt_combo.addItems(self.display_type_options)
|
|
||||||
value = var['pt_type'].replace('pt_', '')
|
|
||||||
if value not in self.display_type_options:
|
|
||||||
pt_combo.addItem(value)
|
|
||||||
pt_combo.setCurrentText(value)
|
|
||||||
pt_combo.currentTextChanged.connect(on_change_callback)
|
|
||||||
pt_combo.setStyleSheet(style_with_padding)
|
|
||||||
self.setCellWidget(row, rows.pt_type, pt_combo)
|
|
||||||
|
|
||||||
# iq_type
|
|
||||||
iq_combo = QComboBox()
|
|
||||||
iq_combo.addItems(self.iq_types)
|
|
||||||
value = var['iq_type'].replace('t_', '')
|
|
||||||
if value not in self.iq_types:
|
|
||||||
iq_combo.addItem(value)
|
|
||||||
iq_combo.setCurrentText(value)
|
|
||||||
iq_combo.currentTextChanged.connect(on_change_callback)
|
|
||||||
iq_combo.setStyleSheet(style_with_padding)
|
|
||||||
self.setCellWidget(row, rows.iq_type, iq_combo)
|
|
||||||
|
|
||||||
# return_type
|
|
||||||
ret_combo = QComboBox()
|
|
||||||
ret_combo.addItems(self.iq_types)
|
|
||||||
ret_combo.setCurrentText(var.get('return_type', ''))
|
|
||||||
ret_combo.currentTextChanged.connect(on_change_callback)
|
|
||||||
ret_combo.setStyleSheet(style_with_padding)
|
|
||||||
self.setCellWidget(row, rows.ret_type, ret_combo)
|
|
||||||
|
|
||||||
# short_name
|
|
||||||
short_name_val = var.get('shortname', var['name'])
|
|
||||||
short_name_edit = QLineEdit(short_name_val)
|
|
||||||
short_name_edit.textChanged.connect(on_change_callback)
|
|
||||||
short_name_edit.setStyleSheet(style_with_padding)
|
|
||||||
self.setCellWidget(row, rows.short_name, short_name_edit)
|
|
||||||
|
|
||||||
self.check()
|
|
||||||
|
|
||||||
def check(self):
|
|
||||||
warning_color = (QColor("#FFFACD")) # Жёлтый для длинных shortname
|
|
||||||
error_color = (QColor("#FFB6C1")) # Светло-красный для отсутствующих переменных
|
|
||||||
tooltip_shortname = "Short Name длиннее 10 символов — будет обрезано при генерации"
|
|
||||||
tooltip_missing = f'Имя переменной не найдено среди переменных. Добавьте её через кнопку "Добавить переменные"'
|
|
||||||
|
|
||||||
for row in range(self.rowCount()):
|
|
||||||
# Получаем имя переменной (столбец `name`)
|
|
||||||
name_widget = self.cellWidget(row, rows.name)
|
|
||||||
name = name_widget.text() if name_widget else ""
|
|
||||||
|
|
||||||
# Получаем shortname
|
|
||||||
short_name_edit = self.cellWidget(row, rows.short_name)
|
|
||||||
shortname = short_name_edit.text() if short_name_edit else ""
|
|
||||||
|
|
||||||
# Флаги ошибок
|
|
||||||
long_shortname = len(shortname) > 10
|
|
||||||
found = any(v.get('name') == name for v in self.var_list)
|
|
||||||
|
|
||||||
# Выбираем цвет и подсказку
|
|
||||||
color = None
|
|
||||||
tooltip = ""
|
|
||||||
if not found:
|
|
||||||
color = error_color
|
|
||||||
tooltip = tooltip_missing
|
|
||||||
elif long_shortname:
|
|
||||||
color = warning_color
|
|
||||||
tooltip = tooltip_shortname
|
|
||||||
|
|
||||||
self.highlight_row(row, color, tooltip)
|
|
||||||
|
|
||||||
|
|
||||||
def read_data(self):
|
|
||||||
result = []
|
|
||||||
for row in range(self.rowCount()):
|
|
||||||
cb = self.cellWidget(row, rows.include)
|
|
||||||
name = self.cellWidget(row, rows.name).text()
|
|
||||||
pt = self.cellWidget(row, rows.pt_type).currentText()
|
|
||||||
iq = self.cellWidget(row, rows.iq_type).currentText()
|
|
||||||
ret = self.cellWidget(row, rows.ret_type).currentText()
|
|
||||||
shortname = self.cellWidget(row, rows.short_name).text()
|
|
||||||
origin_type = self.item(row, rows.type).text()
|
|
||||||
|
|
||||||
result.append({
|
|
||||||
'show_var': True,
|
|
||||||
'enable': cb.isChecked(),
|
|
||||||
'name': name,
|
|
||||||
'pt_type': f'pt_{pt}',
|
|
||||||
'iq_type': f't_{iq}',
|
|
||||||
'return_type': f't_{ret}',
|
|
||||||
'shortname': shortname,
|
|
||||||
'type': origin_type,
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
|
|
||||||
def on_section_resized(self, logicalIndex, oldSize, newSize):
|
|
||||||
if self._resizing:
|
|
||||||
return # предотвращаем рекурсию
|
|
||||||
|
|
||||||
min_width = 50
|
|
||||||
delta = newSize - oldSize
|
|
||||||
right_index = logicalIndex + 1
|
|
||||||
|
|
||||||
if right_index >= self.columnCount():
|
|
||||||
# Если правая колока - нет соседа, ограничиваем минимальную ширину
|
|
||||||
if newSize < min_width:
|
|
||||||
self._resizing = True
|
|
||||||
self.setColumnWidth(logicalIndex, min_width)
|
|
||||||
self._resizing = False
|
|
||||||
return
|
|
||||||
|
|
||||||
self._resizing = True
|
|
||||||
try:
|
|
||||||
right_width = self.columnWidth(right_index)
|
|
||||||
new_right_width = right_width - delta
|
|
||||||
|
|
||||||
# Если соседняя колонка станет уже минимальной - подкорректируем левую
|
|
||||||
if new_right_width < min_width:
|
|
||||||
new_right_width = min_width
|
|
||||||
newSize = oldSize + (right_width - min_width)
|
|
||||||
self.setColumnWidth(logicalIndex, newSize)
|
|
||||||
|
|
||||||
self.setColumnWidth(right_index, new_right_width)
|
|
||||||
finally:
|
|
||||||
self._resizing = False
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def highlight_row(self, row: int, color: QColor = None, tooltip: str = ""):
|
|
||||||
"""
|
|
||||||
Подсвечивает строку таблицы цветом `color`, не меняя шрифт.
|
|
||||||
Работает с QLineEdit, QComboBox, QCheckBox (включая обёртки).
|
|
||||||
Если `color=None`, сбрасывает подсветку.
|
|
||||||
"""
|
|
||||||
css_reset = "background-color: none; font: inherit;"
|
|
||||||
css_color = f"background-color: {color.name()};" if color else css_reset
|
|
||||||
|
|
||||||
for col in range(self.columnCount()):
|
|
||||||
item = self.item(row, col)
|
|
||||||
widget = self.cellWidget(row, col)
|
|
||||||
|
|
||||||
# Подсветка обычной item-ячейки (например, тип переменной)
|
|
||||||
if item is not None:
|
|
||||||
if color:
|
|
||||||
item.setBackground(QBrush(color))
|
|
||||||
item.setToolTip(tooltip)
|
|
||||||
else:
|
|
||||||
item.setBackground(QBrush(Qt.NoBrush))
|
|
||||||
item.setToolTip("")
|
|
||||||
|
|
||||||
# Подсветка виджетов — здесь главная доработка
|
|
||||||
elif widget is not None:
|
|
||||||
# Надёжная подсветка: через styleSheet
|
|
||||||
widget.setStyleSheet(css_color)
|
|
||||||
widget.setToolTip(tooltip if color else "")
|
|
||||||
500
Src/allvars_xml_parser.py
Normal file
500
Src/allvars_xml_parser.py
Normal file
@@ -0,0 +1,500 @@
|
|||||||
|
"""
|
||||||
|
VariablesXML + get_all_vars_data
|
||||||
|
---------------------------------
|
||||||
|
Поддержка вложенных структур, указателей на структуры ("->"),
|
||||||
|
и многомерных массивов (индексация [i][j]...).
|
||||||
|
|
||||||
|
Требования пользователя:
|
||||||
|
- size (без индекса) = общий размер массива в байтах (НЕ измерение!).
|
||||||
|
- size1..sizeN = размеры измерений массива.
|
||||||
|
- В результирующем плоском списке (flattened) должны присутствовать ВСЕ промежуточные
|
||||||
|
пути: var, var[0], var[0][0], var[0][0].field, var[0][0].field->subfield, ...
|
||||||
|
- Аналогично для членов структур.
|
||||||
|
|
||||||
|
Пример желаемого формата:
|
||||||
|
project
|
||||||
|
project.adc
|
||||||
|
project.adc[0]
|
||||||
|
project.adc[0][0]
|
||||||
|
project.adc[0][0].bus
|
||||||
|
project.adc[0][0].bus->status
|
||||||
|
|
||||||
|
Данный модуль реализует:
|
||||||
|
- Разбор XML (parse) с извлечением размеров размерностей в поле `dims`.
|
||||||
|
- Генерацию плоского списка словарей `flattened()`.
|
||||||
|
- Построение иерархии словарей `get_all_vars_data()`.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import List, Dict, Optional, Tuple, Any
|
||||||
|
|
||||||
|
import var_setup # ожидается split_path(...)
|
||||||
|
from generate_debug_vars import choose_type_map, type_map # используется для выбора карт типов
|
||||||
|
|
||||||
|
# --------------------------- константы ----------------------------
|
||||||
|
|
||||||
|
DATE_FIELD_SET = {"year", "month", "day", "hour", "minute"}
|
||||||
|
|
||||||
|
# --------------------------- dataclasses --------------------------
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class MemberNode:
|
||||||
|
name: str
|
||||||
|
offset: int = 0
|
||||||
|
type_str: str = ""
|
||||||
|
size: Optional[int] = None # общий размер (байты), если известен
|
||||||
|
children: List["MemberNode"] = field(default_factory=list)
|
||||||
|
# --- доп.поля ---
|
||||||
|
kind: Optional[str] = None # 'array', 'union', ...
|
||||||
|
dims: Optional[List[int]] = None
|
||||||
|
|
||||||
|
def is_date_struct(self) -> bool:
|
||||||
|
if not self.children:
|
||||||
|
return False
|
||||||
|
child_names = {c.name for c in self.children}
|
||||||
|
return DATE_FIELD_SET.issubset(child_names)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VariableNode:
|
||||||
|
name: str
|
||||||
|
address: int
|
||||||
|
type_str: str
|
||||||
|
size: Optional[int]
|
||||||
|
members: List[MemberNode] = field(default_factory=list)
|
||||||
|
# --- доп.поля ---
|
||||||
|
kind: Optional[str] = None # 'array'
|
||||||
|
dims: Optional[List[int]] = None # полный список размеров [size1, size2, ...]
|
||||||
|
|
||||||
|
def base_address_hex(self) -> str:
|
||||||
|
return f"0x{self.address:06X}"
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------- класс парсера -----------------------
|
||||||
|
|
||||||
|
class VariablesXML:
|
||||||
|
"""
|
||||||
|
Читает XML и предоставляет методы:
|
||||||
|
- flattened(): плоский список всех путей.
|
||||||
|
- date_struct_candidates(): как раньше.
|
||||||
|
|
||||||
|
Правила формирования путей:
|
||||||
|
* Структурные поля: '.'
|
||||||
|
* Поля через указатель на структуру: '->'
|
||||||
|
* Массивы: [index] (каждое измерение).
|
||||||
|
"""
|
||||||
|
|
||||||
|
# предполагаемые размеры примитивов (MCU: int=2)
|
||||||
|
_PRIM_SIZE = {
|
||||||
|
'char': 1, 'signed char': 1, 'unsigned char': 1,
|
||||||
|
'uint8_t': 1, 'int8_t': 1,
|
||||||
|
'short': 2, 'short int': 2, 'signed short': 2, 'unsigned short': 2,
|
||||||
|
'uint16_t': 2, 'int16_t': 2,
|
||||||
|
'int': 2, 'signed int': 2, 'unsigned int': 2,
|
||||||
|
'long': 4, 'unsigned long': 4, 'int32_t': 4, 'uint32_t': 4,
|
||||||
|
'float': 4,
|
||||||
|
'long long': 8, 'unsigned long long': 8, 'int64_t': 8, 'uint64_t': 8, 'double': 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, path: str):
|
||||||
|
self.path = path
|
||||||
|
self.timestamp: str = ""
|
||||||
|
self.variables: List[VariableNode] = []
|
||||||
|
choose_type_map(0) # инициализация карт типов (если требуется)
|
||||||
|
self._parse()
|
||||||
|
|
||||||
|
# ------------------ утилиты ------------------
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_int_guess(txt: Optional[str]) -> Optional[int]:
|
||||||
|
if not txt:
|
||||||
|
return None
|
||||||
|
txt = txt.strip()
|
||||||
|
if txt.startswith(('0x', '0X')):
|
||||||
|
return int(txt, 16)
|
||||||
|
# если в строке есть A-F, попробуем hex
|
||||||
|
if any(c in 'abcdefABCDEF' for c in txt):
|
||||||
|
try:
|
||||||
|
return int(txt, 16)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
return int(txt, 10)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_pointer_to_struct(t: str) -> bool:
|
||||||
|
if not t:
|
||||||
|
return False
|
||||||
|
low = t.replace('\t', ' ').replace('\n', ' ')
|
||||||
|
return 'struct ' in low and '*' in low
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_struct_or_union(t: str) -> bool:
|
||||||
|
if not t:
|
||||||
|
return False
|
||||||
|
low = t.strip()
|
||||||
|
return low.startswith('struct ') or low.startswith('union ')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _is_union(t: str) -> bool:
|
||||||
|
if not t:
|
||||||
|
return False
|
||||||
|
low = t.strip()
|
||||||
|
return low.startswith('union ')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _strip_array_suffix(t: str) -> str:
|
||||||
|
t = t.strip()
|
||||||
|
while t.endswith('[]'):
|
||||||
|
t = t[:-2].strip()
|
||||||
|
return t
|
||||||
|
|
||||||
|
def _guess_primitive_size(self, type_str: str) -> Optional[int]:
|
||||||
|
if not type_str:
|
||||||
|
return None
|
||||||
|
base = type_str
|
||||||
|
for tok in ('volatile', 'const'):
|
||||||
|
base = base.replace(tok, '')
|
||||||
|
base = base.replace('*', ' ')
|
||||||
|
base = base.replace('[', ' ').replace(']', ' ')
|
||||||
|
base = ' '.join(base.split()).strip()
|
||||||
|
return self._PRIM_SIZE.get(base)
|
||||||
|
|
||||||
|
# ------------------ XML read ------------------
|
||||||
|
|
||||||
|
def _parse(self) -> None:
|
||||||
|
try:
|
||||||
|
tree = ET.parse(self.path)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
ts = root.find('timestamp')
|
||||||
|
self.timestamp = ts.text.strip() if ts is not None and ts.text else ''
|
||||||
|
|
||||||
|
def parse_member(elem: ET.Element, base_offset=0) -> MemberNode:
|
||||||
|
name = elem.get('name', '')
|
||||||
|
offset = int(elem.get('offset', '0'), 16) if elem.get('offset') else 0
|
||||||
|
t = elem.get('type', '') or ''
|
||||||
|
size_attr = elem.get('size')
|
||||||
|
size = int(size_attr, 16) if size_attr else None
|
||||||
|
kind = elem.get('kind')
|
||||||
|
|
||||||
|
abs_offset = base_offset + offset
|
||||||
|
|
||||||
|
|
||||||
|
# Собираем размеры, если есть
|
||||||
|
dims: List[int] = []
|
||||||
|
i = 1
|
||||||
|
while True:
|
||||||
|
size_key = f"size{i}"
|
||||||
|
size_val = elem.get(size_key)
|
||||||
|
if size_val is None:
|
||||||
|
break
|
||||||
|
parsed = self._parse_int_guess(size_val) # предполагается твоя функция парсинга int
|
||||||
|
if parsed is not None:
|
||||||
|
dims.append(parsed)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
node = MemberNode(
|
||||||
|
name=name,
|
||||||
|
offset=abs_offset,
|
||||||
|
type_str=t,
|
||||||
|
size=size,
|
||||||
|
kind=kind,
|
||||||
|
dims=dims if dims else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Для детей
|
||||||
|
for ch in elem.findall('member'):
|
||||||
|
if kind == 'union':
|
||||||
|
# Для union детей НЕ добавляем их offset, просто передаём abs_offset
|
||||||
|
child = parse_member(ch, base_offset=abs_offset)
|
||||||
|
child.offset = abs_offset # выравниваем offset, игнорируем offset детей
|
||||||
|
else:
|
||||||
|
# Для struct/array суммируем offset нормально
|
||||||
|
child = parse_member(ch, base_offset=abs_offset)
|
||||||
|
node.children.append(child)
|
||||||
|
|
||||||
|
# Аналогично для pointee
|
||||||
|
pointee_elem = elem.find('pointee')
|
||||||
|
if pointee_elem is not None:
|
||||||
|
for ch in pointee_elem.findall('member'):
|
||||||
|
if kind == 'union':
|
||||||
|
child = parse_member(ch, base_offset=abs_offset)
|
||||||
|
child.offset = abs_offset
|
||||||
|
else:
|
||||||
|
child = parse_member(ch, base_offset=abs_offset)
|
||||||
|
node.children.append(child)
|
||||||
|
size_p = pointee_elem.get('size')
|
||||||
|
if size_p:
|
||||||
|
node.size = int(size_p, 16)
|
||||||
|
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for var in root.findall('variable'):
|
||||||
|
addr = int(var.get('address', '0'), 16)
|
||||||
|
name = var.get('name', '')
|
||||||
|
t = var.get('type', '') or ''
|
||||||
|
size_attr = var.get('size') # общий размер байт
|
||||||
|
size = int(size_attr, 16) if size_attr else None
|
||||||
|
kind = var.get('kind')
|
||||||
|
|
||||||
|
dims: List[int] = []
|
||||||
|
i = 1
|
||||||
|
while True:
|
||||||
|
key = f'size{i}'
|
||||||
|
val = var.get(key)
|
||||||
|
if val is None:
|
||||||
|
break
|
||||||
|
parsed = self._parse_int_guess(val)
|
||||||
|
if parsed is not None:
|
||||||
|
dims.append(parsed)
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
members = [parse_member(m) for m in var.findall('member')]
|
||||||
|
|
||||||
|
v = VariableNode(
|
||||||
|
name=name,
|
||||||
|
address=addr,
|
||||||
|
type_str=t,
|
||||||
|
size=size,
|
||||||
|
members=members,
|
||||||
|
kind=kind,
|
||||||
|
dims=dims if dims else None,
|
||||||
|
)
|
||||||
|
self.variables.append(v)
|
||||||
|
except FileNotFoundError:
|
||||||
|
self.variables = []
|
||||||
|
except ET.ParseError:
|
||||||
|
self.variables = []
|
||||||
|
|
||||||
|
# ------------------ helpers для flattened ---------------------
|
||||||
|
|
||||||
|
def _elem_size_bytes(self, total_size: Optional[int], dims: List[int], base_type: str, members: List[MemberNode]) -> int:
|
||||||
|
"""Оценка размера одного *листового* элемента (последнего измерения).
|
||||||
|
Если total_size и dims все известны — берём size / prod(dims).
|
||||||
|
Иначе — пробуем примитивный размер; иначе 1.
|
||||||
|
(Не учитываем выравнивание структур; при необходимости можно расширить.)
|
||||||
|
"""
|
||||||
|
if total_size is not None and dims:
|
||||||
|
prod = 1
|
||||||
|
for d in dims:
|
||||||
|
if d is None or d == 0:
|
||||||
|
prod = None
|
||||||
|
break
|
||||||
|
prod *= d
|
||||||
|
if prod and prod > 0:
|
||||||
|
return max(1, total_size // prod)
|
||||||
|
prim = self._guess_primitive_size(base_type)
|
||||||
|
if prim:
|
||||||
|
return prim
|
||||||
|
# Если структура и у неё есть size по детям? Пока fallback=1.
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# ------------------ flattened ------------------
|
||||||
|
|
||||||
|
def flattened(self, max_array_elems: Optional[int] = None) -> List[Dict[str, Any]]:
|
||||||
|
"""Возвращает плоский список всех путей (каждый путь = dict).
|
||||||
|
Включает промежуточные узлы массивов (var[0], var[0][0], ...).
|
||||||
|
"""
|
||||||
|
out: List[Dict[str, Any]] = []
|
||||||
|
|
||||||
|
def mk(name: str, addr: Optional[int], type_str: str, size: Optional[int], kind: Optional[str], dims_for_node: Optional[List[int]]):
|
||||||
|
if 'Bender' in name:
|
||||||
|
a=1
|
||||||
|
out.append({
|
||||||
|
'name': name,
|
||||||
|
'address': addr,
|
||||||
|
'type': type_str,
|
||||||
|
'size': size,
|
||||||
|
'kind': kind,
|
||||||
|
'dims': dims_for_node[:] if dims_for_node else None,
|
||||||
|
})
|
||||||
|
|
||||||
|
def expand_members(prefix: str, base_addr: int, members: List[MemberNode], parent_is_ptr_struct: bool, parent_is_union: bool) -> None:
|
||||||
|
# Выбираем разделитель пути: '.' если обычный член, '->' если указатель на структуру
|
||||||
|
join = '->' if parent_is_ptr_struct else '.'
|
||||||
|
|
||||||
|
for m in members:
|
||||||
|
path_m = f"{prefix}{join}{m.name}" if prefix else m.name
|
||||||
|
is_union = m.kind == 'union' or parent_is_union
|
||||||
|
if is_union:
|
||||||
|
# Все поля union начинаются с одного адреса
|
||||||
|
addr_m = base_addr
|
||||||
|
else:
|
||||||
|
addr_m = base_addr + m.offset
|
||||||
|
|
||||||
|
dims = m.dims or []
|
||||||
|
|
||||||
|
mk(path_m, addr_m, m.type_str, m.size, m.kind, dims)
|
||||||
|
|
||||||
|
if m.kind == 'array' and dims:
|
||||||
|
base_t = self._strip_array_suffix(m.type_str)
|
||||||
|
elem_sz = m.size
|
||||||
|
|
||||||
|
# Для массива внутри структуры: первый уровень — '.' для доступа,
|
||||||
|
# внутри массива раскрываем по обычной логике с parent_is_ptr_struct=False
|
||||||
|
expand_dims(path_m, addr_m, dims, base_t, m.children, elem_sz, parent_is_ptr_struct=False)
|
||||||
|
else:
|
||||||
|
if m.children:
|
||||||
|
# Проверяем, является ли поле указателем на структуру
|
||||||
|
is_ptr = self._is_pointer_to_struct(m.type_str)
|
||||||
|
# Рекурсивно раскрываем дочерние поля, выбирая правильный разделитель
|
||||||
|
expand_members(path_m, addr_m, m.children, is_ptr, is_union)
|
||||||
|
|
||||||
|
|
||||||
|
def expand_dims(name: str, base_addr: int, dims: List[int], base_type: str, children: List[MemberNode], elem_size: int, parent_is_ptr_struct: bool) -> None:
|
||||||
|
prods: List[int] = []
|
||||||
|
acc = 1
|
||||||
|
for d in reversed(dims[1:]):
|
||||||
|
acc *= (d if d else 1)
|
||||||
|
prods.append(acc)
|
||||||
|
prods.reverse()
|
||||||
|
|
||||||
|
def rec(k: int, cur_name: str, cur_addr: int) -> None:
|
||||||
|
if k == len(dims):
|
||||||
|
# Листовой элемент массива
|
||||||
|
mk(cur_name, cur_addr, base_type, elem_size, None, None)
|
||||||
|
# Если элемент — структура или указатель на структуру, раскрываем вложения
|
||||||
|
if children and self._is_struct_or_union(base_type):
|
||||||
|
expand_members(cur_name, cur_addr, children, parent_is_ptr_struct=False, parent_is_union=self._is_union(base_type))
|
||||||
|
elif self._is_pointer_to_struct(base_type):
|
||||||
|
expand_members(cur_name, cur_addr, children, parent_is_ptr_struct=True, parent_is_union=self._is_union(base_type))
|
||||||
|
return
|
||||||
|
|
||||||
|
dim_sz = dims[k] or 0
|
||||||
|
if max_array_elems is not None:
|
||||||
|
dim_sz = min(dim_sz, max_array_elems)
|
||||||
|
|
||||||
|
stride = elem_size * prods[k] if k < len(prods) else elem_size
|
||||||
|
if len(dims) > 2:
|
||||||
|
a=1
|
||||||
|
for i in range(dim_sz):
|
||||||
|
child_name = f"{cur_name}[{i}]"
|
||||||
|
child_addr = (cur_addr + i * stride) if cur_addr is not None else None
|
||||||
|
remaining = dims[k+1:]
|
||||||
|
mk(child_name, child_addr, base_type + '[]' * len(remaining), stride if remaining else elem_size, 'array' if remaining else None, remaining)
|
||||||
|
rec(k + 1, child_name, child_addr)
|
||||||
|
|
||||||
|
rec(0, name, base_addr)
|
||||||
|
|
||||||
|
|
||||||
|
# --- цикл по топ‑левел переменным ---
|
||||||
|
for v in self.variables:
|
||||||
|
dims = v.dims or []
|
||||||
|
mk(v.name, v.address, v.type_str, v.size, v.kind, dims)
|
||||||
|
if (v.kind == 'array' or v.type_str.endswith('[]')) and dims:
|
||||||
|
base_t = self._strip_array_suffix(v.type_str)
|
||||||
|
elem_sz = v.size
|
||||||
|
expand_dims(v.name, v.address, dims, base_t, v.members, elem_sz, parent_is_ptr_struct=False)
|
||||||
|
else:
|
||||||
|
if v.members:
|
||||||
|
is_ptr = self._is_pointer_to_struct(v.type_str)
|
||||||
|
is_union = self._is_union(v.type_str)
|
||||||
|
expand_members(v.name, v.address, v.members, is_ptr, is_union)
|
||||||
|
|
||||||
|
return out
|
||||||
|
|
||||||
|
# -------------------- date candidates (как раньше) -------------
|
||||||
|
|
||||||
|
def date_struct_candidates(self) -> List[Tuple[str, int]]:
|
||||||
|
cands = []
|
||||||
|
for v in self.variables:
|
||||||
|
# top level (if all date fields are present)
|
||||||
|
direct_names = {mm.name for mm in v.members}
|
||||||
|
if DATE_FIELD_SET.issubset(direct_names):
|
||||||
|
cands.append((v.name, v.address))
|
||||||
|
# check first-level members
|
||||||
|
for m in v.members:
|
||||||
|
if m.is_date_struct():
|
||||||
|
cands.append((f"{v.name}.{m.name}", v.address + m.offset))
|
||||||
|
return cands
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# Построение иерархического дерева из flattened()
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def get_all_vars_data(self) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Строит иерархию словарей из плоского списка переменных.
|
||||||
|
|
||||||
|
Каждый узел = {
|
||||||
|
'name': <полный путь>,
|
||||||
|
'address': <адрес или None>,
|
||||||
|
'type': <тип>,
|
||||||
|
'size': <байты>,
|
||||||
|
'kind': <'array' | ...>,
|
||||||
|
'dims': [size1, size2, ...] или None,
|
||||||
|
'children': [...список дочерних узлов]
|
||||||
|
}
|
||||||
|
|
||||||
|
Возвращает список корневых узлов (top-level переменных).
|
||||||
|
"""
|
||||||
|
flat_data = self.flattened(max_array_elems=None)
|
||||||
|
|
||||||
|
# Быстрое отображение имя -> узел (словарь с детьми)
|
||||||
|
all_nodes: Dict[str, Dict[str, Any]] = {}
|
||||||
|
for item in flat_data:
|
||||||
|
node = dict(item)
|
||||||
|
node['children'] = []
|
||||||
|
all_nodes[item['name']] = node
|
||||||
|
|
||||||
|
def _parent_struct_split(path: str) -> Optional[str]:
|
||||||
|
# Ищем последний '.' или '->' для определения родителя
|
||||||
|
dot_idx = path.rfind('.')
|
||||||
|
arrow_idx = path.rfind('->')
|
||||||
|
cut_idx = max(dot_idx, arrow_idx)
|
||||||
|
if cut_idx == -1:
|
||||||
|
return None
|
||||||
|
# '->' занимает 2 символа, нужно взять срез до начала '->'
|
||||||
|
if arrow_idx > dot_idx:
|
||||||
|
return path[:arrow_idx]
|
||||||
|
else:
|
||||||
|
return path[:dot_idx]
|
||||||
|
|
||||||
|
def find_parent(path: str) -> Optional[str]:
|
||||||
|
"""
|
||||||
|
Возвращает полный путь родителя, учитывая '.', '->' и индексы [] в конце.
|
||||||
|
|
||||||
|
Если путь заканчивается индексом [k], удаляет последний индекс и проверяет наличие родителя.
|
||||||
|
Иначе пытается найти последний сепаратор '.' или '->'.
|
||||||
|
"""
|
||||||
|
# Если есть trailing индекс в конце, убираем его
|
||||||
|
m = re.search(r'\[[0-9]+\]$', path)
|
||||||
|
if m:
|
||||||
|
base = path[:m.start()] # убираем последний [k]
|
||||||
|
# Если базовый путь есть в узлах, считаем его родителем
|
||||||
|
if base in all_nodes:
|
||||||
|
return base
|
||||||
|
# Иначе пытаемся найти родителя от базового пути
|
||||||
|
return _parent_struct_split(base)
|
||||||
|
else:
|
||||||
|
# Если нет индекса, просто ищем последний разделитель
|
||||||
|
return _parent_struct_split(path)
|
||||||
|
|
||||||
|
# Строим иерархию: parent -> children
|
||||||
|
roots: List[Dict[str, Any]] = []
|
||||||
|
for full_name, node in all_nodes.items():
|
||||||
|
parent_name = find_parent(full_name)
|
||||||
|
if parent_name and parent_name in all_nodes:
|
||||||
|
all_nodes[parent_name]['children'].append(node)
|
||||||
|
else:
|
||||||
|
roots.append(node)
|
||||||
|
|
||||||
|
# Рекурсивно сортируем детей по имени для порядка
|
||||||
|
def sort_nodes(nodes: List[Dict[str, Any]]):
|
||||||
|
nodes.sort(key=lambda n: n['name'])
|
||||||
|
for n in nodes:
|
||||||
|
if n['children']:
|
||||||
|
sort_nodes(n['children'])
|
||||||
|
|
||||||
|
sort_nodes(roots)
|
||||||
|
return roots
|
||||||
@@ -2,22 +2,22 @@ import subprocess
|
|||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from PIL import Image # нужна библиотека Pillow для конвертации PNG в ICO
|
|
||||||
import PySide2
|
import PySide2
|
||||||
from PyInstaller.utils.hooks import collect_data_files
|
from PyInstaller.utils.hooks import collect_data_files
|
||||||
# install:
|
# install: pip install PySide2 lxml nuitka pyinstaller
|
||||||
# - PyInstaller
|
# - PyInstaller
|
||||||
# - nuitka
|
# - nuitka
|
||||||
# - Pillow
|
|
||||||
# - PySide2
|
# - PySide2
|
||||||
# - clang
|
# - clang
|
||||||
|
|
||||||
# === Конфигурация ===
|
# === Конфигурация ===
|
||||||
USE_NUITKA = True # True — сборка через Nuitka, False — через PyInstaller
|
USE_NUITKA = True # True — сборка через Nuitka, False — через PyInstaller
|
||||||
|
MAIN_SCRIPT_NAME = "tms_debugvar_term"
|
||||||
|
OUTPUT_NAME = "DebugVarTerminal"
|
||||||
|
|
||||||
|
|
||||||
SRC_PATH = Path("./Src/")
|
SRC_PATH = Path("./Src/")
|
||||||
SCRIPT_PATH = SRC_PATH / "DebugVarEdit_GUI.py"
|
SCRIPT_PATH = SRC_PATH / (MAIN_SCRIPT_NAME + ".py")
|
||||||
OUTPUT_NAME = "DebugVarEdit"
|
|
||||||
|
|
||||||
DIST_PATH = Path("./").resolve()
|
DIST_PATH = Path("./").resolve()
|
||||||
WORK_PATH = Path("./build_temp").resolve()
|
WORK_PATH = Path("./build_temp").resolve()
|
||||||
@@ -25,6 +25,13 @@ SPEC_PATH = WORK_PATH
|
|||||||
ICON_PATH = SRC_PATH / "icon.png"
|
ICON_PATH = SRC_PATH / "icon.png"
|
||||||
ICON_ICO_PATH = SRC_PATH / "icon.ico"
|
ICON_ICO_PATH = SRC_PATH / "icon.ico"
|
||||||
|
|
||||||
|
TEMP_FOLDERS = [
|
||||||
|
"build_temp",
|
||||||
|
"__pycache__",
|
||||||
|
MAIN_SCRIPT_NAME + ".build",
|
||||||
|
MAIN_SCRIPT_NAME + ".onefile-build",
|
||||||
|
MAIN_SCRIPT_NAME + ".dist"
|
||||||
|
]
|
||||||
# === Пути к DLL и прочим зависимостям ===
|
# === Пути к DLL и прочим зависимостям ===
|
||||||
LIBS = {
|
LIBS = {
|
||||||
"libclang.dll": SRC_PATH / "libclang.dll"
|
"libclang.dll": SRC_PATH / "libclang.dll"
|
||||||
@@ -48,7 +55,7 @@ for name, path in LIBS.items():
|
|||||||
print(f"WARNING: {path.name} не найден — он не будет включён в сборку")
|
print(f"WARNING: {path.name} не найден — он не будет включён в сборку")
|
||||||
|
|
||||||
def clean_temp():
|
def clean_temp():
|
||||||
for folder in ["build_temp", "__pycache__", "DebugVarEdit_GUI.build", "DebugVarEdit_GUI.dist", "DebugVarEdit_GUI.onefile-build"]:
|
for folder in TEMP_FOLDERS:
|
||||||
path = Path(folder)
|
path = Path(folder)
|
||||||
if path.exists():
|
if path.exists():
|
||||||
shutil.rmtree(path, ignore_errors=True)
|
shutil.rmtree(path, ignore_errors=True)
|
||||||
224
Src/csv_logger.py
Normal file
224
Src/csv_logger.py
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
import csv
|
||||||
|
import numbers
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
from PySide2 import QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class CsvLogger:
|
||||||
|
"""
|
||||||
|
Логгер, совместимый по формату с C-реализацией CSV_AddTitlesLine / CSV_AddLogLine.
|
||||||
|
|
||||||
|
Публичный API сохранён:
|
||||||
|
set_titles(varnames)
|
||||||
|
set_value(timestamp, varname, varvalue)
|
||||||
|
select_file(parent=None) -> bool
|
||||||
|
write_to_csv()
|
||||||
|
|
||||||
|
Использование:
|
||||||
|
1) set_titles([...])
|
||||||
|
2) многократно set_value(ts, name, value)
|
||||||
|
3) select_file() (по желанию)
|
||||||
|
4) write_to_csv()
|
||||||
|
"""
|
||||||
|
def __init__(self, filename="log.csv", delimiter=';'):
|
||||||
|
self._filename = filename
|
||||||
|
self._delimiter = delimiter
|
||||||
|
|
||||||
|
# Пользовательские заголовки
|
||||||
|
self.variable_names_ordered = []
|
||||||
|
# Полные заголовки CSV (Ticks(X), Ticks(Y), Time(Y), ...)
|
||||||
|
self.headers = ['t'] # до вызова set_titles placeholder
|
||||||
|
|
||||||
|
# Данные: {timestamp_key: {varname: value, ...}}
|
||||||
|
# timestamp_key = то, что передано в set_value (float/int/etc)
|
||||||
|
self.data_rows = {}
|
||||||
|
|
||||||
|
# Внутренние структуры для генерации CSV-формата С
|
||||||
|
self._row_wall_dt = {} # {timestamp_key: datetime при первой записи}
|
||||||
|
self._base_ts = None # timestamp_key первой строки (число)
|
||||||
|
self._base_ts_val = 0.0 # float значение первой строки (для delta)
|
||||||
|
self._tick_x_start = 0 # начальный тик (можно менять вручную при необходимости)
|
||||||
|
|
||||||
|
# ---- Свойства ----
|
||||||
|
@property
|
||||||
|
def filename(self):
|
||||||
|
return self._filename
|
||||||
|
|
||||||
|
# ---- Публичные методы ----
|
||||||
|
def set_titles(self, varnames):
|
||||||
|
"""
|
||||||
|
Устанавливает имена переменных.
|
||||||
|
Формирует полные заголовки CSV в формате С-лога.
|
||||||
|
"""
|
||||||
|
if not isinstance(varnames, list):
|
||||||
|
raise TypeError("Varnames must be a list of strings.")
|
||||||
|
if not all(isinstance(name, str) for name in varnames):
|
||||||
|
raise ValueError("All variable names must be strings.")
|
||||||
|
|
||||||
|
self.variable_names_ordered = varnames
|
||||||
|
self.headers = ["Ticks(X)", "Ticks(Y)", "Time(Y)"] + self.variable_names_ordered
|
||||||
|
|
||||||
|
# Сброс данных (структура изменилась)
|
||||||
|
self.data_rows.clear()
|
||||||
|
self._row_wall_dt.clear()
|
||||||
|
self._base_ts = None
|
||||||
|
self._base_ts_val = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def set_value(self, timestamp, varname, varvalue):
|
||||||
|
"""
|
||||||
|
Установить ОДНО значение в ОДНУ колонку для заданного timestamp’а.
|
||||||
|
timestamp — float секунд с эпохи (time.time()).
|
||||||
|
"""
|
||||||
|
if varname not in self.variable_names_ordered:
|
||||||
|
return # игнор, как у тебя было
|
||||||
|
|
||||||
|
# Новая строка?
|
||||||
|
if timestamp not in self.data_rows:
|
||||||
|
# Инициализируем поля переменных значением None
|
||||||
|
self.data_rows[timestamp] = {vn: None for vn in self.variable_names_ordered}
|
||||||
|
|
||||||
|
# Дата/время строки из ПЕРЕДАННОГО timestamp (а не datetime.now()!)
|
||||||
|
try:
|
||||||
|
ts_float = float(timestamp)
|
||||||
|
except Exception:
|
||||||
|
# если какая-то дичь прилетела, пусть будет 0 (эпоха) чтобы не упасть
|
||||||
|
ts_float = 0.0
|
||||||
|
self._row_wall_dt[timestamp] = datetime.fromtimestamp(ts_float)
|
||||||
|
|
||||||
|
# База для расчёта Ticks(Y) — первая строка
|
||||||
|
if self._base_ts is None:
|
||||||
|
self._base_ts = timestamp
|
||||||
|
self._base_ts_val = ts_float
|
||||||
|
|
||||||
|
# Записываем значение
|
||||||
|
self.data_rows[timestamp][varname] = varvalue
|
||||||
|
|
||||||
|
def select_file(self, parent=None) -> bool:
|
||||||
|
"""
|
||||||
|
Диалог выбора файла.
|
||||||
|
"""
|
||||||
|
options = QtWidgets.QFileDialog.Options()
|
||||||
|
filename, _ = QtWidgets.QFileDialog.getSaveFileName(
|
||||||
|
parent,
|
||||||
|
"Сохранить данные CSV",
|
||||||
|
self._filename,
|
||||||
|
"CSV Files (*.csv);;All Files (*)",
|
||||||
|
options=options
|
||||||
|
)
|
||||||
|
if filename:
|
||||||
|
if not filename.lower().endswith('.csv'):
|
||||||
|
filename += '.csv'
|
||||||
|
self._filename = filename
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def write_to_csv(self):
|
||||||
|
"""
|
||||||
|
Формирует CSV в формате C:
|
||||||
|
Ticks(X);Ticks(Y);Time(Y);Var1;Var2;...
|
||||||
|
0;0,000000;22/07/2025 13:45:12:0123;...;...
|
||||||
|
|
||||||
|
Правила значений:
|
||||||
|
- Тик X: автоинкремент от 0 (или self._tick_x_start) по порядку сортировки timestamp.
|
||||||
|
- Ticks(Y): дельта (секунды,микросекунды) между текущим timestamp и первым timestamp.
|
||||||
|
- Time(Y): wallclock строки (datetime.now() при первом появлении timestamp).
|
||||||
|
- Значение < 0 -> пустая ячейка (как if(raw_data[i] >= 0) else ;)
|
||||||
|
- None -> пустая ячейка.
|
||||||
|
"""
|
||||||
|
if len(self.headers) <= 3: # только служебные поля без переменных
|
||||||
|
print("Ошибка: Заголовки не установлены или не содержат переменных. Вызовите set_titles() перед записью.")
|
||||||
|
return
|
||||||
|
if not self._filename:
|
||||||
|
print("Ошибка: Имя файла не определено. select_file() или задайте при инициализации.")
|
||||||
|
return
|
||||||
|
if not self.data_rows:
|
||||||
|
print("Предупреждение: Нет данных для записи.")
|
||||||
|
# всё равно создадим файл с одними заголовками
|
||||||
|
try:
|
||||||
|
with open(self._filename, 'w', newline='', encoding='utf-8') as csvfile:
|
||||||
|
# QUOTE_NONE + escapechar для чистого формата без кавычек (как в С-строке)
|
||||||
|
writer = csv.writer(
|
||||||
|
csvfile,
|
||||||
|
delimiter=self._delimiter,
|
||||||
|
quoting=csv.QUOTE_NONE,
|
||||||
|
escapechar='\\',
|
||||||
|
lineterminator='\r\n'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Пишем заголовки
|
||||||
|
writer.writerow(self.headers)
|
||||||
|
|
||||||
|
if self.data_rows:
|
||||||
|
sorted_ts = sorted(self.data_rows.keys(), key=self._ts_sort_key)
|
||||||
|
# убедимся, что база была зафиксирована
|
||||||
|
if self._base_ts is None:
|
||||||
|
self._base_ts = sorted_ts[0]
|
||||||
|
self._base_ts_val = self._coerce_ts_to_float(self._base_ts)
|
||||||
|
|
||||||
|
tick_x = self._tick_x_start
|
||||||
|
for ts in sorted_ts:
|
||||||
|
row_dict = self.data_rows[ts]
|
||||||
|
# delta по timestamp
|
||||||
|
cur_ts_val = self._coerce_ts_to_float(ts)
|
||||||
|
delta_us = int(round((cur_ts_val - self._base_ts_val) * 1_000_000))
|
||||||
|
if delta_us < 0:
|
||||||
|
delta_us = 0 # защита
|
||||||
|
|
||||||
|
seconds = delta_us // 1_000_000
|
||||||
|
micros = delta_us % 1_000_000
|
||||||
|
|
||||||
|
# wallclock строки
|
||||||
|
dt = self._row_wall_dt.get(ts, datetime.now())
|
||||||
|
# Формат DD/MM/YYYY HH:MM:SS:мммм (4 цифры ms, как в C: us/1000)
|
||||||
|
time_str = dt.strftime("%d/%m/%Y %H:%M:%S") + f":{dt.microsecond // 1000:04d}"
|
||||||
|
|
||||||
|
# Значения
|
||||||
|
row_vals = []
|
||||||
|
for vn in self.variable_names_ordered:
|
||||||
|
v = row_dict.get(vn)
|
||||||
|
if v is None:
|
||||||
|
row_vals.append("") # нет данных
|
||||||
|
else:
|
||||||
|
# если числовое и <0 -> пусто (как в C: если raw_data[i] >= 0 else ;)
|
||||||
|
if isinstance(v, numbers.Number) and v < 0:
|
||||||
|
row_vals.append("")
|
||||||
|
else:
|
||||||
|
row_vals.append(v)
|
||||||
|
|
||||||
|
csv_row = [tick_x, f"{seconds},{micros:06d}", time_str] + row_vals
|
||||||
|
writer.writerow(csv_row)
|
||||||
|
tick_x += 1
|
||||||
|
|
||||||
|
print(f"Данные успешно записаны в '{self._filename}'")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка при записи в файл '{self._filename}': {e}")
|
||||||
|
|
||||||
|
# ---- Вспомогательные ----
|
||||||
|
def _coerce_ts_to_float(self, ts):
|
||||||
|
"""
|
||||||
|
Пробуем привести переданный timestamp к float.
|
||||||
|
Разрешаем int/float/str, остальное -> индекс по порядку (0).
|
||||||
|
"""
|
||||||
|
if isinstance(ts, numbers.Number):
|
||||||
|
return float(ts)
|
||||||
|
try:
|
||||||
|
return float(ts)
|
||||||
|
except Exception:
|
||||||
|
# fallback: нечисловой ключ -> используем порядковый индекс
|
||||||
|
# (таких почти не должно быть, но на всякий)
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
def _ts_sort_key(self, ts):
|
||||||
|
"""
|
||||||
|
Ключ сортировки timestamp’ов — сначала попытка float, потом str.
|
||||||
|
"""
|
||||||
|
if isinstance(ts, numbers.Number):
|
||||||
|
return (0, float(ts))
|
||||||
|
try:
|
||||||
|
return (0, float(ts))
|
||||||
|
except Exception:
|
||||||
|
return (1, str(ts))
|
||||||
|
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
# build command
|
# build command
|
||||||
# pyinstaller --onefile --distpath . --workpath ./build --specpath ./build generateVars.py
|
# pyinstaller --onefile --distpath . --workpath ./build --specpath ./build generate_debug_vars.py
|
||||||
# start script
|
# start script
|
||||||
# generateVars.exe F:\Work\Projects\TMS\TMS_new_bus\ Src/DebugTools/vars.xml Src/DebugTools
|
# generate_debug_vars.exe F:\Work\Projects\TMS\TMS_new_bus\ Src/DebugTools/vars.xml Src/DebugTools
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import xml.etree.ElementTree as ET
|
import lxml.etree as ET
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import myXML
|
import myXML
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
|
shortnameSize = 10
|
||||||
|
|
||||||
# === Словарь соответствия типов XML → DebugVarType_t ===
|
# === Словарь соответствия типов XML → DebugVarType_t ===
|
||||||
type_map = dict([
|
type_map_tms = dict([
|
||||||
*[(k, 'pt_int8') for k in ('signed char', 'char')],
|
*[(k, 'pt_int8') for k in ('signed char', 'char')],
|
||||||
*[(k, 'pt_int16') for k in ('int', 'int16', 'short')],
|
*[(k, 'pt_int16') for k in ('int', 'int16', 'short')],
|
||||||
*[(k, 'pt_int32') for k in ('long', 'int32', '_iqx')],
|
*[(k, 'pt_int32') for k in ('long', 'int32', '_iqx')],
|
||||||
@@ -52,6 +53,150 @@ type_map = dict([
|
|||||||
('struct[]', 'pt_arr_struct'),
|
('struct[]', 'pt_arr_struct'),
|
||||||
('union[]', 'pt_arr_union'),
|
('union[]', 'pt_arr_union'),
|
||||||
])
|
])
|
||||||
|
# === Словарь соответствия типов XML → DebugVarType_t ===
|
||||||
|
type_map_stm32 = dict([
|
||||||
|
|
||||||
|
*[(k, 'pt_int8') for k in (
|
||||||
|
'int8_t', 'signed char', 'char'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 8-bit unsigned ---
|
||||||
|
*[(k, 'pt_uint8') for k in (
|
||||||
|
'uint8_t', 'unsigned char'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 16-bit signed ---
|
||||||
|
*[(k, 'pt_int16') for k in (
|
||||||
|
'int16_t', 'short', 'short int', 'signed short', 'signed short int'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 16-bit unsigned ---
|
||||||
|
*[(k, 'pt_uint16') for k in (
|
||||||
|
'uint16_t', 'unsigned short', 'unsigned short int'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 32-bit signed ---
|
||||||
|
*[(k, 'pt_int32') for k in (
|
||||||
|
'int32_t', 'int', 'signed', 'signed int'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 32-bit unsigned ---
|
||||||
|
*[(k, 'pt_uint32') for k in (
|
||||||
|
'uint32_t', 'unsigned', 'unsigned int'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 64-bit signed ---
|
||||||
|
*[(k, 'pt_int64') for k in (
|
||||||
|
'int64_t', 'long long', 'signed long long', 'signed long long int'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- 64-bit unsigned ---
|
||||||
|
*[(k, 'pt_uint64') for k in (
|
||||||
|
'uint64_t', 'unsigned long long', 'unsigned long long int'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- Float ---
|
||||||
|
*[(k, 'pt_float') for k in (
|
||||||
|
'float', 'float32_t'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# --- Struct and Union ---
|
||||||
|
('struct', 'pt_struct'),
|
||||||
|
('union', 'pt_union'),
|
||||||
|
('struct*', 'pt_ptr_struct'),
|
||||||
|
('union*', 'pt_ptr_union'),
|
||||||
|
('struct[]', 'pt_arr_struct'),
|
||||||
|
('union[]', 'pt_arr_union'),
|
||||||
|
|
||||||
|
# === POINTERS ===
|
||||||
|
|
||||||
|
# 8-bit
|
||||||
|
*[(k, 'pt_ptr_int8') for k in (
|
||||||
|
'int8_t*', 'signed char*', 'char*'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_ptr_uint8') for k in (
|
||||||
|
'uint8_t*', 'unsigned char*'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# 16-bit
|
||||||
|
*[(k, 'pt_ptr_int16') for k in (
|
||||||
|
'int16_t*', 'short*', 'short int*', 'signed short*', 'signed short int*'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_ptr_uint16') for k in (
|
||||||
|
'uint16_t*', 'unsigned short*', 'unsigned short int*'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# 32-bit
|
||||||
|
*[(k, 'pt_ptr_int32') for k in (
|
||||||
|
'int32_t*', 'int*', 'signed*', 'signed int*'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_ptr_uint32') for k in (
|
||||||
|
'uint32_t*', 'unsigned*', 'unsigned int*'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# 64-bit
|
||||||
|
*[(k, 'pt_ptr_int64') for k in (
|
||||||
|
'int64_t*', 'long long*', 'signed long long*', 'signed long long int*'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_ptr_uint64') for k in (
|
||||||
|
'uint64_t*', 'unsigned long long*', 'unsigned long long int*'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# float*
|
||||||
|
*[(k, 'pt_ptr_float') for k in (
|
||||||
|
'float*', 'float32_t*'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# === ARRAYS ===
|
||||||
|
|
||||||
|
# 8-bit
|
||||||
|
*[(k, 'pt_arr_int8') for k in (
|
||||||
|
'int8_t[]', 'signed char[]', 'char[]'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_arr_uint8') for k in (
|
||||||
|
'uint8_t[]', 'unsigned char[]'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# 16-bit
|
||||||
|
*[(k, 'pt_arr_int16') for k in (
|
||||||
|
'int16_t[]', 'short[]', 'short int[]', 'signed short[]', 'signed short int[]'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_arr_uint16') for k in (
|
||||||
|
'uint16_t[]', 'unsigned short[]', 'unsigned short int[]'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# 32-bit
|
||||||
|
*[(k, 'pt_arr_int32') for k in (
|
||||||
|
'int32_t[]', 'int[]', 'signed[]', 'signed int[]'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_arr_uint32') for k in (
|
||||||
|
'uint32_t[]', 'unsigned[]', 'unsigned int[]'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# 64-bit
|
||||||
|
*[(k, 'pt_arr_int64') for k in (
|
||||||
|
'int64_t[]', 'long long[]', 'signed long long[]', 'signed long long int[]'
|
||||||
|
)],
|
||||||
|
*[(k, 'pt_arr_uint64') for k in (
|
||||||
|
'uint64_t[]', 'unsigned long long[]', 'unsigned long long int[]'
|
||||||
|
)],
|
||||||
|
|
||||||
|
# float[]
|
||||||
|
*[(k, 'pt_arr_float') for k in (
|
||||||
|
'float[]', 'float32_t[]'
|
||||||
|
)],
|
||||||
|
])
|
||||||
|
type_map = type_map_tms
|
||||||
|
stm_flag_global = 0
|
||||||
|
def choose_type_map(stm_flag):
|
||||||
|
global type_map # объявляем, что будем менять глобальную переменную
|
||||||
|
global stm_flag_global # объявляем, что будем менять глобальную переменную
|
||||||
|
if stm_flag:
|
||||||
|
type_map = type_map_stm32
|
||||||
|
stm_flag_global = 1
|
||||||
|
else:
|
||||||
|
type_map = type_map_tms
|
||||||
|
stm_flag_global = 0
|
||||||
|
|
||||||
def map_type_to_pt(typename, varname=None, typedef_map=None):
|
def map_type_to_pt(typename, varname=None, typedef_map=None):
|
||||||
typename_orig = typename.strip()
|
typename_orig = typename.strip()
|
||||||
@@ -140,20 +285,26 @@ def add_new_vars_to_xml(proj_path, xml_rel_path, output_path):
|
|||||||
Возвращает True если что-то добавлено и XML перезаписан, иначе False.
|
Возвращает True если что-то добавлено и XML перезаписан, иначе False.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
pattern = re.compile(
|
||||||
|
r'{\s*\(uint8_t\s*\*\)\s*&([a-zA-Z_][a-zA-Z0-9_]*(?:\[.*?\])?(?:(?:\.|->)[a-zA-Z_][a-zA-Z0-9_]*(?:\[.*?\])?)*)\s*,\s*'
|
||||||
|
r'(pt_\w+)\s*,\s*'
|
||||||
|
r'(t?_?iq\w+)\s*,\s*'
|
||||||
|
r'(t?_?iq\w+)\s*,\s*'
|
||||||
|
r'"([^"]+)"'
|
||||||
|
)
|
||||||
# Считываем существующие переменные
|
# Считываем существующие переменные
|
||||||
parsed_vars = {}
|
parsed_vars = {}
|
||||||
if os.path.isfile(output_path):
|
if os.path.isfile(output_path):
|
||||||
with open(output_path, 'r', encoding='utf-8', errors='ignore') as f:
|
with open(output_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
# {(char *)&some.deep.var.name , pt_uint16 , t_iq15 , "ShortName"},
|
# {(uint8_t *)&some.deep.var.name , pt_uint16 , t_iq15 , t_iq10, "ShortName"},
|
||||||
m = re.match(
|
m = pattern.search(line)
|
||||||
r'{\s*\(char\s*\*\)\s*&([a-zA-Z_][a-zA-Z0-9_]*)\s*,\s*(pt_\w+)\s*,\s*(t?iq_\w+)\s*,\s*"([^"]+)"',
|
|
||||||
line)
|
|
||||||
if m:
|
if m:
|
||||||
full_varname = m.group(1) # e.g., some.deep.var.name
|
full_varname = m.group(1) # e.g., some.deep.var.name
|
||||||
pt_type = m.group(2)
|
pt_type = m.group(2)
|
||||||
iq_type = m.group(3)
|
iq_type = m.group(3)
|
||||||
shortname = m.group(4)
|
return_type = m.group(4)
|
||||||
|
shortname = m.group(5)
|
||||||
|
|
||||||
parsed_vars[full_varname] = {
|
parsed_vars[full_varname] = {
|
||||||
'pt_type': pt_type,
|
'pt_type': pt_type,
|
||||||
@@ -161,7 +312,7 @@ def add_new_vars_to_xml(proj_path, xml_rel_path, output_path):
|
|||||||
'enable': True,
|
'enable': True,
|
||||||
'show_var': True,
|
'show_var': True,
|
||||||
'shortname': shortname,
|
'shortname': shortname,
|
||||||
'return_type': 'int',
|
'return_type': return_type,
|
||||||
'type': '', # Можешь дополнить из externs
|
'type': '', # Можешь дополнить из externs
|
||||||
'file': '', # Можешь дополнить из externs
|
'file': '', # Можешь дополнить из externs
|
||||||
'extern': False,
|
'extern': False,
|
||||||
@@ -284,12 +435,27 @@ def read_vars_from_xml(proj_path, xml_rel_path):
|
|||||||
return unique_vars, include_files, vars_need_extern
|
return unique_vars, include_files, vars_need_extern
|
||||||
|
|
||||||
|
|
||||||
|
def read_file_try_encodings(filepath):
|
||||||
|
if not os.path.isfile(filepath):
|
||||||
|
# Файл не существует — просто вернуть пустую строку или None
|
||||||
|
return "", None
|
||||||
|
for enc in ['utf-8', 'cp1251']:
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding=enc) as f:
|
||||||
|
content = f.read()
|
||||||
|
return content, enc
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
continue
|
||||||
|
raise UnicodeDecodeError(f"Не удалось прочитать файл {filepath} с кодировками utf-8 и cp1251")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def generate_vars_file(proj_path, xml_path, output_dir):
|
def generate_vars_file(proj_path, xml_path, output_dir):
|
||||||
output_dir = os.path.join(proj_path, output_dir)
|
output_dir = os.path.join(proj_path, output_dir)
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
output_path = os.path.join(output_dir, 'debug_vars.c')
|
output_path = os.path.join(output_dir, 'debug_vars.c')
|
||||||
|
LIBC_path = os.path.join(output_dir, 'debug_tools.c')
|
||||||
|
LIBH_path = os.path.join(output_dir, 'debug_tools.h')
|
||||||
|
|
||||||
|
|
||||||
# Запись новых переменных для в XML
|
# Запись новых переменных для в XML
|
||||||
@@ -330,15 +496,14 @@ def generate_vars_file(proj_path, xml_path, output_dir):
|
|||||||
if not pt_type:
|
if not pt_type:
|
||||||
pt_type = map_type_to_pt(vtype, vname)
|
pt_type = map_type_to_pt(vtype, vname)
|
||||||
|
|
||||||
|
ret_type = info.get('return_type')
|
||||||
ret_type = info.get('pt_type')
|
|
||||||
if not ret_type:
|
if not ret_type:
|
||||||
pt_type = 't_iq_none'
|
pt_type = 't_iq_none'
|
||||||
|
|
||||||
# Дополнительные поля, например комментарий
|
# Дополнительные поля, например комментарий
|
||||||
comment = info.get("comment", "")
|
comment = info.get("comment", "")
|
||||||
short_name = info.get("shortname", f'"{vname}"')
|
short_name = info.get("shortname", f'"{vname}"')
|
||||||
short_trimmed = short_name[:10] # ограничиваем длину до 10
|
short_trimmed = short_name[:shortnameSize] # ограничиваем длину до 10
|
||||||
|
|
||||||
if pt_type not in ('pt_struct', 'pt_union'):
|
if pt_type not in ('pt_struct', 'pt_union'):
|
||||||
f_name = f'{vname},'
|
f_name = f'{vname},'
|
||||||
@@ -348,7 +513,7 @@ def generate_vars_file(proj_path, xml_path, output_dir):
|
|||||||
f_short_name = f'"{short_trimmed}"' # оборачиваем в кавычки
|
f_short_name = f'"{short_trimmed}"' # оборачиваем в кавычки
|
||||||
# Добавим комментарий после записи, если он есть
|
# Добавим комментарий после записи, если он есть
|
||||||
comment_str = f' // {comment}' if comment else ''
|
comment_str = f' // {comment}' if comment else ''
|
||||||
line = f'{{(char *)&{f_name:<45} {f_type:<15} {f_iq:<15} {f_ret_iq:<15} {f_short_name:<21}}}, \\{comment_str}'
|
line = f'{{(uint8_t *)&{f_name:<58} {f_type:<15} {f_iq:<15} {f_ret_iq:<15} {f_short_name:<21}}}, \\{comment_str}'
|
||||||
new_debug_vars[vname] = line
|
new_debug_vars[vname] = line
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@@ -394,14 +559,19 @@ def generate_vars_file(proj_path, xml_path, output_dir):
|
|||||||
|
|
||||||
out_lines.append(f'\n\n// Определение массива с указателями на переменные для отладки')
|
out_lines.append(f'\n\n// Определение массива с указателями на переменные для отладки')
|
||||||
out_lines.append(f'int DebugVar_Qnt = {len(all_debug_lines)};')
|
out_lines.append(f'int DebugVar_Qnt = {len(all_debug_lines)};')
|
||||||
out_lines.append('#pragma DATA_SECTION(dbg_vars,".dbgvar_info")')
|
if stm_flag_global == 0:
|
||||||
|
out_lines.append('#pragma DATA_SECTION(dbg_vars,".dbgvar_info")')
|
||||||
|
out_lines.append('// pointer_type iq_type return_iq_type short_name')
|
||||||
out_lines.append('DebugVar_t dbg_vars[] = {\\')
|
out_lines.append('DebugVar_t dbg_vars[] = {\\')
|
||||||
out_lines.extend(all_debug_lines)
|
out_lines.extend(all_debug_lines)
|
||||||
out_lines.append('};')
|
out_lines.append('};')
|
||||||
out_lines.append('')
|
out_lines.append('')
|
||||||
# Выберем кодировку для записи файла
|
# Выберем кодировку для записи файла
|
||||||
# Если встречается несколько, возьмем первую из set
|
# Если встречается несколько, возьмем первую из set
|
||||||
enc_to_write = 'cp1251'
|
if stm_flag_global == 0:
|
||||||
|
enc_to_write = 'cp1251'
|
||||||
|
else:
|
||||||
|
enc_to_write = 'utf-8'
|
||||||
|
|
||||||
#print("== GLOBAL VARS FOUND ==")
|
#print("== GLOBAL VARS FOUND ==")
|
||||||
#for vname, (vtype, path) in vars_in_c.items():
|
#for vname, (vtype, path) in vars_in_c.items():
|
||||||
@@ -411,6 +581,16 @@ def generate_vars_file(proj_path, xml_path, output_dir):
|
|||||||
with open(output_path, 'w', encoding=enc_to_write) as f:
|
with open(output_path, 'w', encoding=enc_to_write) as f:
|
||||||
f.write('\n'.join(out_lines))
|
f.write('\n'.join(out_lines))
|
||||||
|
|
||||||
|
if os.path.isfile(LIBC_path):
|
||||||
|
libc_code, _ = read_file_try_encodings(LIBC_path)
|
||||||
|
with open(LIBC_path, 'w', encoding=enc_to_write) as f:
|
||||||
|
f.write(libc_code)
|
||||||
|
|
||||||
|
if os.path.isfile(LIBH_path):
|
||||||
|
libh_code, _ = read_file_try_encodings(LIBH_path)
|
||||||
|
with open(LIBH_path, 'w', encoding=enc_to_write) as f:
|
||||||
|
f.write(libh_code)
|
||||||
|
|
||||||
print(f'Файл debug_vars.c сгенерирован в кодировке, переменных: {len(all_debug_lines)}')
|
print(f'Файл debug_vars.c сгенерирован в кодировке, переменных: {len(all_debug_lines)}')
|
||||||
|
|
||||||
|
|
||||||
@@ -472,16 +652,17 @@ Usage example:
|
|||||||
print(f"Error: Project path '{proj_path}' не является директорией или не существует.")
|
print(f"Error: Project path '{proj_path}' не является директорией или не существует.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
generate_vars_file(proj_path, xml_path_rel, output_dir_rel)
|
generate_vars_file(proj_path, xml_path_rel, output_dir_rel, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
def run_generate(proj_path, xml_path, output_dir):
|
def run_generate(proj_path, xml_path, output_dir, shortname_size):
|
||||||
import os
|
import os
|
||||||
|
global shortnameSize
|
||||||
|
shortnameSize = shortname_size
|
||||||
# Normalize absolute paths
|
# Normalize absolute paths
|
||||||
proj_path = os.path.abspath(proj_path)
|
proj_path = os.path.abspath(proj_path)
|
||||||
xml_path_abs = os.path.abspath(xml_path)
|
xml_path_abs = os.path.abspath(xml_path)
|
||||||
242
Src/makefile_parser.py
Normal file
242
Src/makefile_parser.py
Normal file
@@ -0,0 +1,242 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
from lxml import etree as ET
|
||||||
|
|
||||||
|
|
||||||
|
def strip_single_line_comments(code):
|
||||||
|
# Удалим // ... до конца строки
|
||||||
|
return re.sub(r'//.*?$', '', code, flags=re.MULTILINE)
|
||||||
|
|
||||||
|
def read_file_try_encodings(filepath):
|
||||||
|
if not os.path.isfile(filepath):
|
||||||
|
# Файл не существует — просто вернуть пустую строку или None
|
||||||
|
return "", None
|
||||||
|
for enc in ['utf-8', 'cp1251']:
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding=enc) as f:
|
||||||
|
content = f.read()
|
||||||
|
content = strip_single_line_comments(content)
|
||||||
|
return content, enc
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
continue
|
||||||
|
raise UnicodeDecodeError(f"Не удалось прочитать файл {filepath} с кодировками utf-8 и cp1251")
|
||||||
|
|
||||||
|
def find_all_includes_recursive(c_files, include_dirs, processed_files=None):
|
||||||
|
"""
|
||||||
|
Рекурсивно ищет все include-файлы начиная с заданных c_files.
|
||||||
|
Возвращает множество ПОЛНЫХ ПУТЕЙ к найденным include-файлам.
|
||||||
|
|
||||||
|
include_dirs — список директорий, в которых ищем include-файлы.
|
||||||
|
processed_files — множество уже обработанных файлов (для избежания циклов).
|
||||||
|
"""
|
||||||
|
if processed_files is None:
|
||||||
|
processed_files = set()
|
||||||
|
|
||||||
|
include_files = set()
|
||||||
|
include_pattern = re.compile(r'#include\s+"([^"]+)"')
|
||||||
|
|
||||||
|
for cfile in c_files:
|
||||||
|
norm_path = os.path.normpath(cfile)
|
||||||
|
if norm_path in processed_files:
|
||||||
|
continue
|
||||||
|
processed_files.add(norm_path)
|
||||||
|
|
||||||
|
content, _ = read_file_try_encodings(cfile)
|
||||||
|
if content is None:
|
||||||
|
continue
|
||||||
|
includes = include_pattern.findall(content)
|
||||||
|
for inc in includes:
|
||||||
|
# Ищем полный путь к include-файлу в include_dirs
|
||||||
|
inc_full_path = None
|
||||||
|
for dir_ in include_dirs:
|
||||||
|
candidate = os.path.normpath(os.path.join(dir_, inc))
|
||||||
|
if os.path.isfile(candidate):
|
||||||
|
inc_full_path = os.path.abspath(candidate)
|
||||||
|
break
|
||||||
|
|
||||||
|
if inc_full_path:
|
||||||
|
include_files.add(inc_full_path)
|
||||||
|
|
||||||
|
# Рекурсивный обход вложенных includes
|
||||||
|
if inc_full_path not in processed_files:
|
||||||
|
nested_includes = find_all_includes_recursive(
|
||||||
|
[inc_full_path], include_dirs, processed_files
|
||||||
|
)
|
||||||
|
include_files.update(nested_includes)
|
||||||
|
|
||||||
|
return include_files
|
||||||
|
|
||||||
|
|
||||||
|
def parse_objects_list(objects_list_path, project_root):
|
||||||
|
c_files = []
|
||||||
|
include_dirs = set()
|
||||||
|
|
||||||
|
if not os.path.isfile(objects_list_path):
|
||||||
|
return c_files, include_dirs
|
||||||
|
|
||||||
|
with open(objects_list_path, 'r', encoding='utf-8') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip().strip('"').replace("\\", "/")
|
||||||
|
if line.endswith(".o"):
|
||||||
|
c_file = re.sub(r"\.o$", ".c", line)
|
||||||
|
abs_path = os.path.normpath(os.path.join(project_root, c_file))
|
||||||
|
if os.path.isfile(abs_path):
|
||||||
|
if not any(x in abs_path for x in ["DebugTools", "v120", "v100"]):
|
||||||
|
c_files.append(abs_path)
|
||||||
|
include_dirs.add(os.path.dirname(abs_path))
|
||||||
|
|
||||||
|
return c_files, include_dirs
|
||||||
|
|
||||||
|
|
||||||
|
def parse_uvprojx(uvprojx_path):
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import os
|
||||||
|
|
||||||
|
tree = ET.parse(uvprojx_path)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
project_dir = os.path.dirname(os.path.abspath(uvprojx_path))
|
||||||
|
|
||||||
|
c_files = []
|
||||||
|
include_dirs = set()
|
||||||
|
defines = set()
|
||||||
|
|
||||||
|
# Найдём C-файлы и директории
|
||||||
|
for file_elem in root.findall(".//FilePath"):
|
||||||
|
file_path = file_elem.text
|
||||||
|
if file_path:
|
||||||
|
abs_path = os.path.normpath(os.path.join(project_dir, file_path))
|
||||||
|
if os.path.isfile(abs_path):
|
||||||
|
if abs_path.endswith(".c"):
|
||||||
|
c_files.append(abs_path)
|
||||||
|
include_dirs.add(os.path.dirname(abs_path))
|
||||||
|
|
||||||
|
# Включаем IncludePath
|
||||||
|
for inc_path_elem in root.findall(".//IncludePath"):
|
||||||
|
path_text = inc_path_elem.text
|
||||||
|
if path_text:
|
||||||
|
paths = path_text.split(';')
|
||||||
|
for p in paths:
|
||||||
|
p = p.strip()
|
||||||
|
if p:
|
||||||
|
abs_inc_path = os.path.normpath(os.path.join(project_dir, p))
|
||||||
|
if os.path.isdir(abs_inc_path):
|
||||||
|
include_dirs.add(abs_inc_path)
|
||||||
|
|
||||||
|
# Добавим <Define>
|
||||||
|
for define_elem in root.findall(".//Define"):
|
||||||
|
def_text = define_elem.text
|
||||||
|
if def_text:
|
||||||
|
for d in def_text.split(','):
|
||||||
|
d = d.strip()
|
||||||
|
if d:
|
||||||
|
defines.add(d)
|
||||||
|
|
||||||
|
h_files = find_all_includes_recursive(c_files, include_dirs)
|
||||||
|
|
||||||
|
return sorted(c_files), sorted(h_files), sorted(include_dirs), sorted(defines)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def parse_makefile(makefile_path, proj_path):
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
project_root = os.path.abspath(proj_path)
|
||||||
|
c_files = []
|
||||||
|
include_dirs = set()
|
||||||
|
defines = [] # Заглушка: нет define-параметров из Makefile
|
||||||
|
|
||||||
|
with open(makefile_path, 'r', encoding='utf-8') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
raw_entries = []
|
||||||
|
collecting = False
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.strip()
|
||||||
|
|
||||||
|
if (("ORDERED_OBJS" in stripped or "C_SOURCES" in stripped) and ("+=" in stripped or "=" in stripped)):
|
||||||
|
collecting = True
|
||||||
|
|
||||||
|
if collecting:
|
||||||
|
line_clean = stripped.rstrip("\\").strip()
|
||||||
|
if line_clean:
|
||||||
|
line_clean = re.sub(r"\$\([^)]+\)", "", line_clean)
|
||||||
|
line_clean = re.sub(r"\$\{[^}]+\}", "", line_clean)
|
||||||
|
raw_entries.append(line_clean)
|
||||||
|
|
||||||
|
if not stripped.endswith("\\"):
|
||||||
|
collecting = False
|
||||||
|
|
||||||
|
for entry in raw_entries:
|
||||||
|
for token in entry.split():
|
||||||
|
token = token.strip('"')
|
||||||
|
if not token:
|
||||||
|
continue
|
||||||
|
|
||||||
|
token = token.replace("\\", "/")
|
||||||
|
|
||||||
|
if token.endswith(".obj"):
|
||||||
|
token = re.sub(r"\.obj$", ".c", token)
|
||||||
|
elif token.endswith(".o"):
|
||||||
|
token = re.sub(r"\.o$", ".c", token)
|
||||||
|
|
||||||
|
if token.endswith(".c"):
|
||||||
|
abs_path = os.path.normpath(os.path.join(project_root, token))
|
||||||
|
if os.path.isfile(abs_path):
|
||||||
|
if not any(x in abs_path for x in ["DebugTools", "v120", "v100"]):
|
||||||
|
c_files.append(abs_path)
|
||||||
|
include_dirs.add(os.path.dirname(abs_path))
|
||||||
|
|
||||||
|
if not c_files:
|
||||||
|
makefile_dir = os.path.dirname(os.path.abspath(makefile_path))
|
||||||
|
objects_list_path = os.path.join(makefile_dir, "objects.list")
|
||||||
|
c_from_objects, inc_from_objects = parse_objects_list(objects_list_path, project_root)
|
||||||
|
c_files.extend(c_from_objects)
|
||||||
|
include_dirs.update(inc_from_objects)
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
if "-I" in line or "C_INCLUDES" in line:
|
||||||
|
matches = re.findall(r"-I\s*([^\s\\]+)", line)
|
||||||
|
for match in matches:
|
||||||
|
match = match.strip('"').replace("\\", "/")
|
||||||
|
abs_include = os.path.normpath(os.path.join(project_root, match))
|
||||||
|
if os.path.isdir(abs_include):
|
||||||
|
include_dirs.add(abs_include)
|
||||||
|
|
||||||
|
# Добавляем пути с заменой 'Src' на 'Inc', если путь заканчивается на 'Src'
|
||||||
|
additional_includes = set()
|
||||||
|
for inc in include_dirs:
|
||||||
|
if inc.endswith(os.sep + "Src") or inc.endswith("/Src"):
|
||||||
|
inc_inc = inc[:-3] + "Inc" # заменяем 'Src' на 'Inc'
|
||||||
|
if os.path.isdir(inc_inc):
|
||||||
|
additional_includes.add(inc_inc)
|
||||||
|
|
||||||
|
include_dirs.update(additional_includes)
|
||||||
|
|
||||||
|
h_files = find_all_includes_recursive(c_files, include_dirs)
|
||||||
|
|
||||||
|
return sorted(c_files), sorted(h_files), sorted(include_dirs), sorted(defines)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_project(project_file_path, project_root=None):
|
||||||
|
"""
|
||||||
|
Выбирает парсер в зависимости от расширения project_file_path:
|
||||||
|
- для *.uvprojx и *.uvproj вызывается парсер Keil
|
||||||
|
- для остальных - parse_makefile
|
||||||
|
|
||||||
|
project_root нужен для parse_makefile, если не передан - берется из project_file_path
|
||||||
|
"""
|
||||||
|
ext = os.path.splitext(project_file_path)[1].lower()
|
||||||
|
|
||||||
|
if ext in ['.uvprojx', '.uvproj']:
|
||||||
|
# Парсим Keil проект
|
||||||
|
return parse_uvprojx(project_file_path)
|
||||||
|
else:
|
||||||
|
# Парсим makefile
|
||||||
|
if project_root is None:
|
||||||
|
project_root = os.path.dirname(os.path.abspath(project_file_path))
|
||||||
|
return parse_makefile(project_file_path, project_root)
|
||||||
36
Src/myXML.py
36
Src/myXML.py
@@ -1,5 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
import xml.etree.ElementTree as ET
|
from lxml import etree
|
||||||
|
|
||||||
def make_absolute_path(path, base_path):
|
def make_absolute_path(path, base_path):
|
||||||
if not os.path.isabs(path) and os.path.isdir(base_path):
|
if not os.path.isabs(path) and os.path.isdir(base_path):
|
||||||
@@ -33,44 +33,38 @@ def make_relative_path(abs_path, base_path):
|
|||||||
return abs_path.replace("\\", "/")
|
return abs_path.replace("\\", "/")
|
||||||
|
|
||||||
def indent_xml(elem, level=0):
|
def indent_xml(elem, level=0):
|
||||||
indent = " "
|
# Убираем strip() — они медленные, и текст мы всё равно перезаписываем
|
||||||
i = "\n" + level * indent
|
i = "\n" + level * " "
|
||||||
if len(elem):
|
if len(elem):
|
||||||
if not elem.text or not elem.text.strip():
|
elem.text = elem.text or i + " "
|
||||||
elem.text = i + indent
|
|
||||||
for child in elem:
|
for child in elem:
|
||||||
indent_xml(child, level + 1)
|
indent_xml(child, level + 1)
|
||||||
if not elem.tail or not elem.tail.strip():
|
elem[-1].tail = elem[-1].tail or i
|
||||||
elem.tail = i
|
|
||||||
else:
|
else:
|
||||||
if level and (not elem.tail or not elem.tail.strip()):
|
elem.tail = elem.tail or i
|
||||||
elem.tail = i
|
|
||||||
|
|
||||||
|
|
||||||
def fwrite(root, xml_full_path):
|
def fwrite(root, xml_full_path):
|
||||||
indent_xml(root)
|
#indent_xml(root)
|
||||||
ET.ElementTree(root).write(xml_full_path, encoding="utf-8", xml_declaration=True)
|
#ET.ElementTree(root).write(xml_full_path, encoding="utf-8", xml_declaration=True)
|
||||||
|
rough_string = etree.tostring(root, encoding="utf-8")
|
||||||
|
parsed = etree.fromstring(rough_string)
|
||||||
|
with open(xml_full_path, "wb") as f:
|
||||||
|
f.write(etree.tostring(parsed, pretty_print=True, encoding="utf-8", xml_declaration=True))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def safe_parse_xml(xml_path):
|
def safe_parse_xml(xml_path):
|
||||||
"""
|
|
||||||
Безопасно парсит XML-файл.
|
|
||||||
|
|
||||||
Возвращает кортеж (root, tree) или (None, None) при ошибках.
|
|
||||||
"""
|
|
||||||
if not xml_path or not os.path.isfile(xml_path):
|
if not xml_path or not os.path.isfile(xml_path):
|
||||||
print(f"Файл '{xml_path}' не найден или путь пустой")
|
print(f"Файл '{xml_path}' не найден или путь пустой")
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if os.path.getsize(xml_path) == 0:
|
if os.path.getsize(xml_path) == 0:
|
||||||
return None, None
|
return None, None
|
||||||
|
tree = etree.parse(xml_path)
|
||||||
tree = ET.parse(xml_path)
|
|
||||||
root = tree.getroot()
|
root = tree.getroot()
|
||||||
return root, tree
|
return root, tree
|
||||||
|
except etree .XMLSyntaxError as e:
|
||||||
except ET.ParseError as e:
|
|
||||||
print(f"Ошибка парсинга XML файла '{xml_path}': {e}")
|
print(f"Ошибка парсинга XML файла '{xml_path}': {e}")
|
||||||
return None, None
|
return None, None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
def strip_single_line_comments(code):
|
|
||||||
# Удалим // ... до конца строки
|
|
||||||
return re.sub(r'//.*?$', '', code, flags=re.MULTILINE)
|
|
||||||
|
|
||||||
def read_file_try_encodings(filepath):
|
|
||||||
if not os.path.isfile(filepath):
|
|
||||||
# Файл не существует — просто вернуть пустую строку или None
|
|
||||||
return "", None
|
|
||||||
for enc in ['utf-8', 'cp1251']:
|
|
||||||
try:
|
|
||||||
with open(filepath, 'r', encoding=enc) as f:
|
|
||||||
content = f.read()
|
|
||||||
content = strip_single_line_comments(content)
|
|
||||||
return content, enc
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
continue
|
|
||||||
raise UnicodeDecodeError(f"Не удалось прочитать файл {filepath} с кодировками utf-8 и cp1251")
|
|
||||||
|
|
||||||
def find_all_includes_recursive(c_files, include_dirs, processed_files=None):
|
|
||||||
"""
|
|
||||||
Рекурсивно ищет все include-файлы начиная с заданных c_files.
|
|
||||||
Возвращает множество ПОЛНЫХ ПУТЕЙ к найденным include-файлам.
|
|
||||||
|
|
||||||
include_dirs — список директорий, в которых ищем include-файлы.
|
|
||||||
processed_files — множество уже обработанных файлов (для избежания циклов).
|
|
||||||
"""
|
|
||||||
if processed_files is None:
|
|
||||||
processed_files = set()
|
|
||||||
|
|
||||||
include_files = set()
|
|
||||||
include_pattern = re.compile(r'#include\s+"([^"]+)"')
|
|
||||||
|
|
||||||
for cfile in c_files:
|
|
||||||
norm_path = os.path.normpath(cfile)
|
|
||||||
if norm_path in processed_files:
|
|
||||||
continue
|
|
||||||
processed_files.add(norm_path)
|
|
||||||
|
|
||||||
content, _ = read_file_try_encodings(cfile)
|
|
||||||
if content is None:
|
|
||||||
continue
|
|
||||||
includes = include_pattern.findall(content)
|
|
||||||
for inc in includes:
|
|
||||||
# Ищем полный путь к include-файлу в include_dirs
|
|
||||||
inc_full_path = None
|
|
||||||
for dir_ in include_dirs:
|
|
||||||
candidate = os.path.normpath(os.path.join(dir_, inc))
|
|
||||||
if os.path.isfile(candidate):
|
|
||||||
inc_full_path = os.path.abspath(candidate)
|
|
||||||
break
|
|
||||||
|
|
||||||
if inc_full_path:
|
|
||||||
include_files.add(inc_full_path)
|
|
||||||
|
|
||||||
# Рекурсивный обход вложенных includes
|
|
||||||
if inc_full_path not in processed_files:
|
|
||||||
nested_includes = find_all_includes_recursive(
|
|
||||||
[inc_full_path], include_dirs, processed_files
|
|
||||||
)
|
|
||||||
include_files.update(nested_includes)
|
|
||||||
|
|
||||||
return include_files
|
|
||||||
|
|
||||||
|
|
||||||
def parse_makefile(makefile_path, proj_path):
|
|
||||||
makefile_dir = os.path.dirname(makefile_path)
|
|
||||||
project_root = proj_path
|
|
||||||
|
|
||||||
with open(makefile_path, 'r', encoding='utf-8') as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
|
|
||||||
objs_lines = []
|
|
||||||
collecting = False
|
|
||||||
|
|
||||||
for line in lines:
|
|
||||||
stripped = line.strip()
|
|
||||||
if stripped.startswith("ORDERED_OBJS") and "+=" in stripped:
|
|
||||||
parts = stripped.split("\\")
|
|
||||||
first_part = parts[0]
|
|
||||||
idx = first_part.find("+=")
|
|
||||||
tail = first_part[idx+2:].strip()
|
|
||||||
if tail:
|
|
||||||
objs_lines.append(tail)
|
|
||||||
collecting = True
|
|
||||||
if len(parts) > 1:
|
|
||||||
for p in parts[1:]:
|
|
||||||
p = p.strip()
|
|
||||||
if p:
|
|
||||||
objs_lines.append(p)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if collecting:
|
|
||||||
if stripped.endswith("\\"):
|
|
||||||
objs_lines.append(stripped[:-1].strip())
|
|
||||||
else:
|
|
||||||
objs_lines.append(stripped)
|
|
||||||
collecting = False
|
|
||||||
|
|
||||||
objs_str = ' '.join(objs_lines)
|
|
||||||
|
|
||||||
objs_str = re.sub(r"\$\([^)]+\)", "", objs_str)
|
|
||||||
|
|
||||||
objs = []
|
|
||||||
for part in objs_str.split():
|
|
||||||
part = part.strip()
|
|
||||||
if part.startswith('"') and part.endswith('"'):
|
|
||||||
part = part[1:-1]
|
|
||||||
if part:
|
|
||||||
objs.append(part)
|
|
||||||
|
|
||||||
c_files = []
|
|
||||||
include_dirs = set()
|
|
||||||
|
|
||||||
for obj_path in objs:
|
|
||||||
if "DebugTools" in obj_path:
|
|
||||||
continue
|
|
||||||
if "v120" in obj_path:
|
|
||||||
continue
|
|
||||||
if "v100" in obj_path:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if obj_path.startswith("Debug\\") or obj_path.startswith("Debug/"):
|
|
||||||
rel_path = obj_path.replace("Debug\\", "Src\\").replace("Debug/", "Src/")
|
|
||||||
else:
|
|
||||||
rel_path = obj_path
|
|
||||||
|
|
||||||
abs_path = os.path.normpath(os.path.join(project_root, rel_path))
|
|
||||||
|
|
||||||
root, ext = os.path.splitext(abs_path)
|
|
||||||
if ext.lower() == ".obj":
|
|
||||||
c_path = root + ".c"
|
|
||||||
else:
|
|
||||||
c_path = abs_path
|
|
||||||
|
|
||||||
# Проверяем существование файла, если нет — пропускаем
|
|
||||||
if not os.path.isfile(c_path):
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Сохраняем только .c файлы
|
|
||||||
if c_path.lower().endswith(".c"):
|
|
||||||
c_files.append(c_path)
|
|
||||||
dir_path = os.path.dirname(c_path)
|
|
||||||
if dir_path and "DebugTools" not in dir_path:
|
|
||||||
include_dirs.add(dir_path)
|
|
||||||
|
|
||||||
|
|
||||||
h_files = find_all_includes_recursive(c_files, include_dirs)
|
|
||||||
|
|
||||||
|
|
||||||
return sorted(c_files), sorted(h_files), sorted(include_dirs)
|
|
||||||
319
Src/path_hints.py
Normal file
319
Src/path_hints.py
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
# path_hints.py
|
||||||
|
from __future__ import annotations
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- tokenization helpers ----------------------
|
||||||
|
|
||||||
|
def split_path_tokens(path: str) -> List[str]:
|
||||||
|
"""
|
||||||
|
Разбивает строку пути на логические части:
|
||||||
|
'foo[2].bar[1]->baz' -> ['foo', '[2]', 'bar', '[1]', 'baz']
|
||||||
|
Аналог твоей split_path(), но оставлена как чистая функция.
|
||||||
|
"""
|
||||||
|
tokens: List[str] = []
|
||||||
|
token = ''
|
||||||
|
i = 0
|
||||||
|
L = len(path)
|
||||||
|
while i < L:
|
||||||
|
c = path[i]
|
||||||
|
# '->'
|
||||||
|
if c == '-' and i + 1 < L and path[i:i+2] == '->':
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
token = ''
|
||||||
|
i += 2
|
||||||
|
continue
|
||||||
|
# одиночный '-' в конце
|
||||||
|
if c == '-' and i == L - 1:
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
# '.'
|
||||||
|
if c == '.':
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
token = ''
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
# '[' ... ']'
|
||||||
|
if c == '[':
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
token = ''
|
||||||
|
idx = ''
|
||||||
|
while i < L and path[i] != ']':
|
||||||
|
idx += path[i]
|
||||||
|
i += 1
|
||||||
|
if i < L and path[i] == ']':
|
||||||
|
idx += ']'
|
||||||
|
i += 1
|
||||||
|
tokens.append(idx)
|
||||||
|
continue
|
||||||
|
# обычный символ
|
||||||
|
token += c
|
||||||
|
i += 1
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
return tokens
|
||||||
|
|
||||||
|
def split_path_tokens_with_spans(path: str) -> List[Tuple[str, int, int]]:
|
||||||
|
"""
|
||||||
|
Возвращает список кортежей (токен, start_pos, end_pos)
|
||||||
|
Токены — так же, как в split_path_tokens, но с позициями в исходной строке.
|
||||||
|
"""
|
||||||
|
tokens = []
|
||||||
|
i = 0
|
||||||
|
L = len(path)
|
||||||
|
while i < L:
|
||||||
|
c = path[i]
|
||||||
|
start = i
|
||||||
|
# '->'
|
||||||
|
if c == '-' and i + 1 < L and path[i:i+2] == '->':
|
||||||
|
tokens.append(('->', start, start + 2))
|
||||||
|
i += 2
|
||||||
|
continue
|
||||||
|
if c == '.':
|
||||||
|
tokens.append(('.', start, start + 1))
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
if c == '[':
|
||||||
|
# захватим весь индекс с ']'
|
||||||
|
j = i
|
||||||
|
while j < L and path[j] != ']':
|
||||||
|
j += 1
|
||||||
|
if j < L and path[j] == ']':
|
||||||
|
j += 1
|
||||||
|
tokens.append((path[i:j], i, j))
|
||||||
|
i = j
|
||||||
|
continue
|
||||||
|
# иначе - обычное имя (до точки, стрелки или скобок)
|
||||||
|
j = i
|
||||||
|
while j < L and path[j] not in ['.', '-', '[']:
|
||||||
|
if path[j] == '-' and j + 1 < L and path[j:j+2] == '->':
|
||||||
|
break
|
||||||
|
j += 1
|
||||||
|
tokens.append((path[i:j], i, j))
|
||||||
|
i = j
|
||||||
|
# фильтруем из списка токены-разделители '.' и '->' чтобы оставить только логические части
|
||||||
|
filtered = [t for t in tokens if t[0] not in ['.', '->']]
|
||||||
|
return filtered
|
||||||
|
|
||||||
|
def canonical_key(path: str) -> str:
|
||||||
|
"""
|
||||||
|
Преобразует путь к канонической форме для индекса / поиска:
|
||||||
|
- '->' -> '.'
|
||||||
|
- '[' -> '.['
|
||||||
|
- lower()
|
||||||
|
"""
|
||||||
|
p = path.replace('->', '.')
|
||||||
|
p = p.replace('[', '.[')
|
||||||
|
return p.lower()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- индекс узлов ----------------------
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PathNode:
|
||||||
|
"""
|
||||||
|
Узел в логическом дереве путей.
|
||||||
|
Храним:
|
||||||
|
- собственное имя (локальное, напр. 'controller' или '[3]')
|
||||||
|
- полный путь (оригинальный, как его должен видеть пользователь)
|
||||||
|
- тип (опционально; widget может хранить отдельно)
|
||||||
|
- дети
|
||||||
|
"""
|
||||||
|
name: str
|
||||||
|
full_path: str
|
||||||
|
type_str: str = ''
|
||||||
|
children: Dict[str, "PathNode"] = field(default_factory=dict)
|
||||||
|
|
||||||
|
def add_child(self, child: "PathNode") -> None:
|
||||||
|
self.children[child.name] = child
|
||||||
|
|
||||||
|
def get_children(self) -> List["PathNode"]:
|
||||||
|
"""
|
||||||
|
Вернуть список дочерних узлов, отсортированных по имени.
|
||||||
|
"""
|
||||||
|
return sorted(self.children.values(), key=lambda n: n.name)
|
||||||
|
|
||||||
|
class PathHints:
|
||||||
|
"""
|
||||||
|
Движок автоподсказок / completion.
|
||||||
|
Работает с плоским списком ПОЛНЫХ имён (как показываются пользователю).
|
||||||
|
Сам восстанавливает иерархию и выдаёт подсказки по текущему вводу.
|
||||||
|
Qt-независим.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self._paths: List[str] = []
|
||||||
|
self._types: Dict[str, str] = {} # full_path -> type_str (опционально)
|
||||||
|
self._index: Dict[str, PathNode] = {} # canonical full path -> node
|
||||||
|
self._root_children: Dict[str, PathNode] = {} # top-level по первому токену
|
||||||
|
|
||||||
|
# ------------ Подаём данные ------------
|
||||||
|
def set_paths(self,
|
||||||
|
paths: List[Tuple[str, Optional[str]]]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
paths: список кортежей (full_path, type_str|None).
|
||||||
|
Пример: ('project.controller.read.errors.bit.status_er0', 'unsigned int')
|
||||||
|
Поля могут содержать '->' и индексы, т.е. строки в пользовательском формате.
|
||||||
|
|
||||||
|
NOTE: порядок не важен; дерево строится автоматически.
|
||||||
|
"""
|
||||||
|
self._paths = []
|
||||||
|
self._types.clear()
|
||||||
|
self._index.clear()
|
||||||
|
self._root_children.clear()
|
||||||
|
|
||||||
|
for p, t in paths:
|
||||||
|
if t is None:
|
||||||
|
t = ''
|
||||||
|
self._add_path(p, t)
|
||||||
|
|
||||||
|
def _add_path(self, full_path: str, type_str: str) -> None:
|
||||||
|
self._paths.append(full_path)
|
||||||
|
self._types[full_path] = type_str
|
||||||
|
|
||||||
|
tokens_spans = split_path_tokens_with_spans(full_path)
|
||||||
|
if not tokens_spans:
|
||||||
|
return
|
||||||
|
|
||||||
|
cur_dict = self._root_children
|
||||||
|
cur_full = ''
|
||||||
|
parent_node: Optional[PathNode] = None
|
||||||
|
|
||||||
|
for i, (tok, start, end) in enumerate(tokens_spans):
|
||||||
|
cur_full = full_path[:end] # подстрока с начала до конца токена включительно
|
||||||
|
|
||||||
|
node = cur_dict.get(tok)
|
||||||
|
if node is None:
|
||||||
|
node = PathNode(name=tok, full_path=cur_full)
|
||||||
|
cur_dict[tok] = node
|
||||||
|
|
||||||
|
# Регистрируем все узлы, включая промежуточные
|
||||||
|
self._index[canonical_key(cur_full)] = node
|
||||||
|
|
||||||
|
parent_node = node
|
||||||
|
cur_dict = node.children
|
||||||
|
|
||||||
|
# В последний узел добавляем тип
|
||||||
|
if parent_node:
|
||||||
|
parent_node.type_str = type_str
|
||||||
|
|
||||||
|
|
||||||
|
# ------------ Поиск узла ------------
|
||||||
|
|
||||||
|
def find_node(self, path: str) -> Optional[PathNode]:
|
||||||
|
return self._index.get(canonical_key(path))
|
||||||
|
|
||||||
|
def get_children(self, full_path: str) -> List[PathNode]:
|
||||||
|
"""
|
||||||
|
Вернуть список дочерних узлов PathNode для заданного полного пути.
|
||||||
|
Если узел не найден — вернуть пустой список.
|
||||||
|
"""
|
||||||
|
node = self.find_node(full_path)
|
||||||
|
if node is None:
|
||||||
|
return []
|
||||||
|
return node.get_children()
|
||||||
|
# ------------ Подсказки ------------
|
||||||
|
|
||||||
|
def suggest(self,
|
||||||
|
text: str,
|
||||||
|
*,
|
||||||
|
include_partial: bool = True
|
||||||
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Вернёт список *полных имён узлов*, подходящих под ввод.
|
||||||
|
Правила (упрощённо, повторяя твою update_completions()):
|
||||||
|
- Если текст пуст → top-level.
|
||||||
|
- Если заканчивается на '.' или '->' или '[' → вернуть детей текущего узла.
|
||||||
|
- Иначе → фильтр по последнему фрагменту (prefix substring match).
|
||||||
|
"""
|
||||||
|
text = text or ''
|
||||||
|
stripped = text.strip()
|
||||||
|
|
||||||
|
# пусто: top-level
|
||||||
|
if stripped == '':
|
||||||
|
return sorted(self._root_full_names())
|
||||||
|
|
||||||
|
# Завершение по разделителю?
|
||||||
|
if stripped.endswith('.') or stripped.endswith('->') or stripped.endswith('['):
|
||||||
|
base = stripped[:-1] if stripped.endswith('[') else stripped.rstrip('.').rstrip('>').rstrip('-')
|
||||||
|
node = self.find_node(base)
|
||||||
|
if node:
|
||||||
|
return self._children_full_names(node)
|
||||||
|
# не нашли базу — ничего
|
||||||
|
return []
|
||||||
|
|
||||||
|
# иначе: обычный поиск по последней части
|
||||||
|
toks = split_path_tokens(stripped)
|
||||||
|
prefix_last = toks[-1].lower() if toks else ''
|
||||||
|
parent_toks = toks[:-1]
|
||||||
|
|
||||||
|
if not parent_toks:
|
||||||
|
# фильтр top-level
|
||||||
|
res = []
|
||||||
|
for name, node in self._root_children.items():
|
||||||
|
if prefix_last == '' or prefix_last in name.lower():
|
||||||
|
res.append(node.full_path)
|
||||||
|
return sorted(res)
|
||||||
|
|
||||||
|
# есть родитель
|
||||||
|
parent_path = self._join_tokens(parent_toks)
|
||||||
|
parent_node = self.find_node(parent_path)
|
||||||
|
if not parent_node:
|
||||||
|
return []
|
||||||
|
res = []
|
||||||
|
for child in parent_node.children.values():
|
||||||
|
if prefix_last == '' or prefix_last in child.name.lower():
|
||||||
|
res.append(child.full_path)
|
||||||
|
return sorted(res)
|
||||||
|
|
||||||
|
def add_separator(self, full_path: str) -> str:
|
||||||
|
"""
|
||||||
|
Возвращает full_path с добавленным разделителем ('.' или '['),
|
||||||
|
если у узла есть дети и пользователь ещё не поставил разделитель.
|
||||||
|
Если первый ребёнок — массивный токен ('[0]') → добавляем '['.
|
||||||
|
Позже можно допилить '->' для указателей.
|
||||||
|
"""
|
||||||
|
node = self.find_node(full_path)
|
||||||
|
text = full_path
|
||||||
|
|
||||||
|
if node and node.children and not (
|
||||||
|
text.endswith('.') or text.endswith('->') or text.endswith('[')
|
||||||
|
):
|
||||||
|
first_child = next(iter(node.children.values()))
|
||||||
|
if first_child.name.startswith('['):
|
||||||
|
text += '[' # сразу начинаем индекс
|
||||||
|
else:
|
||||||
|
text += '.' # обычный переход
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
# ------------ внутренние вспомогательные ------------
|
||||||
|
|
||||||
|
def _root_full_names(self) -> List[str]:
|
||||||
|
return [node.full_path for node in self._root_children.values()]
|
||||||
|
|
||||||
|
def _children_full_names(self, node: PathNode) -> List[str]:
|
||||||
|
return [ch.full_path for ch in node.children.values()]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _join_tokens(tokens: List[str]) -> str:
|
||||||
|
"""
|
||||||
|
Собираем путь обратно. Для внутренних нужд (поиск), формат не критичен —
|
||||||
|
всё равно canonical_key() нормализует.
|
||||||
|
"""
|
||||||
|
if not tokens:
|
||||||
|
return ''
|
||||||
|
out = tokens[0]
|
||||||
|
for t in tokens[1:]:
|
||||||
|
if t.startswith('['):
|
||||||
|
out += t
|
||||||
|
else:
|
||||||
|
out += '.' + t
|
||||||
|
return out
|
||||||
Binary file not shown.
@@ -6,8 +6,8 @@ import sys
|
|||||||
import contextlib
|
import contextlib
|
||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
from scanVars import run_scan
|
from scan_vars import run_scan
|
||||||
from VariableTable import VariableTableWidget, rows
|
from var_table import VariableTableWidget, rows
|
||||||
|
|
||||||
from PySide2.QtWidgets import (
|
from PySide2.QtWidgets import (
|
||||||
QApplication, QWidget, QTableWidget, QTableWidgetItem,
|
QApplication, QWidget, QTableWidget, QTableWidgetItem,
|
||||||
@@ -73,13 +73,13 @@ class EmittingStream(QObject):
|
|||||||
self._buffer = ""
|
self._buffer = ""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessOutputWindow(QDialog):
|
class ProcessOutputWindow(QDialog):
|
||||||
def __init__(self, proj_path, makefile_path, xml_path, on_done_callback=None):
|
def __init__(self, proj_path, makefile_path, xml_path, on_done_callback=None, parent=None):
|
||||||
super().__init__()
|
super().__init__(parent)
|
||||||
self.setWindowTitle("Поиск переменных...")
|
self.setWindowTitle("Поиск переменных...")
|
||||||
self.resize(600, 480)
|
self.resize(600, 480)
|
||||||
self.setModal(True)
|
self.setModal(True)
|
||||||
|
self.setAttribute(Qt.WA_DeleteOnClose)
|
||||||
|
|
||||||
self.proj_path = proj_path
|
self.proj_path = proj_path
|
||||||
self.makefile_path = makefile_path
|
self.makefile_path = makefile_path
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# build command
|
# build command
|
||||||
# pyinstaller --onefile scanVars.py --add-binary "F:\Work\Projects\TMS\TMS_new_bus\Src\DebugTools/build/libclang.dll;." --distpath . --workpath ./build --specpath ./build
|
# pyinstaller --onefile scan_vars.py --add-binary "F:\Work\Projects\TMS\TMS_new_bus\Src\DebugTools/build/libclang.dll;." --distpath . --workpath ./build --specpath ./build
|
||||||
# start script
|
# start script
|
||||||
# scanVars.exe F:\Work\Projects\TMS\TMS_new_bus\ F:\Work\Projects\TMS\TMS_new_bus\Debug\makefile
|
# scan_vars.exe F:\Work\Projects\TMS\TMS_new_bus\ F:\Work\Projects\TMS\TMS_new_bus\Debug\makefile
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
@@ -9,9 +9,9 @@ import re
|
|||||||
import clang.cindex
|
import clang.cindex
|
||||||
from clang import cindex
|
from clang import cindex
|
||||||
from clang.cindex import Config
|
from clang.cindex import Config
|
||||||
import xml.etree.ElementTree as ET
|
import lxml.etree as ET
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from parseMakefile import parse_makefile
|
from makefile_parser import parse_project
|
||||||
from collections import deque
|
from collections import deque
|
||||||
import argparse
|
import argparse
|
||||||
import myXML
|
import myXML
|
||||||
@@ -118,11 +118,11 @@ def get_canonical_typedef_file(var_type, include_dirs):
|
|||||||
break
|
break
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def analyze_variables_across_files(c_files, h_files, include_dirs):
|
def analyze_variables_across_files(c_files, h_files, include_dirs, global_defs):
|
||||||
optional_printf(PRINT_STATUS, "Starting analysis of variables across files...")
|
optional_printf(PRINT_STATUS, "Starting analysis of variables across files...")
|
||||||
index = clang.cindex.Index.create()
|
index = clang.cindex.Index.create()
|
||||||
args = [f"-I{inc}" for inc in include_dirs]
|
define_args = [f"-D{d}" for d in global_defs]
|
||||||
|
args = [f"-I{inc}" for inc in include_dirs] + define_args
|
||||||
unique_vars = {} # имя переменной → словарь с инфой
|
unique_vars = {} # имя переменной → словарь с инфой
|
||||||
h_files_needed = set()
|
h_files_needed = set()
|
||||||
vars_need_extern = {} # имя переменной → словарь без поля 'extern'
|
vars_need_extern = {} # имя переменной → словарь без поля 'extern'
|
||||||
@@ -154,6 +154,7 @@ def analyze_variables_across_files(c_files, h_files, include_dirs):
|
|||||||
# Проверяем, начинается ли имя с "_" и содержит заглавные буквы или служебные символы
|
# Проверяем, начинается ли имя с "_" и содержит заглавные буквы или служебные символы
|
||||||
return bool(re.match(r"^_[_A-Z]", var_name))
|
return bool(re.match(r"^_[_A-Z]", var_name))
|
||||||
|
|
||||||
|
|
||||||
if node.kind == clang.cindex.CursorKind.VAR_DECL:
|
if node.kind == clang.cindex.CursorKind.VAR_DECL:
|
||||||
if node.semantic_parent.kind == clang.cindex.CursorKind.TRANSLATION_UNIT:
|
if node.semantic_parent.kind == clang.cindex.CursorKind.TRANSLATION_UNIT:
|
||||||
is_extern = (node.storage_class == clang.cindex.StorageClass.EXTERN)
|
is_extern = (node.storage_class == clang.cindex.StorageClass.EXTERN)
|
||||||
@@ -171,6 +172,11 @@ def analyze_variables_across_files(c_files, h_files, include_dirs):
|
|||||||
if node.spelling == 'HUGE': # еще одна служеюная, которую хз как выделять
|
if node.spelling == 'HUGE': # еще одна служеюная, которую хз как выделять
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if 'Drivers' in node.location.file.name:
|
||||||
|
return
|
||||||
|
|
||||||
|
if 'uint' in node.spelling:
|
||||||
|
a = 1
|
||||||
# Проверяем, является ли тип указателем на функцию
|
# Проверяем, является ли тип указателем на функцию
|
||||||
# Признак: в типе есть '(' и ')' и '*', например: "void (*)(int)"
|
# Признак: в типе есть '(' и ')' и '*', например: "void (*)(int)"
|
||||||
if "(" in var_type and "*" in var_type and ")" in var_type:
|
if "(" in var_type and "*" in var_type and ")" in var_type:
|
||||||
@@ -295,6 +301,8 @@ def strip_ptr_and_array(typename):
|
|||||||
|
|
||||||
return typename
|
return typename
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def analyze_typedefs_and_struct(typedefs, structs):
|
def analyze_typedefs_and_struct(typedefs, structs):
|
||||||
optional_printf(PRINT_STATUS, "Resolving typedefs and expanding struct field types...")
|
optional_printf(PRINT_STATUS, "Resolving typedefs and expanding struct field types...")
|
||||||
|
|
||||||
@@ -422,10 +430,28 @@ def contains_anywhere_in_node(node, target: str) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def analyze_typedefs_and_structs_across_files(c_files, include_dirs):
|
|
||||||
|
def try_guess_std_include():
|
||||||
|
# Популярные места, где может лежать stdint.h
|
||||||
|
guesses = [
|
||||||
|
r"C:\Keil_v5\ARM\ARMCLANG\include",
|
||||||
|
r"C:\Program Files (x86)\GNU Arm Embedded Toolchain",
|
||||||
|
r"C:\Program Files (x86)\Arm GNU Toolchain"
|
||||||
|
]
|
||||||
|
|
||||||
|
found = []
|
||||||
|
for base in guesses:
|
||||||
|
for root, dirs, files in os.walk(base):
|
||||||
|
if "stdint.h" in files:
|
||||||
|
found.append(root)
|
||||||
|
return found
|
||||||
|
|
||||||
|
def analyze_typedefs_and_structs_across_files(c_files, include_dirs, global_defs):
|
||||||
optional_printf(PRINT_STATUS, "Starting analysis of typedefs and structs across files...")
|
optional_printf(PRINT_STATUS, "Starting analysis of typedefs and structs across files...")
|
||||||
index = clang.cindex.Index.create()
|
index = clang.cindex.Index.create()
|
||||||
args = [f"-I{inc}" for inc in include_dirs]
|
define_args = [f"-D{d}" for d in global_defs]
|
||||||
|
extra_std_include_dirs = try_guess_std_include()
|
||||||
|
args = [f"-I{inc}" for inc in include_dirs] + extra_std_include_dirs + define_args
|
||||||
|
|
||||||
unique_typedefs_raw = {}
|
unique_typedefs_raw = {}
|
||||||
unique_structs_raw = {}
|
unique_structs_raw = {}
|
||||||
@@ -452,7 +478,6 @@ def analyze_typedefs_and_structs_across_files(c_files, include_dirs):
|
|||||||
|
|
||||||
raw_name = node.spelling
|
raw_name = node.spelling
|
||||||
normalized_name = normalize_type_name(raw_name)
|
normalized_name = normalize_type_name(raw_name)
|
||||||
|
|
||||||
# struct_name всегда с префиксом
|
# struct_name всегда с префиксом
|
||||||
if node.spelling and "unnamed" not in normalized_name:
|
if node.spelling and "unnamed" not in normalized_name:
|
||||||
struct_name = f"{prefix}{normalized_name}"
|
struct_name = f"{prefix}{normalized_name}"
|
||||||
@@ -545,7 +570,7 @@ def read_vars_from_xml(xml_path):
|
|||||||
'shortname': var_elem.findtext('shortname', name),
|
'shortname': var_elem.findtext('shortname', name),
|
||||||
'pt_type': var_elem.findtext('pt_type', ''),
|
'pt_type': var_elem.findtext('pt_type', ''),
|
||||||
'iq_type': var_elem.findtext('iq_type', ''),
|
'iq_type': var_elem.findtext('iq_type', ''),
|
||||||
'return_type': var_elem.findtext('return_type', 'int'),
|
'return_type': var_elem.findtext('return_type', 't_iq_none'),
|
||||||
'type': var_elem.findtext('type', 'unknown'),
|
'type': var_elem.findtext('type', 'unknown'),
|
||||||
'file': var_elem.findtext('file', ''),
|
'file': var_elem.findtext('file', ''),
|
||||||
'extern': get_bool('extern'),
|
'extern': get_bool('extern'),
|
||||||
@@ -608,7 +633,7 @@ def generate_xml_output(proj_path, xml_path, unique_vars, h_files_needed, vars_n
|
|||||||
'shortname': info.get('shortname', name),
|
'shortname': info.get('shortname', name),
|
||||||
'pt_type': info.get('pt_type', ''),
|
'pt_type': info.get('pt_type', ''),
|
||||||
'iq_type': info.get('iq_type', ''),
|
'iq_type': info.get('iq_type', ''),
|
||||||
'return_type': info.get('return_type', 'int'),
|
'return_type': info.get('return_type', 't_iq_none'),
|
||||||
'type': info.get('type', 'unknown'),
|
'type': info.get('type', 'unknown'),
|
||||||
'file': info.get('file', ''),
|
'file': info.get('file', ''),
|
||||||
'extern': info.get('extern', False),
|
'extern': info.get('extern', False),
|
||||||
@@ -627,7 +652,7 @@ def generate_xml_output(proj_path, xml_path, unique_vars, h_files_needed, vars_n
|
|||||||
ET.SubElement(var_elem, "shortname").text = info.get('shortname', name)
|
ET.SubElement(var_elem, "shortname").text = info.get('shortname', name)
|
||||||
ET.SubElement(var_elem, "pt_type").text = info.get('pt_type', '')
|
ET.SubElement(var_elem, "pt_type").text = info.get('pt_type', '')
|
||||||
ET.SubElement(var_elem, "iq_type").text = info.get('iq_type', '')
|
ET.SubElement(var_elem, "iq_type").text = info.get('iq_type', '')
|
||||||
ET.SubElement(var_elem, "return_type").text = info.get('return_type', 'int')
|
ET.SubElement(var_elem, "return_type").text = info.get('return_type', 't_iq_none')
|
||||||
|
|
||||||
ET.SubElement(var_elem, "type").text = info.get('type', 'unknown')
|
ET.SubElement(var_elem, "type").text = info.get('type', 'unknown')
|
||||||
rel_file = make_relative_if_possible(info.get('file', ''), proj_path).replace("\\", "/")
|
rel_file = make_relative_if_possible(info.get('file', ''), proj_path).replace("\\", "/")
|
||||||
@@ -855,10 +880,10 @@ Usage example:
|
|||||||
print(f"Error: Makefile path '{makefile_path}' does not exist.")
|
print(f"Error: Makefile path '{makefile_path}' does not exist.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
c_files, h_files, include_dirs = parse_makefile(makefile_path, proj_path)
|
c_files, h_files, include_dirs, global_defs = parse_project(makefile_path, proj_path)
|
||||||
|
|
||||||
vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs)
|
vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs, global_defs)
|
||||||
typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs)
|
typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs, global_defs)
|
||||||
|
|
||||||
vars = dict(sorted(vars.items()))
|
vars = dict(sorted(vars.items()))
|
||||||
includes = get_sorted_headers(c_files, includes, include_dirs)
|
includes = get_sorted_headers(c_files, includes, include_dirs)
|
||||||
@@ -898,10 +923,10 @@ def run_scan(proj_path, makefile_path, output_xml, verbose=2):
|
|||||||
if not os.path.isfile(makefile_path):
|
if not os.path.isfile(makefile_path):
|
||||||
raise FileNotFoundError(f"Makefile path '{makefile_path}' does not exist.")
|
raise FileNotFoundError(f"Makefile path '{makefile_path}' does not exist.")
|
||||||
|
|
||||||
c_files, h_files, include_dirs = parse_makefile(makefile_path, proj_path)
|
c_files, h_files, include_dirs, global_defs = parse_project(makefile_path, proj_path)
|
||||||
|
|
||||||
vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs)
|
vars, includes, externs = analyze_variables_across_files(c_files, h_files, include_dirs, global_defs)
|
||||||
typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs)
|
typedefs, structs = analyze_typedefs_and_structs_across_files(c_files, include_dirs, global_defs)
|
||||||
|
|
||||||
vars = dict(sorted(vars.items()))
|
vars = dict(sorted(vars.items()))
|
||||||
includes = get_sorted_headers(c_files, includes, include_dirs)
|
includes = get_sorted_headers(c_files, includes, include_dirs)
|
||||||
504
Src/tms_debugvar_lowlevel.py
Normal file
504
Src/tms_debugvar_lowlevel.py
Normal file
@@ -0,0 +1,504 @@
|
|||||||
|
"""
|
||||||
|
LowLevelSelectorWidget (refactored)
|
||||||
|
-----------------------------------
|
||||||
|
Версия, использующая VariableTableWidget вместо самодельной таблицы selected_vars_table.
|
||||||
|
|
||||||
|
Ключевые изменения:
|
||||||
|
* Вместо QTableWidget с 6 колонками теперь встраивается VariableTableWidget (8 колонок: №, En, Name, Origin Type, Base Type, IQ Type, Return Type, Short Name).
|
||||||
|
* Логика sync <-> self._all_available_vars перенесена в _on_var_table_changed() и _pull_from_var_table().
|
||||||
|
* Поддержка политики хранения типов:
|
||||||
|
- ptr_type: строковое имя (без префикса `pt_`).
|
||||||
|
- ptr_type_enum: числовой индекс (см. PT_ENUM_ORDER).
|
||||||
|
- Для совместимости с VariableTableWidget: поле `pt_type` = 'pt_<name>'.
|
||||||
|
- IQ / Return: аналогично (`iq_type` / `iq_type_enum`, `return_type` / `return_type_enum`).
|
||||||
|
* Функции получения выбранных переменных теперь читают данные из VariableTableWidget.
|
||||||
|
* Убраны неиспользуемые методы, связанные с прежней таблицей (комбо‑боксы и т.п.).
|
||||||
|
|
||||||
|
Как интегрировать:
|
||||||
|
1. Поместите этот файл рядом с module VariableTableWidget (см. импорт ниже). Если класс VariableTableWidget находится в том же файле — удалите строку импорта и используйте напрямую.
|
||||||
|
2. Убедитесь, что VariablesXML предоставляет методы get_all_vars_data() (list[dict]) и, при наличии, get_struct_map() -> dict[type_name -> dict[field_name -> field_type]]. Если такого метода нет, передаём пустой {} и автодополнение по структурам будет недоступно.
|
||||||
|
3. Отметьте переменные в VariableSelectorDialog (как и раньше) — он обновит self._all_available_vars. После закрытия диалога вызывается self._populate_var_table().
|
||||||
|
4. Для чтения выбранных переменных используйте get_selected_variables_and_addresses(); она вернёт список словарей в унифицированном формате.
|
||||||
|
|
||||||
|
Примечание о совместимости: VariableTableWidget работает с ключами `pt_type`, `iq_type`, `return_type` (строки с префиксами). Мы поддерживаем дублирование этих полей с «новыми» полями без префикса и enum‑значениями.
|
||||||
|
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
import datetime
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import List, Dict, Optional, Tuple, Any
|
||||||
|
|
||||||
|
from PySide2 import QtCore, QtGui
|
||||||
|
from PySide2.QtWidgets import (
|
||||||
|
QWidget, QVBoxLayout, QPushButton, QLabel, QHBoxLayout, QFileDialog, QMessageBox,
|
||||||
|
QMainWindow, QApplication, QSizePolicy, QSpinBox, QGroupBox, QSplitter, QFormLayout
|
||||||
|
)
|
||||||
|
|
||||||
|
# Локальные импорты
|
||||||
|
from path_hints import PathHints
|
||||||
|
from generate_debug_vars import choose_type_map, type_map
|
||||||
|
from var_selector_window import VariableSelectorDialog
|
||||||
|
from allvars_xml_parser import VariablesXML
|
||||||
|
|
||||||
|
# Импортируем готовую таблицу
|
||||||
|
# ЗАМЕТКА: замените на реальное имя файла/модуля, если отличается.
|
||||||
|
from var_table import VariableTableWidget, rows as VT_ROWS # noqa: F401
|
||||||
|
|
||||||
|
# ------------------------------------------------------------ Enumerations --
|
||||||
|
# Порядок фиксируем на основании предыдущей версии. При необходимости расширьте.
|
||||||
|
PT_ENUM_ORDER = [
|
||||||
|
'unknown','int8','int16','int32','int64',
|
||||||
|
'uint8','uint16','uint32','uint64','float',
|
||||||
|
'struct','union'
|
||||||
|
]
|
||||||
|
|
||||||
|
IQ_ENUM_ORDER = [
|
||||||
|
'iq_none','iq','iq1','iq2','iq3','iq4','iq5','iq6',
|
||||||
|
'iq7','iq8','iq9','iq10','iq11','iq12','iq13','iq14',
|
||||||
|
'iq15','iq16','iq17','iq18','iq19','iq20','iq21','iq22',
|
||||||
|
'iq23','iq24','iq25','iq26','iq27','iq28','iq29','iq30'
|
||||||
|
]
|
||||||
|
|
||||||
|
PT_ENUM_VALUE: Dict[str, int] = {name: idx for idx, name in enumerate(PT_ENUM_ORDER)}
|
||||||
|
IQ_ENUM_VALUE: Dict[str, int] = {name: idx for idx, name in enumerate(IQ_ENUM_ORDER)}
|
||||||
|
PT_ENUM_NAME_FROM_VAL: Dict[int, str] = {v: k for k, v in PT_ENUM_VALUE.items()}
|
||||||
|
IQ_ENUM_NAME_FROM_VAL: Dict[int, str] = {v: k for k, v in IQ_ENUM_VALUE.items()}
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------- Address / validation helpers --
|
||||||
|
HEX_ADDR_MASK = QtCore.QRegExp(r"0x[0-9A-Fa-f]{0,6}")
|
||||||
|
class HexAddrValidator(QtGui.QRegExpValidator):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(HEX_ADDR_MASK, parent)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def normalize(text: str) -> str:
|
||||||
|
if not text:
|
||||||
|
return '0x000000'
|
||||||
|
try:
|
||||||
|
val = int(text,16)
|
||||||
|
except ValueError:
|
||||||
|
return '0x000000'
|
||||||
|
return f"0x{val & 0xFFFFFF:06X}"
|
||||||
|
|
||||||
|
|
||||||
|
class LowLevelSelectorWidget(QWidget):
|
||||||
|
variablePrepared = QtCore.Signal(dict)
|
||||||
|
xmlLoaded = QtCore.Signal(str)
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle('LowLevel Variable Selector')
|
||||||
|
self._xml: Optional[VariablesXML] = None
|
||||||
|
self._paths: List[str] = []
|
||||||
|
self._path_info: Dict[str, Tuple[int, str]] = {}
|
||||||
|
self._addr_index: Dict[int, Optional[str]] = {}
|
||||||
|
self._hints = PathHints()
|
||||||
|
self._all_available_vars: List[Dict[str, Any]] = []
|
||||||
|
self.dt = None
|
||||||
|
self.flat_vars = None
|
||||||
|
|
||||||
|
# --- NEW ---
|
||||||
|
self.btn_read_once = QPushButton("Read Once")
|
||||||
|
self.btn_start_polling = QPushButton("Start Polling")
|
||||||
|
self.spin_interval = QSpinBox()
|
||||||
|
self.spin_interval.setRange(50, 10000)
|
||||||
|
self.spin_interval.setValue(500)
|
||||||
|
self.spin_interval.setSuffix(" ms")
|
||||||
|
|
||||||
|
self._build_ui()
|
||||||
|
self._connect()
|
||||||
|
|
||||||
|
def _build_ui(self):
|
||||||
|
tab = QWidget()
|
||||||
|
main_layout = QVBoxLayout(tab)
|
||||||
|
|
||||||
|
# --- Variable Selector ---
|
||||||
|
g_selector = QGroupBox("Variable Selector")
|
||||||
|
selector_layout = QVBoxLayout(g_selector)
|
||||||
|
|
||||||
|
form_selector = QFormLayout()
|
||||||
|
|
||||||
|
# --- XML File chooser ---
|
||||||
|
file_layout = QHBoxLayout()
|
||||||
|
self.btn_load = QPushButton('Load XML...')
|
||||||
|
self.lbl_file = QLabel('<no file>')
|
||||||
|
self.lbl_file.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
|
||||||
|
file_layout.addWidget(self.btn_load)
|
||||||
|
file_layout.addWidget(self.lbl_file, 1)
|
||||||
|
form_selector.addRow("XML File:", file_layout)
|
||||||
|
|
||||||
|
# --- Interval SpinBox ---
|
||||||
|
self.spin_interval = QSpinBox()
|
||||||
|
self.spin_interval.setRange(50, 10000)
|
||||||
|
self.spin_interval.setValue(500)
|
||||||
|
self.spin_interval.setSuffix(" ms")
|
||||||
|
form_selector.addRow("Interval:", self.spin_interval)
|
||||||
|
|
||||||
|
selector_layout.addLayout(form_selector)
|
||||||
|
|
||||||
|
# --- Buttons ---
|
||||||
|
self.btn_read_once = QPushButton("Read Once")
|
||||||
|
self.btn_start_polling = QPushButton("Start Polling")
|
||||||
|
btn_layout = QHBoxLayout()
|
||||||
|
btn_layout.addWidget(self.btn_read_once)
|
||||||
|
btn_layout.addWidget(self.btn_start_polling)
|
||||||
|
selector_layout.addLayout(btn_layout)
|
||||||
|
|
||||||
|
# --- Table ---
|
||||||
|
g_table = QGroupBox("Table")
|
||||||
|
table_layout = QVBoxLayout(g_table)
|
||||||
|
self.btn_open_var_selector = QPushButton("Выбрать переменные...")
|
||||||
|
table_layout.addWidget(self.btn_open_var_selector)
|
||||||
|
self.var_table = VariableTableWidget(self, show_value_instead_of_shortname=1)
|
||||||
|
self.var_table.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
table_layout.addWidget(self.var_table)
|
||||||
|
|
||||||
|
# --- Timestamp (moved here) ---
|
||||||
|
self.lbl_timestamp = QLabel('Timestamp: -')
|
||||||
|
table_layout.addWidget(self.lbl_timestamp)
|
||||||
|
|
||||||
|
# --- Splitter (Selector + Table) ---
|
||||||
|
v_split = QSplitter(QtCore.Qt.Vertical)
|
||||||
|
v_split.addWidget(g_selector)
|
||||||
|
v_split.addWidget(g_table)
|
||||||
|
v_split.setStretchFactor(0, 1)
|
||||||
|
v_split.setStretchFactor(1, 3)
|
||||||
|
|
||||||
|
main_layout.addWidget(v_split)
|
||||||
|
self.setLayout(main_layout)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _connect(self):
|
||||||
|
self.btn_load.clicked.connect(self._on_load_xml)
|
||||||
|
self.btn_open_var_selector.clicked.connect(self._on_open_variable_selector)
|
||||||
|
|
||||||
|
# ------------------------------------------------------ XML loading ----
|
||||||
|
def _on_load_xml(self):
|
||||||
|
path, _ = QFileDialog.getOpenFileName(
|
||||||
|
self, 'Select variables XML', '', 'XML Files (*.xml);;All Files (*)')
|
||||||
|
if not path:
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
self._xml = VariablesXML(path)
|
||||||
|
self.flat_vars = {v['name']: v for v in self._xml.flattened()}
|
||||||
|
# Получаем сырые данные по переменным
|
||||||
|
self._all_available_vars = self._xml.get_all_vars_data()
|
||||||
|
except Exception as e:
|
||||||
|
QMessageBox.critical(self, 'Parse error', f'Ошибка парсинга:\n{e}')
|
||||||
|
return
|
||||||
|
|
||||||
|
self.lbl_file.setText(path)
|
||||||
|
self.lbl_timestamp.setText(f'Timestamp: {self._xml.timestamp or "-"}')
|
||||||
|
|
||||||
|
self._populate_internal_maps_from_all_vars()
|
||||||
|
self._apply_timestamp_to_date()
|
||||||
|
self.xmlLoaded.emit(path)
|
||||||
|
self._log(f'Loaded {path}, variables={len(self._all_available_vars)})')
|
||||||
|
|
||||||
|
|
||||||
|
def _apply_timestamp_to_date(self):
|
||||||
|
if not (self._xml and self._xml.timestamp):
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
# Пример: "Sat Jul 19 15:27:59 2025"
|
||||||
|
self.dt = datetime.datetime.strptime(self._xml.timestamp, "%a %b %d %H:%M:%S %Y")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Ошибка разбора timestamp '{self._xml.timestamp}': {e}")
|
||||||
|
|
||||||
|
# ------------------------------------------ Variable selector dialog ----
|
||||||
|
def _on_open_variable_selector(self):
|
||||||
|
if not self._xml:
|
||||||
|
QMessageBox.warning(self, 'No XML', 'Сначала загрузите XML файл.')
|
||||||
|
return
|
||||||
|
|
||||||
|
dialog = VariableSelectorDialog(
|
||||||
|
table=None, # не используем встроенную таблицу
|
||||||
|
all_vars=self._all_available_vars,
|
||||||
|
structs=None, # при необходимости подайте реальные структуры из XML
|
||||||
|
typedefs=None, # ...
|
||||||
|
xml_path=None, # по запросу пользователя xml_path = None
|
||||||
|
parent=self
|
||||||
|
)
|
||||||
|
if dialog.exec_() == dialog.Accepted:
|
||||||
|
# Диалог обновил self._all_available_vars напрямую
|
||||||
|
self._populate_internal_maps_from_all_vars()
|
||||||
|
self._populate_var_table()
|
||||||
|
self._log("Variable selection updated.")
|
||||||
|
|
||||||
|
# ----------------------------------------------------- Populate table ----
|
||||||
|
def _populate_var_table(self):
|
||||||
|
"""Отобразить переменные (show_var == 'true') в VariableTableWidget."""
|
||||||
|
if not self._all_available_vars:
|
||||||
|
self.var_table.setRowCount(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Нормализуем все записи перед передачей таблице.
|
||||||
|
for var in self._all_available_vars:
|
||||||
|
self._normalize_var_record(var)
|
||||||
|
|
||||||
|
# Карта структур для автодополнения (если VariablesXML предоставляет)
|
||||||
|
try:
|
||||||
|
structs_map = self._xml.get_struct_map() if self._xml else {}
|
||||||
|
except AttributeError:
|
||||||
|
structs_map = {}
|
||||||
|
|
||||||
|
# populate() принимает: (vars_list, structs, on_change_callback)
|
||||||
|
self.var_table.populate(self._all_available_vars, structs_map, self._on_var_table_changed)
|
||||||
|
|
||||||
|
# -------------------------------------------------- Table change slot ----
|
||||||
|
def _on_var_table_changed(self, *args, **kwargs): # noqa: D401 (неиспользуемые)
|
||||||
|
"""Вызывается при любом изменении в VariableTableWidget.
|
||||||
|
|
||||||
|
Читаем данные из таблицы, мержим в self._all_available_vars (по имени),
|
||||||
|
пересобираем служебные индексы.
|
||||||
|
"""
|
||||||
|
updated = self.var_table.read_data() # list[dict]
|
||||||
|
|
||||||
|
# создаём индекс по имени из master списка
|
||||||
|
idx_by_name = {v.get('name'): v for v in self._all_available_vars if v.get('name')}
|
||||||
|
|
||||||
|
for rec in updated:
|
||||||
|
nm = rec.get('name')
|
||||||
|
if not nm:
|
||||||
|
continue
|
||||||
|
dst = idx_by_name.get(nm)
|
||||||
|
if not dst:
|
||||||
|
# Новая запись; добавляем базовые поля
|
||||||
|
dst = {
|
||||||
|
'name': nm,
|
||||||
|
'address': 0,
|
||||||
|
'file': '', 'extern': 'false', 'static': 'false',
|
||||||
|
}
|
||||||
|
self._all_available_vars.append(dst)
|
||||||
|
idx_by_name[nm] = dst
|
||||||
|
|
||||||
|
# перенести видимые поля
|
||||||
|
dst['show_var'] = str(bool(rec.get('show_var'))).lower()
|
||||||
|
dst['enable'] = str(bool(rec.get('enable'))).lower()
|
||||||
|
dst['shortname']= rec.get('shortname', nm)
|
||||||
|
dst['type'] = rec.get('type', dst.get('type',''))
|
||||||
|
|
||||||
|
# типы (строковые, с префиксами) -> нормализуем
|
||||||
|
pt_pref = rec.get('pt_type','pt_unknown') # 'pt_int16'
|
||||||
|
iq_pref = rec.get('iq_type','t_iq_none') # 't_iq10' etc.
|
||||||
|
rt_pref = rec.get('return_type', iq_pref)
|
||||||
|
|
||||||
|
self._assign_types_from_prefixed(dst, pt_pref, iq_pref, rt_pref)
|
||||||
|
|
||||||
|
# Пересобрать карты путей/адресов
|
||||||
|
self._populate_internal_maps_from_all_vars()
|
||||||
|
|
||||||
|
# --------------------------------- Normalize var record (public-ish) ----
|
||||||
|
def _normalize_var_record(self, var: Dict[str, Any]):
|
||||||
|
"""Унифицирует записи переменной.
|
||||||
|
|
||||||
|
Требуемые поля после нормализации:
|
||||||
|
var['ptr_type'] -> str (напр. 'int16')
|
||||||
|
var['ptr_type_enum'] -> int
|
||||||
|
var['iq_type'] -> str ('iq10')
|
||||||
|
var['iq_type_enum'] -> int
|
||||||
|
var['return_type'] -> str ('iq10')
|
||||||
|
var['return_type_enum']-> int
|
||||||
|
var['pt_type'] -> 'pt_<ptr_type>' (для совместимости с VariableTableWidget)
|
||||||
|
var['return_type_pref']-> 't_<return_type>' (см. ниже) # не обяз.
|
||||||
|
|
||||||
|
Дополнительно корректируем show_var/enable и адрес.
|
||||||
|
"""
|
||||||
|
# --- show_var / enable
|
||||||
|
var['show_var'] = str(var.get('show_var', 'false')).lower()
|
||||||
|
var['enable'] = str(var.get('enable', 'true')).lower()
|
||||||
|
|
||||||
|
# --- address
|
||||||
|
if not var.get('address'):
|
||||||
|
var_name = var.get('name')
|
||||||
|
# Ищем в self.flat_vars
|
||||||
|
if hasattr(self, 'flat_vars') and isinstance(self.flat_vars, dict):
|
||||||
|
flat_entry = self.flat_vars.get(var_name)
|
||||||
|
if flat_entry and 'address' in flat_entry:
|
||||||
|
var['address'] = flat_entry['address']
|
||||||
|
else:
|
||||||
|
var['address'] = 0
|
||||||
|
else:
|
||||||
|
var['address'] = 0
|
||||||
|
else:
|
||||||
|
# Нормализация адреса (если строка типа '0x1234')
|
||||||
|
try:
|
||||||
|
if isinstance(var['address'], str):
|
||||||
|
var['address'] = int(var['address'], 16)
|
||||||
|
except ValueError:
|
||||||
|
var['address'] = 0
|
||||||
|
|
||||||
|
|
||||||
|
# --- ptr_type (строка)
|
||||||
|
name = None
|
||||||
|
if isinstance(var.get('ptr_type'), str):
|
||||||
|
name = var['ptr_type']
|
||||||
|
elif isinstance(var.get('ptr_type_name'), str):
|
||||||
|
name = var['ptr_type_name']
|
||||||
|
elif isinstance(var.get('pt_type'), str) and 'pt_' in var.get('pt_type'):
|
||||||
|
name = var['pt_type'].replace('pt_','')
|
||||||
|
elif isinstance(var.get('ptr_type'), int):
|
||||||
|
name = PT_ENUM_NAME_FROM_VAL.get(var['ptr_type'], 'unknown')
|
||||||
|
else:
|
||||||
|
name = self._map_type_to_ptr_enum(var.get('type'))
|
||||||
|
val = PT_ENUM_VALUE.get(name, 0)
|
||||||
|
var['ptr_type'] = name
|
||||||
|
var['ptr_type_enum'] = val
|
||||||
|
var['pt_type'] = f'pt_{name}'
|
||||||
|
|
||||||
|
# ---------------------------------------------- prefixed assign helper ----
|
||||||
|
def _assign_types_from_prefixed(self, dst: Dict[str, Any], pt_pref: str, iq_pref: str, rt_pref: str):
|
||||||
|
"""Парсит строки вида 'pt_int16', 't_iq10' и записывает нормализованные поля."""
|
||||||
|
pt_name = pt_pref.replace('pt_','') if pt_pref else 'unknown'
|
||||||
|
iq_name = iq_pref
|
||||||
|
if iq_name.startswith('t_'):
|
||||||
|
iq_name = iq_name[2:]
|
||||||
|
rt_name = rt_pref
|
||||||
|
if rt_name.startswith('t_'):
|
||||||
|
rt_name = rt_name[2:]
|
||||||
|
|
||||||
|
dst['ptr_type'] = pt_name
|
||||||
|
dst['ptr_type_enum'] = PT_ENUM_VALUE.get(pt_name, 0)
|
||||||
|
dst['pt_type'] = f'pt_{pt_name}'
|
||||||
|
|
||||||
|
dst['iq_type'] = iq_name
|
||||||
|
dst['iq_type_enum'] = IQ_ENUM_VALUE.get(iq_name, 0)
|
||||||
|
|
||||||
|
dst['return_type'] = rt_name
|
||||||
|
dst['return_type_enum'] = IQ_ENUM_VALUE.get(rt_name, dst['iq_type_enum'])
|
||||||
|
dst['return_type_pref'] = f't_{rt_name}'
|
||||||
|
|
||||||
|
# ------------------------------------------ Populate internal maps ----
|
||||||
|
def _populate_internal_maps_from_all_vars(self):
|
||||||
|
self._path_info.clear()
|
||||||
|
self._addr_index.clear()
|
||||||
|
self._paths.clear()
|
||||||
|
|
||||||
|
for var in self._all_available_vars:
|
||||||
|
nm = var.get('name')
|
||||||
|
tp = var.get('type')
|
||||||
|
addr = var.get('address')
|
||||||
|
if nm is None:
|
||||||
|
continue
|
||||||
|
if addr is None:
|
||||||
|
addr = 0
|
||||||
|
var['address'] = 0
|
||||||
|
self._paths.append(nm)
|
||||||
|
self._path_info[nm] = (addr, tp)
|
||||||
|
if addr in self._addr_index:
|
||||||
|
self._addr_index[addr] = None
|
||||||
|
else:
|
||||||
|
self._addr_index[addr] = nm
|
||||||
|
|
||||||
|
# Обновим подсказки
|
||||||
|
self._hints.set_paths([(p, self._path_info[p][1]) for p in self._paths])
|
||||||
|
|
||||||
|
# -------------------------------------------------- Public helpers ----
|
||||||
|
def get_selected_variables_and_addresses(self) -> List[Dict[str, Any]]:
|
||||||
|
"""Возвращает список выбранных переменных (show_var == true) с адресами и типами.
|
||||||
|
|
||||||
|
Чтение из VariableTableWidget + подстановка адресов/прочих служебных полей
|
||||||
|
из master списка.
|
||||||
|
"""
|
||||||
|
tbl_data = self.var_table.read_data() # список dict'ов в формате VariableTableWidget
|
||||||
|
idx_by_name = {v.get('name'): v for v in self._all_available_vars if v.get('name')}
|
||||||
|
|
||||||
|
out: List[Dict[str, Any]] = []
|
||||||
|
for rec in tbl_data:
|
||||||
|
nm = rec.get('name')
|
||||||
|
if not nm:
|
||||||
|
continue
|
||||||
|
src = idx_by_name.get(nm, {})
|
||||||
|
addr = src.get('address')
|
||||||
|
if addr is None or addr == '' or addr == 0:
|
||||||
|
src['address'] = self.flat_vars.get(nm, {}).get('address', 0)
|
||||||
|
else:
|
||||||
|
# если это строка "0x..." — конвертируем в int
|
||||||
|
if isinstance(addr, str) and addr.startswith('0x'):
|
||||||
|
try:
|
||||||
|
src['address'] = int(addr, 16)
|
||||||
|
except ValueError:
|
||||||
|
src['address'] = self.flat_vars.get(nm, {}).get('address', 0)
|
||||||
|
type_str = src.get('type', rec.get('type','N/A'))
|
||||||
|
|
||||||
|
# нормализация типов
|
||||||
|
tmp = dict(src) # copy src to preserve extra fields (file, extern, ...)
|
||||||
|
self._assign_types_from_prefixed(tmp,
|
||||||
|
rec.get('pt_type','pt_unknown'),
|
||||||
|
rec.get('iq_type','t_iq_none'),
|
||||||
|
rec.get('return_type', rec.get('iq_type','t_iq_none')))
|
||||||
|
tmp['show_var'] = str(bool(rec.get('show_var'))).lower()
|
||||||
|
tmp['enable'] = str(bool(rec.get('enable'))).lower()
|
||||||
|
tmp['name'] = nm
|
||||||
|
tmp['address'] = addr
|
||||||
|
tmp['type'] = type_str
|
||||||
|
out.append(tmp)
|
||||||
|
return out
|
||||||
|
|
||||||
|
def get_datetime(self):
|
||||||
|
return self.dt
|
||||||
|
|
||||||
|
def set_variable_value(self, var_name: str, value: Any):
|
||||||
|
# 1. Обновляем master-список переменных
|
||||||
|
found = None
|
||||||
|
for var in self._all_available_vars:
|
||||||
|
if var.get('name') == var_name:
|
||||||
|
var['value'] = value
|
||||||
|
found = var
|
||||||
|
break
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
# Если переменной нет в списке, можно либо проигнорировать, либо добавить.
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 2. Обновляем отображение в таблице
|
||||||
|
#self.var_table.populate(self._all_available_vars, {}, self._on_var_table_changed)
|
||||||
|
return True
|
||||||
|
|
||||||
|
# --------------- Address mapping / type mapping helpers ---------------
|
||||||
|
|
||||||
|
|
||||||
|
def _map_type_to_ptr_enum(self, type_str: Optional[str]) -> str:
|
||||||
|
if not type_str:
|
||||||
|
return 'unknown'
|
||||||
|
low = type_str.lower()
|
||||||
|
token = low.replace('*',' ').replace('[',' ')
|
||||||
|
return type_map.get(token, 'unknown').replace('pt_','')
|
||||||
|
|
||||||
|
# ----------------------------------------------------------- Logging --
|
||||||
|
def _log(self, msg: str):
|
||||||
|
print(f"[LowLevelSelectorWidget Log] {msg}")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Тест‑прогоночка (ручной) --------------------------------------------------
|
||||||
|
# Запускать только вручную: python LowLevelSelectorWidget_refactored.py <xml>
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------- Demo window --
|
||||||
|
class _DemoWindow(QMainWindow):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.setWindowTitle('LowLevel Selector Demo')
|
||||||
|
self.selector = LowLevelSelectorWidget(self)
|
||||||
|
self.setCentralWidget(self.selector)
|
||||||
|
self.selector.variablePrepared.connect(self.on_var)
|
||||||
|
|
||||||
|
def on_var(self, data: dict):
|
||||||
|
print('Variable prepared ->', data)
|
||||||
|
|
||||||
|
def closeEvent(self, ev):
|
||||||
|
self.setCentralWidget(None)
|
||||||
|
super().closeEvent(ev)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------- main ---
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
w = _DemoWindow()
|
||||||
|
w.resize(640, 520)
|
||||||
|
w.show()
|
||||||
|
sys.exit(app.exec_())
|
||||||
1268
Src/tms_debugvar_term.py
Normal file
1268
Src/tms_debugvar_term.py
Normal file
@@ -0,0 +1,1268 @@
|
|||||||
|
from PySide2 import QtCore, QtWidgets, QtSerialPort, QtGui
|
||||||
|
from tms_debugvar_lowlevel import LowLevelSelectorWidget
|
||||||
|
import datetime
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
from csv_logger import CsvLogger
|
||||||
|
# ------------------------------- Константы протокола ------------------------
|
||||||
|
WATCH_SERVICE_BIT = 0x8000
|
||||||
|
DEBUG_OK = 0 # ожидаемый код успешного чтения
|
||||||
|
SIGN_BIT_MASK = 0x80
|
||||||
|
FRAC_MASK_FULL = 0x7F # если используем 7 бит дробной части
|
||||||
|
|
||||||
|
# --- Debug status codes (из прошивки) ---
|
||||||
|
DEBUG_OK = 0x00
|
||||||
|
DEBUG_ERR = 0x80 # общий флаг ошибки (старший бит)
|
||||||
|
|
||||||
|
DEBUG_ERR_VAR_NUMB = DEBUG_ERR | (1 << 0)
|
||||||
|
DEBUG_ERR_INVALID_VAR = DEBUG_ERR | (1 << 1)
|
||||||
|
DEBUG_ERR_ADDR = DEBUG_ERR | (1 << 2)
|
||||||
|
DEBUG_ERR_ADDR_ALIGN = DEBUG_ERR | (1 << 3)
|
||||||
|
DEBUG_ERR_INTERNAL = DEBUG_ERR | (1 << 4)
|
||||||
|
DEBUG_ERR_DATATIME = DEBUG_ERR | (1 << 5)
|
||||||
|
DEBUG_ERR_RS = DEBUG_ERR | (1 << 5)
|
||||||
|
|
||||||
|
# для декодирования по битам
|
||||||
|
_DEBUG_ERR_BITS = (
|
||||||
|
(1 << 0, "Invalid Variable Index"),
|
||||||
|
(1 << 1, "Invalid Variable"),
|
||||||
|
(1 << 2, "Invalid Address"),
|
||||||
|
(1 << 3, "Invalid Address Align"),
|
||||||
|
(1 << 4, "Internal Code Error"),
|
||||||
|
(1 << 5, "Invalid Data or Time"),
|
||||||
|
(1 << 6, "Error with RS"),
|
||||||
|
)
|
||||||
|
# ---------------------------------------------------------------- CRC util ---
|
||||||
|
def crc16_ibm(data: bytes, *, init=0xFFFF) -> int:
|
||||||
|
"""CRC16-IBM (aka CRC-16/ANSI, polynomial 0xA001 reflected)."""
|
||||||
|
crc = init
|
||||||
|
for b in data:
|
||||||
|
crc ^= b
|
||||||
|
for _ in range(8):
|
||||||
|
if crc & 1:
|
||||||
|
crc = (crc >> 1) ^ 0xA001
|
||||||
|
else:
|
||||||
|
crc >>= 1
|
||||||
|
return crc & 0xFFFF
|
||||||
|
|
||||||
|
def is_frozen():
|
||||||
|
# Для Nuitka --onefile
|
||||||
|
return getattr(sys, 'frozen', False)
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_path():
|
||||||
|
if is_frozen():
|
||||||
|
# В Nuitka onefile распаковывается в папку с самим exe во временной директории
|
||||||
|
return os.path.dirname(sys.executable)
|
||||||
|
else:
|
||||||
|
# Режим разработки
|
||||||
|
return os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
def _decode_debug_status(status: int) -> str:
|
||||||
|
"""Преобразует код статуса прошивки в строку.
|
||||||
|
Возвращает 'OK' или перечисление битов через '|'.
|
||||||
|
Не зависит от того, WATCH или LowLevel.
|
||||||
|
"""
|
||||||
|
if status == DEBUG_OK:
|
||||||
|
return "OK"
|
||||||
|
parts = []
|
||||||
|
if status & DEBUG_ERR:
|
||||||
|
for mask, name in _DEBUG_ERR_BITS:
|
||||||
|
if status & mask:
|
||||||
|
parts.append(name)
|
||||||
|
if not parts: # старший бит есть, но ни один из известных младших не выставлен
|
||||||
|
parts.append("ERR")
|
||||||
|
else:
|
||||||
|
# Неожиданно: статус !=0, но бит DEBUG_ERR не стоит
|
||||||
|
parts.append(f"0x{status:02X}")
|
||||||
|
return "|".join(parts)
|
||||||
|
|
||||||
|
|
||||||
|
class Spoiler(QtWidgets.QWidget):
|
||||||
|
def __init__(self, title="", animationDuration=300, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self._animationDuration = animationDuration
|
||||||
|
self.state = False
|
||||||
|
|
||||||
|
# --- Toggle button ---
|
||||||
|
self.toggleButton = QtWidgets.QToolButton(self)
|
||||||
|
self.toggleButton.setStyleSheet("QToolButton { border: none; }")
|
||||||
|
self.toggleButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
|
||||||
|
self.toggleButton.setArrowType(QtCore.Qt.RightArrow)
|
||||||
|
self.toggleButton.setText(title)
|
||||||
|
self.toggleButton.setCheckable(True)
|
||||||
|
|
||||||
|
# --- Header line ---
|
||||||
|
self.headerLine = QtWidgets.QFrame(self)
|
||||||
|
self.headerLine.setFrameShape(QtWidgets.QFrame.HLine)
|
||||||
|
self.headerLine.setFrameShadow(QtWidgets.QFrame.Sunken)
|
||||||
|
|
||||||
|
# --- Content area ---
|
||||||
|
self.contentArea = QtWidgets.QScrollArea(self)
|
||||||
|
self.contentArea.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
||||||
|
self.contentArea.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||||
|
self.contentArea.setWidgetResizable(True)
|
||||||
|
self._contentWidget = QtWidgets.QWidget()
|
||||||
|
self.contentArea.setWidget(self._contentWidget)
|
||||||
|
self.contentArea.setMaximumHeight(0)
|
||||||
|
|
||||||
|
# --- Анимация только по контенту ---
|
||||||
|
self._ani_content = QtCore.QPropertyAnimation(self.contentArea, b"maximumHeight")
|
||||||
|
self._ani_content.setDuration(animationDuration)
|
||||||
|
self._ani_content.setEasingCurve(QtCore.QEasingCurve.InOutCubic)
|
||||||
|
|
||||||
|
# --- Layout ---
|
||||||
|
self.mainLayout = QtWidgets.QGridLayout(self)
|
||||||
|
self.mainLayout.setVerticalSpacing(0)
|
||||||
|
self.mainLayout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.mainLayout.addWidget(self.toggleButton, 0, 0, 1, 1)
|
||||||
|
self.mainLayout.addWidget(self.headerLine, 0, 1, 1, 1)
|
||||||
|
self.mainLayout.addWidget(self.contentArea, 1, 0, 1, 2)
|
||||||
|
|
||||||
|
# --- Signals ---
|
||||||
|
self.toggleButton.clicked.connect(self._on_toggled)
|
||||||
|
|
||||||
|
def setContentLayout(self, contentLayout):
|
||||||
|
old = self._contentWidget.layout()
|
||||||
|
if old:
|
||||||
|
QtWidgets.QWidget().setLayout(old)
|
||||||
|
self._contentWidget.setLayout(contentLayout)
|
||||||
|
|
||||||
|
def getState(self):
|
||||||
|
return self.state
|
||||||
|
|
||||||
|
def _on_toggled(self, checked: bool):
|
||||||
|
self.state = checked
|
||||||
|
self.toggleButton.setArrowType(QtCore.Qt.DownArrow if checked else QtCore.Qt.RightArrow)
|
||||||
|
|
||||||
|
contentHeight = self._contentWidget.sizeHint().height()
|
||||||
|
self._ani_content.stop()
|
||||||
|
self._ani_content.setStartValue(self.contentArea.maximumHeight())
|
||||||
|
self._ani_content.setEndValue(contentHeight if checked else 0)
|
||||||
|
self._ani_content.start()
|
||||||
|
|
||||||
|
|
||||||
|
# --------------------------- DebugTerminalWidget ---------------------------
|
||||||
|
class DebugTerminalWidget(QtWidgets.QWidget):
|
||||||
|
# Существующие сигналы (Watch)
|
||||||
|
nameRead = QtCore.Signal(int, int, int, str)
|
||||||
|
valueRead = QtCore.Signal(int, int, int, int, float)
|
||||||
|
valuesRead = QtCore.Signal(int, int, list, list, list, list)
|
||||||
|
# Новые сигналы (LowLevel)
|
||||||
|
llValueRead = QtCore.Signal(int, int, int, int, float) # addr, status, rettype_raw, raw16_signed, scaled
|
||||||
|
|
||||||
|
portOpened = QtCore.Signal(str)
|
||||||
|
portClosed = QtCore.Signal(str)
|
||||||
|
txBytes = QtCore.Signal(bytes)
|
||||||
|
rxBytes = QtCore.Signal(bytes)
|
||||||
|
|
||||||
|
def __init__(self, parent=None, *,
|
||||||
|
start_byte=0x0A,
|
||||||
|
cmd_byte=0x46,
|
||||||
|
cmd_lowlevel=0x47,
|
||||||
|
iq_scaling=None,
|
||||||
|
read_timeout_ms=250,
|
||||||
|
auto_crc_check=True,
|
||||||
|
drop_if_busy=False,
|
||||||
|
replace_if_busy=True):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.device_addr = start_byte
|
||||||
|
self.cmd_byte = cmd_byte
|
||||||
|
self.cmd_lowlevel = cmd_lowlevel
|
||||||
|
self.read_timeout_ms = read_timeout_ms
|
||||||
|
self.auto_crc_check = auto_crc_check
|
||||||
|
self._drop_if_busy = drop_if_busy
|
||||||
|
self._replace_if_busy = replace_if_busy
|
||||||
|
self._last_txn_timestamp = 0
|
||||||
|
self._ll_polling_active = False
|
||||||
|
if iq_scaling is None:
|
||||||
|
iq_scaling = {n: float(1 << n) for n in range(31)}
|
||||||
|
iq_scaling[0] = 1.0
|
||||||
|
self.iq_scaling = iq_scaling
|
||||||
|
|
||||||
|
# Serial
|
||||||
|
self.serial = QtSerialPort.QSerialPort(self)
|
||||||
|
self.serial.setBaudRate(115200)
|
||||||
|
self.serial.readyRead.connect(self._on_ready_read)
|
||||||
|
self.serial.errorOccurred.connect(self._on_serial_error)
|
||||||
|
|
||||||
|
# State
|
||||||
|
self._rx_buf = bytearray()
|
||||||
|
self._busy = False
|
||||||
|
self._pending_cmd = None # (frame, meta)
|
||||||
|
self._txn_meta = None # {'service':bool,'index':int,'varqnt':int,'chain':...,'lowlevel':bool}
|
||||||
|
|
||||||
|
self._txn_timer = QtCore.QTimer(self)
|
||||||
|
self._txn_timer.setSingleShot(True)
|
||||||
|
self._txn_timer.timeout.connect(self._on_txn_timeout)
|
||||||
|
|
||||||
|
# Watch polling
|
||||||
|
self._poll_timer = QtCore.QTimer(self)
|
||||||
|
self._poll_timer.timeout.connect(self._on_poll_timeout)
|
||||||
|
self._polling = False
|
||||||
|
|
||||||
|
# LowLevel polling
|
||||||
|
self._ll_poll_timer = QtCore.QTimer(self)
|
||||||
|
self._ll_poll_timer.timeout.connect(self._on_ll_poll_timeout)
|
||||||
|
self._ll_polling = False
|
||||||
|
self._ll_polling_variables = [] # List of selected variables for polling
|
||||||
|
self._ll_current_poll_index = -1 # Index of the variable currently being polled in the _ll_polling_variables list
|
||||||
|
self._ll_current_var_info = []
|
||||||
|
|
||||||
|
self.csv_logger = CsvLogger()
|
||||||
|
self._csv_logging_active = False
|
||||||
|
self._last_csv_timestamp = 0 # Для отслеживания времени записи
|
||||||
|
|
||||||
|
# Кэш: index -> (status, iq, name, is_signed, frac_bits)
|
||||||
|
self._name_cache = {}
|
||||||
|
|
||||||
|
# Очередь service индексов
|
||||||
|
self._service_queue = []
|
||||||
|
self._pending_data_after_services = None # (base, count)
|
||||||
|
|
||||||
|
self._build_ui()
|
||||||
|
self._connect_ui()
|
||||||
|
self.set_available_ports()
|
||||||
|
|
||||||
|
# ------------------------------ UI ----------------------------------
|
||||||
|
def _build_ui(self):
|
||||||
|
layout = QtWidgets.QVBoxLayout(self)
|
||||||
|
|
||||||
|
# --- Serial group ---
|
||||||
|
g_serial = QtWidgets.QGroupBox("Serial Port")
|
||||||
|
hs = QtWidgets.QHBoxLayout(g_serial)
|
||||||
|
self.cmb_port = QtWidgets.QComboBox()
|
||||||
|
self.btn_refresh = QtWidgets.QPushButton("Refresh")
|
||||||
|
self.cmb_baud = QtWidgets.QComboBox()
|
||||||
|
self.cmb_baud.addItems(["9600","19200","38400","57600","115200","230400"])
|
||||||
|
self.cmb_baud.setCurrentText("115200")
|
||||||
|
self.btn_open = QtWidgets.QPushButton("Open")
|
||||||
|
hs.addWidget(QtWidgets.QLabel("Port:"))
|
||||||
|
hs.addWidget(self.cmb_port, 1)
|
||||||
|
hs.addWidget(self.btn_refresh)
|
||||||
|
hs.addSpacing(10)
|
||||||
|
hs.addWidget(QtWidgets.QLabel("Baud:"))
|
||||||
|
hs.addWidget(self.cmb_baud)
|
||||||
|
hs.addWidget(self.btn_open)
|
||||||
|
|
||||||
|
# --- TabWidget ---
|
||||||
|
self.tabs = QtWidgets.QTabWidget()
|
||||||
|
self._build_watch_tab()
|
||||||
|
self._build_lowlevel_tab() # <-- Вызываем новый метод
|
||||||
|
g_control = QtWidgets.QGroupBox("Control / Status")
|
||||||
|
control_layout = QtWidgets.QHBoxLayout(g_control) # Используем QHBoxLayout
|
||||||
|
|
||||||
|
# Форма для статусов слева
|
||||||
|
form_control = QtWidgets.QFormLayout()
|
||||||
|
self.lbl_status = QtWidgets.QLabel("Idle")
|
||||||
|
self.lbl_status.setStyleSheet("font-weight: bold; color: grey;")
|
||||||
|
form_control.addRow("Status:", self.lbl_status)
|
||||||
|
self.lbl_actual_interval = QtWidgets.QLabel("-")
|
||||||
|
form_control.addRow("Actual Interval:", self.lbl_actual_interval)
|
||||||
|
|
||||||
|
control_layout.addLayout(form_control, 1) # Растягиваем форму
|
||||||
|
|
||||||
|
# Галочка Raw справа
|
||||||
|
self.chk_raw = QtWidgets.QCheckBox("Raw (no IQ scaling)")
|
||||||
|
control_layout.addWidget(self.chk_raw)
|
||||||
|
|
||||||
|
# Создаем QGroupBox для группировки элементов управления CSV
|
||||||
|
self.csv_log_groupbox = QtWidgets.QGroupBox("CSV Logging")
|
||||||
|
csv_log_layout = QtWidgets.QVBoxLayout(self.csv_log_groupbox) # Передаем groupbox как родительский layout
|
||||||
|
|
||||||
|
# Элементы управления CSV
|
||||||
|
h_file_select = QtWidgets.QHBoxLayout()
|
||||||
|
self.btn_select_csv_file = QtWidgets.QPushButton("Выбрать файл CSV")
|
||||||
|
# Убедитесь, что self.csv_logger инициализирован где-то до этого момента
|
||||||
|
self.lbl_csv_filename = QtWidgets.QLabel(self.csv_logger.filename)
|
||||||
|
h_file_select.addWidget(self.btn_select_csv_file)
|
||||||
|
h_file_select.addWidget(self.lbl_csv_filename, 1)
|
||||||
|
csv_log_layout.addLayout(h_file_select)
|
||||||
|
|
||||||
|
h_control_buttons = QtWidgets.QHBoxLayout()
|
||||||
|
self.btn_start_csv_logging = QtWidgets.QPushButton("Начать запись в CSV")
|
||||||
|
self.btn_stop_csv_logging = QtWidgets.QPushButton("Остановить запись в CSV")
|
||||||
|
self.btn_save_csv_data = QtWidgets.QPushButton("Сохранить данные в CSV")
|
||||||
|
|
||||||
|
self.btn_stop_csv_logging.setEnabled(False) # По умолчанию остановлена
|
||||||
|
|
||||||
|
h_control_buttons.addWidget(self.btn_start_csv_logging)
|
||||||
|
h_control_buttons.addWidget(self.btn_stop_csv_logging)
|
||||||
|
h_control_buttons.addWidget(self.btn_save_csv_data)
|
||||||
|
csv_log_layout.addLayout(h_control_buttons)
|
||||||
|
|
||||||
|
# Добавляем QGroupBox в основной лейаут
|
||||||
|
|
||||||
|
# --- UART Log ---
|
||||||
|
self.log_spoiler = Spoiler("UART Log", animationDuration=300, parent=self)
|
||||||
|
self.log_spoiler.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
|
||||||
|
QtWidgets.QSizePolicy.Minimum)
|
||||||
|
log_layout = QtWidgets.QVBoxLayout()
|
||||||
|
self.txt_log = QtWidgets.QTextEdit(); self.txt_log.setReadOnly(True)
|
||||||
|
self.txt_log.setFontFamily("Courier")
|
||||||
|
log_layout.addWidget(self.txt_log)
|
||||||
|
self.log_spoiler.setContentLayout(log_layout)
|
||||||
|
|
||||||
|
layout.addWidget(g_serial)
|
||||||
|
layout.addWidget(self.tabs, 1)
|
||||||
|
layout.addWidget(g_control)
|
||||||
|
layout.addWidget(self.csv_log_groupbox)
|
||||||
|
layout.addWidget(self.log_spoiler)
|
||||||
|
layout.setStretch(layout.indexOf(g_serial), 0)
|
||||||
|
layout.setStretch(layout.indexOf(self.tabs), 1)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_watch_tab(self):
|
||||||
|
tab = QtWidgets.QWidget()
|
||||||
|
main_layout = QtWidgets.QVBoxLayout(tab)
|
||||||
|
|
||||||
|
# --- Variable Selector ---
|
||||||
|
g_selector = QtWidgets.QGroupBox("Variable Selector")
|
||||||
|
selector_layout = QtWidgets.QVBoxLayout(g_selector)
|
||||||
|
|
||||||
|
form_selector = QtWidgets.QFormLayout()
|
||||||
|
h_layout = QtWidgets.QHBoxLayout()
|
||||||
|
|
||||||
|
self.spin_index = QtWidgets.QSpinBox()
|
||||||
|
self.spin_index.setRange(0, 0x7FFF)
|
||||||
|
self.spin_index.setAccelerated(True)
|
||||||
|
|
||||||
|
self.chk_hex_index = QtWidgets.QCheckBox("Hex")
|
||||||
|
|
||||||
|
self.spin_count = QtWidgets.QSpinBox()
|
||||||
|
self.spin_count.setRange(1, 255)
|
||||||
|
self.spin_count.setValue(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Первая группа: Base Index + spin + checkbox
|
||||||
|
base_index_layout = QtWidgets.QHBoxLayout()
|
||||||
|
base_index_label = QtWidgets.QLabel("Base Index")
|
||||||
|
base_index_layout.addWidget(base_index_label)
|
||||||
|
base_index_layout.addWidget(self.spin_index)
|
||||||
|
base_index_layout.addWidget(self.chk_hex_index)
|
||||||
|
base_index_layout.setSpacing(5)
|
||||||
|
|
||||||
|
# Вторая группа: spin_count + метка справа
|
||||||
|
count_layout = QtWidgets.QHBoxLayout()
|
||||||
|
count_layout.setSpacing(2) # минимальный отступ
|
||||||
|
count_layout.addWidget(self.spin_count)
|
||||||
|
count_label = QtWidgets.QLabel("Cnt")
|
||||||
|
count_layout.addWidget(count_label)
|
||||||
|
|
||||||
|
# Добавляем обе группы в общий горизонтальный лэйаут
|
||||||
|
h_layout.addLayout(base_index_layout)
|
||||||
|
h_layout.addSpacing(20)
|
||||||
|
h_layout.addLayout(count_layout)
|
||||||
|
|
||||||
|
form_selector.addRow(h_layout)
|
||||||
|
|
||||||
|
self.spin_interval = QtWidgets.QSpinBox()
|
||||||
|
self.spin_interval.setRange(50, 10000)
|
||||||
|
self.spin_interval.setValue(500)
|
||||||
|
self.spin_interval.setSuffix(" ms")
|
||||||
|
form_selector.addRow("Interval:", self.spin_interval)
|
||||||
|
|
||||||
|
selector_layout.addLayout(form_selector)
|
||||||
|
|
||||||
|
btn_layout = QtWidgets.QHBoxLayout()
|
||||||
|
self.btn_update_service = QtWidgets.QPushButton("Update Service")
|
||||||
|
self.btn_read_values = QtWidgets.QPushButton("Read Value(s)")
|
||||||
|
self.btn_poll = QtWidgets.QPushButton("Start Polling")
|
||||||
|
btn_layout.addWidget(self.btn_update_service)
|
||||||
|
btn_layout.addWidget(self.btn_read_values)
|
||||||
|
btn_layout.addWidget(self.btn_poll)
|
||||||
|
selector_layout.addLayout(btn_layout)
|
||||||
|
|
||||||
|
# --- Table ---
|
||||||
|
g_table = QtWidgets.QGroupBox("Table")
|
||||||
|
table_layout = QtWidgets.QVBoxLayout(g_table)
|
||||||
|
self.tbl_values = QtWidgets.QTableWidget(0, 5)
|
||||||
|
self.tbl_values.setHorizontalHeaderLabels(["Index", "Name", "IQ", "Raw", "Scaled"])
|
||||||
|
hh = self.tbl_values.horizontalHeader()
|
||||||
|
for i in range(4):
|
||||||
|
hh.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents)
|
||||||
|
hh.setSectionResizeMode(4, QtWidgets.QHeaderView.Stretch)
|
||||||
|
self.tbl_values.verticalHeader().setVisible(False)
|
||||||
|
table_layout.addWidget(self.tbl_values)
|
||||||
|
|
||||||
|
# --- Вертикальный сплиттер ---
|
||||||
|
v_split = QtWidgets.QSplitter(QtCore.Qt.Vertical)
|
||||||
|
v_split.addWidget(g_selector)
|
||||||
|
v_split.addWidget(g_table)
|
||||||
|
v_split.setStretchFactor(0, 1)
|
||||||
|
v_split.setStretchFactor(1, 3)
|
||||||
|
v_split.setStretchFactor(2, 1)
|
||||||
|
|
||||||
|
main_layout.addWidget(v_split)
|
||||||
|
self.tabs.addTab(tab, "Watch")
|
||||||
|
|
||||||
|
|
||||||
|
table_layout.addWidget(self.tbl_values)
|
||||||
|
|
||||||
|
|
||||||
|
def _build_lowlevel_tab(self):
|
||||||
|
# создаём виджет LowLevelSelectorWidget
|
||||||
|
self.ll_selector = LowLevelSelectorWidget()
|
||||||
|
# добавляем как корневой виджет вкладки
|
||||||
|
self.tabs.addTab(self.ll_selector, "LowLevel")
|
||||||
|
|
||||||
|
|
||||||
|
def _connect_ui(self):
|
||||||
|
# Watch
|
||||||
|
self.btn_refresh.clicked.connect(self.set_available_ports)
|
||||||
|
self.btn_open.clicked.connect(self._open_close_port)
|
||||||
|
self.btn_update_service.clicked.connect(self.request_service_update_for_table)
|
||||||
|
self.btn_read_values.clicked.connect(self.request_values)
|
||||||
|
self.btn_poll.clicked.connect(self._toggle_polling)
|
||||||
|
self.chk_hex_index.stateChanged.connect(self._toggle_index_base)
|
||||||
|
|
||||||
|
# LowLevel (новые и переделанные)
|
||||||
|
self.ll_selector.xmlLoaded.connect(lambda p: self._log(f"[LL] XML loaded: {p}"))
|
||||||
|
self.ll_selector.btn_read_once.clicked.connect(self._start_ll_cycle)
|
||||||
|
self.ll_selector.btn_start_polling.clicked.connect(self._toggle_ll_polling)
|
||||||
|
|
||||||
|
# --- CSV Logging ---
|
||||||
|
self.btn_select_csv_file.clicked.connect(self._select_csv_file)
|
||||||
|
self.btn_start_csv_logging.clicked.connect(self._start_csv_logging)
|
||||||
|
self.btn_stop_csv_logging.clicked.connect(self._stop_csv_logging)
|
||||||
|
self.btn_save_csv_data.clicked.connect(self._save_csv_data)
|
||||||
|
|
||||||
|
def set_status(self, text: str, mode: str = "idle"):
|
||||||
|
colors = {
|
||||||
|
"idle": "gray",
|
||||||
|
"service": "blue",
|
||||||
|
"values": "green",
|
||||||
|
"error": "red"
|
||||||
|
}
|
||||||
|
color = colors.get(mode.lower(), "black")
|
||||||
|
self.lbl_status.setText(text)
|
||||||
|
self.lbl_status.setStyleSheet(f"font-weight: bold; color: {color};")
|
||||||
|
|
||||||
|
# ----------------------------- SERIAL MGMT ----------------------------
|
||||||
|
def set_available_ports(self):
|
||||||
|
cur = self.cmb_port.currentText()
|
||||||
|
self.cmb_port.blockSignals(True)
|
||||||
|
self.cmb_port.clear()
|
||||||
|
for info in QtSerialPort.QSerialPortInfo.availablePorts():
|
||||||
|
self.cmb_port.addItem(info.portName())
|
||||||
|
if cur:
|
||||||
|
ix = self.cmb_port.findText(cur)
|
||||||
|
if ix >= 0:
|
||||||
|
self.cmb_port.setCurrentIndex(ix)
|
||||||
|
self.cmb_port.blockSignals(False)
|
||||||
|
|
||||||
|
def _open_close_port(self):
|
||||||
|
if self.serial.isOpen():
|
||||||
|
name = self.serial.portName()
|
||||||
|
self.serial.close()
|
||||||
|
self.btn_open.setText("Open")
|
||||||
|
self._log(f"[PORT OK] Closed {name}")
|
||||||
|
self.portClosed.emit(name)
|
||||||
|
return
|
||||||
|
port = self.cmb_port.currentText()
|
||||||
|
if not port:
|
||||||
|
self._log("[ERR] No port selected")
|
||||||
|
return
|
||||||
|
self.serial.setPortName(port)
|
||||||
|
self.serial.setBaudRate(int(self.cmb_baud.currentText()))
|
||||||
|
if not self.serial.open(QtCore.QIODevice.ReadWrite):
|
||||||
|
self._log(f"[ERR] Open fail {port}: {self.serial.errorString()}")
|
||||||
|
return
|
||||||
|
self.btn_open.setText("Close")
|
||||||
|
self._log(f"[PORT OK] Opened {port}")
|
||||||
|
self.portOpened.emit(port)
|
||||||
|
|
||||||
|
# ---------------------------- FRAME BUILD -----------------------------
|
||||||
|
def _build_request(self, index: int, *, service: bool, varqnt: int) -> bytes:
|
||||||
|
dbg = index & 0x7FFF
|
||||||
|
if service:
|
||||||
|
dbg |= WATCH_SERVICE_BIT
|
||||||
|
hi = (dbg >> 8) & 0xFF
|
||||||
|
lo = dbg & 0xFF
|
||||||
|
q = varqnt & 0xFF
|
||||||
|
payload = bytes([self.device_addr & 0xFF, self.cmd_byte & 0xFF, hi, lo, q])
|
||||||
|
crc = crc16_ibm(payload)
|
||||||
|
return payload + bytes([crc & 0xFF, (crc >> 8) & 0xFF])
|
||||||
|
|
||||||
|
def _build_lowlevel_request(self, var_info: dict) -> bytes:
|
||||||
|
# Формат: [adr][cmd_lowlevel][year_hi][year_lo][month][day][hour][minute][addr2][addr1][addr0][pt_type][iq_type][return_type]
|
||||||
|
# Пытаемся получить время из переданной информации
|
||||||
|
dt_info = self.ll_selector.get_datetime()
|
||||||
|
|
||||||
|
if dt_info:
|
||||||
|
# Используем время из var_info
|
||||||
|
year = dt_info.year
|
||||||
|
month = dt_info.month
|
||||||
|
day = dt_info.day
|
||||||
|
hour = dt_info.hour
|
||||||
|
minute = dt_info.minute
|
||||||
|
self._log("[LL] Using time from selector.")
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
addr = var_info.get('address', 0)
|
||||||
|
addr2 = (addr >> 16) & 0xFF
|
||||||
|
addr1 = (addr >> 8) & 0xFF
|
||||||
|
addr0 = addr & 0xFF
|
||||||
|
# Ensure 'ptr_type' and 'iq_type' from var_info are integers (enum values)
|
||||||
|
# Use a fallback to 0 if they are not found or not integers
|
||||||
|
pt_type = var_info.get('ptr_type_enum', 0) & 0xFF
|
||||||
|
iq_type = var_info.get('iq_type_enum', 0) & 0xFF
|
||||||
|
ret_type = var_info.get('return_type_enum', 0) & 0xFF
|
||||||
|
|
||||||
|
|
||||||
|
frame_wo_crc = bytes([
|
||||||
|
self.device_addr & 0xFF, self.cmd_lowlevel & 0xFF,
|
||||||
|
(year >> 8) & 0xFF, year & 0xFF,
|
||||||
|
month & 0xFF, day & 0xFF, hour & 0xFF, minute & 0xFF,
|
||||||
|
addr2, addr1, addr0, pt_type, iq_type, ret_type
|
||||||
|
])
|
||||||
|
crc = crc16_ibm(frame_wo_crc)
|
||||||
|
return frame_wo_crc + bytes([crc & 0xFF, (crc >> 8) & 0xFF])
|
||||||
|
|
||||||
|
# ----------------------------- PUBLIC API -----------------------------
|
||||||
|
def request_service_single(self):
|
||||||
|
idx = int(self.spin_index.value())
|
||||||
|
self._enqueue_or_start(idx, service=True, varqnt=0)
|
||||||
|
|
||||||
|
def request_service_update_for_table(self):
|
||||||
|
"""
|
||||||
|
Очищает кеш имен/типов для всех видимых в таблице переменных
|
||||||
|
и инициирует их повторное чтение.
|
||||||
|
"""
|
||||||
|
indices_to_update = []
|
||||||
|
for row in range(self.tbl_values.rowCount()):
|
||||||
|
item = self.tbl_values.item(row, 0)
|
||||||
|
if item and item.text().isdigit():
|
||||||
|
indices_to_update.append(int(item.text()))
|
||||||
|
|
||||||
|
if not indices_to_update:
|
||||||
|
self._log("[SERVICE] No variables in table to update.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self._log(f"[SERVICE] Queuing name/type update for {len(indices_to_update)} variables.")
|
||||||
|
# Очищаем кеш для этих индексов, чтобы принудительно их перечитать
|
||||||
|
for index in indices_to_update:
|
||||||
|
if index in self._name_cache:
|
||||||
|
del self._name_cache[index]
|
||||||
|
|
||||||
|
# Запускаем стандартный запрос значений. Он автоматически обработает
|
||||||
|
# отсутствующую сервисную информацию (имена/типы) перед запросом данных.
|
||||||
|
if not (self._polling or self._ll_polling):
|
||||||
|
self.request_values()
|
||||||
|
|
||||||
|
def request_values(self):
|
||||||
|
self._update_interval()
|
||||||
|
|
||||||
|
base = int(self.spin_index.value())
|
||||||
|
count = int(self.spin_count.value())
|
||||||
|
needed = []
|
||||||
|
for i in range(base, base+count):
|
||||||
|
if i not in self._name_cache:
|
||||||
|
needed.append(i)
|
||||||
|
if needed:
|
||||||
|
self._service_queue = needed[:]
|
||||||
|
self._pending_data_after_services = (base, count)
|
||||||
|
self._log(f"[AUTO] Need service for {len(needed)} indices: {needed}")
|
||||||
|
self.set_status("Read service...", "service")
|
||||||
|
self._kick_service_queue()
|
||||||
|
else:
|
||||||
|
self.set_status("Read values...", "values")
|
||||||
|
self._enqueue_or_start(base, service=False, varqnt=count)
|
||||||
|
|
||||||
|
def request_lowlevel_once(self):
|
||||||
|
"""Запрашивает чтение выбранной LowLevel переменной (однократно)."""
|
||||||
|
if not self.serial.isOpen():
|
||||||
|
self._log("[LL] Port is not open.")
|
||||||
|
return
|
||||||
|
if self._busy:
|
||||||
|
self._log("[LL] Busy, request dropped.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Если переменная не подготовлена, или нет актуальной информации
|
||||||
|
if not hasattr(self, '_ll_current_var_info') or not self._ll_current_var_info:
|
||||||
|
self._log("[LL] No variable prepared/selected for single read!")
|
||||||
|
return
|
||||||
|
|
||||||
|
frame = self._build_lowlevel_request(self._ll_current_var_info)
|
||||||
|
# --- НОВОЕ: Передаем ll_var_info в метаданные транзакции ---
|
||||||
|
meta = {'lowlevel': True, 'll_polling': False, 'll_var_info': self._ll_current_var_info}
|
||||||
|
self.set_status("Read lowlevel...", "values")
|
||||||
|
self._enqueue_raw(frame, meta)
|
||||||
|
|
||||||
|
# -------------------------- SERVICE QUEUE FLOW ------------------------
|
||||||
|
# ... (код без изменений)
|
||||||
|
def _kick_service_queue(self):
|
||||||
|
if self._busy:
|
||||||
|
return
|
||||||
|
if self._service_queue:
|
||||||
|
nxt = self._service_queue.pop(0)
|
||||||
|
self._enqueue_or_start(nxt, service=True, varqnt=0, queue_mode=True)
|
||||||
|
elif self._pending_data_after_services:
|
||||||
|
base, count = self._pending_data_after_services
|
||||||
|
self._pending_data_after_services = None
|
||||||
|
self._enqueue_or_start(base, service=False, varqnt=count)
|
||||||
|
|
||||||
|
# ------------------------ TRANSACTION SCHEDULER -----------------------
|
||||||
|
# ... (код без изменений)
|
||||||
|
def _enqueue_raw(self, frame: bytes, meta: dict):
|
||||||
|
# Добавляем ll_var_info, если это LL запрос
|
||||||
|
if meta.get('lowlevel', False) and 'll_var_info' not in meta:
|
||||||
|
# Это должно быть установлено вызывающим кодом, но для безопасности
|
||||||
|
# или если LL polling не передал var_info явно
|
||||||
|
meta['ll_var_info'] = self._ll_current_var_info # Используем last prepared var info for single shots
|
||||||
|
|
||||||
|
if self._busy:
|
||||||
|
# ... существующий код ...
|
||||||
|
if self._replace_if_busy:
|
||||||
|
self._pending_cmd = (frame, meta)
|
||||||
|
self._log("[LOCKSTEP] Busy -> replaced pending")
|
||||||
|
else:
|
||||||
|
self._log("[LOCKSTEP] Busy -> ignore")
|
||||||
|
return
|
||||||
|
self._start_txn(frame, meta)
|
||||||
|
|
||||||
|
def _enqueue_or_start(self, index, service: bool, varqnt: int, chain_after=None, queue_mode=False):
|
||||||
|
frame = self._build_request(index, service=service, varqnt=varqnt)
|
||||||
|
meta = {'service': service, 'index': index, 'varqnt': varqnt, 'chain': chain_after, 'queue_mode': queue_mode, 'lowlevel': False}
|
||||||
|
if self._busy:
|
||||||
|
if self._drop_if_busy and not self._replace_if_busy:
|
||||||
|
self._log("[LOCKSTEP] Busy -> drop")
|
||||||
|
return
|
||||||
|
if self._replace_if_busy:
|
||||||
|
self._pending_cmd = (frame, meta)
|
||||||
|
self._log("[LOCKSTEP] Busy -> replaced pending")
|
||||||
|
else:
|
||||||
|
self._log("[LOCKSTEP] Busy -> ignore")
|
||||||
|
return
|
||||||
|
self._start_txn(frame, meta)
|
||||||
|
|
||||||
|
def _start_txn(self, frame: bytes, meta: dict):
|
||||||
|
if(meta.get('service')):
|
||||||
|
self._update_interval()
|
||||||
|
self._busy = True
|
||||||
|
self._txn_meta = meta
|
||||||
|
self._rx_buf.clear()
|
||||||
|
self._set_ui_busy(True)
|
||||||
|
self._send(frame)
|
||||||
|
self._txn_timer.start(self.read_timeout_ms)
|
||||||
|
|
||||||
|
def _end_txn(self):
|
||||||
|
self._txn_timer.stop()
|
||||||
|
queue_mode = False
|
||||||
|
chain = None
|
||||||
|
meta = self._txn_meta
|
||||||
|
if meta:
|
||||||
|
queue_mode = meta.get('queue_mode', False)
|
||||||
|
chain = meta.get('chain')
|
||||||
|
|
||||||
|
self._txn_meta = None
|
||||||
|
self._busy = False
|
||||||
|
self._rx_buf.clear()
|
||||||
|
self._set_ui_busy(False)
|
||||||
|
|
||||||
|
if chain:
|
||||||
|
base, serv, q = chain
|
||||||
|
self._enqueue_or_start(base, service=serv, varqnt=q)
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._pending_cmd is not None:
|
||||||
|
frame, meta = self._pending_cmd
|
||||||
|
self._pending_cmd = None
|
||||||
|
QtCore.QTimer.singleShot(0, lambda f=frame, m=meta: self._start_txn(f, m))
|
||||||
|
return
|
||||||
|
|
||||||
|
if queue_mode:
|
||||||
|
QtCore.QTimer.singleShot(0, self._kick_service_queue)
|
||||||
|
# !!! Раньше тут было `return`, его убираем
|
||||||
|
|
||||||
|
# Если идёт LL polling — переходим сразу к следующей переменной
|
||||||
|
if self._ll_polling:
|
||||||
|
self._process_next_ll_variable_in_cycle()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def _on_txn_timeout(self):
|
||||||
|
if not self._busy: return
|
||||||
|
is_ll = self._txn_meta.get('lowlevel', False) if self._txn_meta else False
|
||||||
|
log_prefix = "[LL TIMEOUT]" if is_ll else "[TIMEOUT]"
|
||||||
|
self._log(f"{log_prefix} No response")
|
||||||
|
if self._rx_buf:
|
||||||
|
self._log_frame(bytes(self._rx_buf), tx=False)
|
||||||
|
self._end_txn()
|
||||||
|
self.set_status("Timeout", "error")
|
||||||
|
|
||||||
|
# ------------------------------- TX/RX ---------------------------------
|
||||||
|
# ... (код без изменений)
|
||||||
|
def _send(self, data: bytes):
|
||||||
|
w = self.serial.write(data)
|
||||||
|
if w != len(data):
|
||||||
|
self._log(f"[ERR] Write short {w}/{len(data)}")
|
||||||
|
self.txBytes.emit(data)
|
||||||
|
self._log_frame(data, tx=True)
|
||||||
|
|
||||||
|
def _on_ready_read(self):
|
||||||
|
self._rx_buf.extend(self.serial.readAll().data())
|
||||||
|
if not self._busy:
|
||||||
|
if self._rx_buf:
|
||||||
|
self._log("[WARN] Data while idle -> drop")
|
||||||
|
self._log_frame(bytes(self._rx_buf), tx=False)
|
||||||
|
self._rx_buf.clear()
|
||||||
|
return
|
||||||
|
self._try_parse()
|
||||||
|
if not (self._polling or self._ll_polling):
|
||||||
|
self.set_status("Idle", "idle")
|
||||||
|
|
||||||
|
# ------------------------------- PARSING -------------------------------
|
||||||
|
def _try_parse(self):
|
||||||
|
if not self._txn_meta:
|
||||||
|
return
|
||||||
|
if self._txn_meta.get('lowlevel', False):
|
||||||
|
self._try_parse_lowlevel()
|
||||||
|
else:
|
||||||
|
self._try_parse_watch()
|
||||||
|
|
||||||
|
def _try_parse_watch(self):
|
||||||
|
# ... (код без изменений)
|
||||||
|
service = self._txn_meta['service']
|
||||||
|
buf = self._rx_buf
|
||||||
|
trailer_len = 4
|
||||||
|
if service:
|
||||||
|
if len(buf) < 7 + trailer_len:
|
||||||
|
return
|
||||||
|
name_len = buf[6]
|
||||||
|
expected = 7 + name_len + trailer_len
|
||||||
|
if len(buf) < expected:
|
||||||
|
return
|
||||||
|
frame = bytes(buf[:expected]); del buf[:expected]
|
||||||
|
self.rxBytes.emit(frame); self._log_frame(frame, tx=False)
|
||||||
|
self._parse_service_frame(frame)
|
||||||
|
self._end_txn()
|
||||||
|
else:
|
||||||
|
if len(buf) < 6 + trailer_len:
|
||||||
|
return
|
||||||
|
varqnt = buf[4]; status = buf[5]
|
||||||
|
if status != DEBUG_OK:
|
||||||
|
expected = 8 + trailer_len
|
||||||
|
if len(buf) < expected: return
|
||||||
|
frame = bytes(buf[:expected]); del buf[:expected]
|
||||||
|
self.rxBytes.emit(frame); self._log_frame(frame, tx=False)
|
||||||
|
self._parse_data_frame(frame, error_mode=True)
|
||||||
|
self._end_txn()
|
||||||
|
else:
|
||||||
|
expected = 6 + varqnt*2 + trailer_len
|
||||||
|
if len(buf) < expected: return
|
||||||
|
frame = bytes(buf[:expected]); del buf[:expected]
|
||||||
|
self.rxBytes.emit(frame); self._log_frame(frame, tx=False)
|
||||||
|
self._parse_data_frame(frame, error_mode=False)
|
||||||
|
self._end_txn()
|
||||||
|
|
||||||
|
def _try_parse_lowlevel(self):
|
||||||
|
# Ожидаемая длина: Успех=13, Ошибка=10
|
||||||
|
buf = self._rx_buf
|
||||||
|
if len(buf) < 10: # Минимальная длина (ошибка)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Проверяем, что ответ для нас
|
||||||
|
if buf[1] != self.cmd_lowlevel:
|
||||||
|
self._log("[LL] Unexpected cmd in lowlevel parser, flushing.")
|
||||||
|
self._log_frame(bytes(self._rx_buf), tx=False)
|
||||||
|
self._rx_buf.clear()
|
||||||
|
# Не завершаем транзакцию, ждём таймаута
|
||||||
|
return
|
||||||
|
|
||||||
|
status = buf[2]
|
||||||
|
expected_len = 13 if status == DEBUG_OK else 10
|
||||||
|
|
||||||
|
if len(buf) >= expected_len:
|
||||||
|
frame = bytes(buf[:expected_len])
|
||||||
|
del buf[:expected_len]
|
||||||
|
self.rxBytes.emit(frame)
|
||||||
|
self._log_frame(frame, tx=False)
|
||||||
|
self._parse_lowlevel_frame(frame, success=(status == DEBUG_OK))
|
||||||
|
self._end_txn()
|
||||||
|
|
||||||
|
|
||||||
|
def _check_crc(self, payload: bytes, crc_lo: int, crc_hi: int):
|
||||||
|
if not self.auto_crc_check:
|
||||||
|
return True
|
||||||
|
crc_rx = (crc_hi << 8) | crc_lo
|
||||||
|
crc_calc = crc16_ibm(payload)
|
||||||
|
if crc_calc != crc_rx:
|
||||||
|
self._log(f"[CRC FAIL] calc=0x{crc_calc:04X} rx=0x{crc_rx:04X}")
|
||||||
|
return False
|
||||||
|
self._log("[CRC OK]")
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _clear_service_bit(vhi, vlo):
|
||||||
|
return ((vhi & 0x7F) << 8) | vlo
|
||||||
|
|
||||||
|
def _parse_service_frame(self, frame: bytes):
|
||||||
|
# ... (код без изменений)
|
||||||
|
payload = frame[:-4]; crc_lo, crc_hi = frame[-4], frame[-3]
|
||||||
|
if len(payload) < 7:
|
||||||
|
self._log("[ERR] Service frame too short"); return
|
||||||
|
self._check_crc(payload, crc_lo, crc_hi)
|
||||||
|
adr, cmd, vhi, vlo, status, iq_raw, name_len = payload[:7]
|
||||||
|
status_desc = _decode_debug_status(status)
|
||||||
|
index = self._clear_service_bit(vhi, vlo)
|
||||||
|
if len(payload) < 7 + name_len:
|
||||||
|
self._log("[ERR] Service name truncated"); return
|
||||||
|
name_bytes = payload[7:7+name_len]; name = name_bytes.decode(errors='replace')
|
||||||
|
is_signed = (iq_raw & SIGN_BIT_MASK) != 0
|
||||||
|
frac_bits = iq_raw & FRAC_MASK_FULL
|
||||||
|
if status == DEBUG_OK:
|
||||||
|
self._name_cache[index] = (status, iq_raw, name, is_signed, frac_bits)
|
||||||
|
self.nameRead.emit(index, status, iq_raw, name)
|
||||||
|
self._log(f"[SERVICE] idx={index} status={status} iq_raw=0x{iq_raw:02X} sign={'S' if is_signed else 'U'} frac={frac_bits} name='{name}'")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_data_frame(self, frame: bytes, *, error_mode: bool):
|
||||||
|
payload = frame[:-4]; crc_lo, crc_hi = frame[-4], frame[-3]
|
||||||
|
if len(payload) < 6:
|
||||||
|
self._log("[ERR] Data frame too short"); return
|
||||||
|
self._check_crc(payload, crc_lo, crc_hi)
|
||||||
|
adr, cmd, vhi, vlo, varqnt, status = payload[:6]
|
||||||
|
base = self._clear_service_bit(vhi, vlo)
|
||||||
|
if error_mode:
|
||||||
|
self.set_status("Error", "error")
|
||||||
|
if len(payload) < 8:
|
||||||
|
self._log("[ERR] Error frame truncated"); return
|
||||||
|
err_hi, err_lo = payload[6:8]
|
||||||
|
bad_index = (err_hi << 8) | err_lo
|
||||||
|
desc = _decode_debug_status(status)
|
||||||
|
self._log(f"[DATA] ERROR status=0x{status:02X} ({desc}) bad_index={bad_index}")
|
||||||
|
|
||||||
|
# Обновим UI
|
||||||
|
self._populate_watch_error(bad_index, status)
|
||||||
|
|
||||||
|
# Сигналы (оставляем совместимость)
|
||||||
|
self.valueRead.emit(bad_index, status, 0, 0, float('nan'))
|
||||||
|
self.valuesRead.emit(base, 0, [], [], [], [])
|
||||||
|
return
|
||||||
|
|
||||||
|
if len(payload) < 6 + varqnt*2:
|
||||||
|
self._log("[ERR] Data payload truncated"); return
|
||||||
|
raw_vals = []
|
||||||
|
pos = 6
|
||||||
|
for _ in range(varqnt):
|
||||||
|
hi = payload[pos]; lo = payload[pos+1]; pos += 2
|
||||||
|
raw16 = (hi << 8) | lo
|
||||||
|
raw_vals.append(raw16)
|
||||||
|
idx_list = []; iq_list = []; name_list = []; scaled_list = []; display_raw_list = []
|
||||||
|
|
||||||
|
# Получаем текущее время один раз для всех переменных в этом фрейме
|
||||||
|
current_time = time.time()
|
||||||
|
|
||||||
|
for ofs, raw16 in enumerate(raw_vals):
|
||||||
|
idx = base + ofs
|
||||||
|
status_i, iq_raw, name_i, is_signed, frac_bits = self._name_cache.get(idx, (DEBUG_OK, 0, '', False, 0))
|
||||||
|
if is_signed and (raw16 & 0x8000):
|
||||||
|
value_int = raw16 - 0x10000
|
||||||
|
else:
|
||||||
|
value_int = raw16
|
||||||
|
if self.chk_raw.isChecked():
|
||||||
|
scale = 1.0
|
||||||
|
else:
|
||||||
|
scale = self.iq_scaling.get(frac_bits, 1.0 / (1 << frac_bits))
|
||||||
|
scaled = float(value_int) / scale if frac_bits > 0 else float(value_int)
|
||||||
|
idx_list.append(idx); iq_list.append(iq_raw); name_list.append(name_i)
|
||||||
|
scaled_list.append(scaled); display_raw_list.append(value_int)
|
||||||
|
|
||||||
|
# --- Здесь записываем имя и значение в csv_logger ---
|
||||||
|
self.csv_logger.set_value(current_time, name_i, scaled)
|
||||||
|
|
||||||
|
self._populate_table(idx_list, name_list, iq_list, display_raw_list, scaled_list)
|
||||||
|
if varqnt == 1:
|
||||||
|
if idx_list[0] == self.spin_index.value():
|
||||||
|
_, iq_raw0, name0, is_signed0, frac0 = self._name_cache.get(idx_list[0], (DEBUG_OK, 0, '', False, 0))
|
||||||
|
self.valueRead.emit(idx_list[0], status, iq_list[0], display_raw_list[0], scaled_list[0])
|
||||||
|
else:
|
||||||
|
self.valuesRead.emit(base, varqnt, idx_list, iq_list, display_raw_list, scaled_list)
|
||||||
|
self._log(f"[DATA] base={base} q={varqnt} values={[f'{v:.6g}' for v in scaled_list] if not self.chk_raw.isChecked() else raw_vals}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_lowlevel_frame(self, frame: bytes, success: bool):
|
||||||
|
payload_len = 9 if success else 6
|
||||||
|
crc_pos = payload_len
|
||||||
|
payload = frame[:payload_len]
|
||||||
|
crc_lo, crc_hi = frame[crc_pos], frame[crc_pos+1]
|
||||||
|
|
||||||
|
self._check_crc(payload, crc_lo, crc_hi)
|
||||||
|
|
||||||
|
status = payload[2]
|
||||||
|
addr2, addr1, addr0 = payload[3], payload[4], payload[5]
|
||||||
|
addr24 = (addr2 << 16) | (addr1 << 8) | addr0
|
||||||
|
|
||||||
|
status_desc = _decode_debug_status(status)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
# Ошибка — в ответе нет ReturnType и данных, только статус
|
||||||
|
self._log(f"[LL] ERROR addr=0x{addr24:06X} status=0x{status:02X} ({status_desc})")
|
||||||
|
self.llValueRead.emit(addr24, status, None, None, None)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Если success == True, продолжаем парсить ReturnType и данные
|
||||||
|
return_type = payload[6]
|
||||||
|
data_hi, data_lo = payload[7], payload[8]
|
||||||
|
raw16 = (data_hi << 8) | data_lo
|
||||||
|
|
||||||
|
is_signed = (return_type & SIGN_BIT_MASK) != 0
|
||||||
|
frac_bits = return_type & FRAC_MASK_FULL
|
||||||
|
|
||||||
|
if is_signed and (raw16 & 0x8000):
|
||||||
|
value_int = raw16 - 0x10000
|
||||||
|
else:
|
||||||
|
value_int = raw16
|
||||||
|
|
||||||
|
if self.chk_raw.isChecked():
|
||||||
|
scale = 1.0
|
||||||
|
else:
|
||||||
|
scale = self.iq_scaling.get(frac_bits, 1.0 / (1 << frac_bits)) # 1 / 2^N
|
||||||
|
|
||||||
|
scaled = float(value_int) / scale
|
||||||
|
|
||||||
|
self.llValueRead.emit(addr24, status, return_type, value_int, scaled)
|
||||||
|
|
||||||
|
var_name = None
|
||||||
|
if self._ll_current_var_info.get("address") == addr24:
|
||||||
|
var_name = self._ll_current_var_info.get("name")
|
||||||
|
display_val = value_int if self.chk_raw.isChecked() else scaled
|
||||||
|
if var_name:
|
||||||
|
self.ll_selector.set_variable_value(var_name, display_val)
|
||||||
|
|
||||||
|
self._log(f"[LL] OK addr=0x{addr24:06X} type=0x{return_type:02X} raw={value_int} scaled={scaled:.6g}")
|
||||||
|
|
||||||
|
current_time = time.time()
|
||||||
|
self.csv_logger.set_value(current_time, var_name, display_val)
|
||||||
|
|
||||||
|
|
||||||
|
def _populate_watch_error(self, bad_index: int, status: int):
|
||||||
|
"""Отобразить строку ошибки при неудачном ответе WATCH."""
|
||||||
|
desc = _decode_debug_status(status)
|
||||||
|
self.tbl_values.setRowCount(1)
|
||||||
|
self.tbl_values.setItem(0, 0, QtWidgets.QTableWidgetItem(str(bad_index)))
|
||||||
|
self.tbl_values.setItem(0, 1, QtWidgets.QTableWidgetItem(f"<ERROR:{desc}>"))
|
||||||
|
self.tbl_values.setItem(0, 2, QtWidgets.QTableWidgetItem("-"))
|
||||||
|
self.tbl_values.setItem(0, 3, QtWidgets.QTableWidgetItem("-"))
|
||||||
|
self.tbl_values.setItem(0, 4, QtWidgets.QTableWidgetItem("<ERROR>"))\
|
||||||
|
|
||||||
|
def _populate_table(self, idxs, names, iqs, raws, scaled):
|
||||||
|
"""
|
||||||
|
Быстрое массовое обновление таблицы значений.
|
||||||
|
- Не пересоздаём QTableWidgetItem при каждом вызове: обновляем текст.
|
||||||
|
- Блокируем сортировку, сигналы и обновления на время заполнения.
|
||||||
|
- Предвычисляем отображаемые строки (особенно формат scaled).
|
||||||
|
"""
|
||||||
|
tbl = self.tbl_values
|
||||||
|
n = len(idxs)
|
||||||
|
|
||||||
|
# Заморозка UI на время массового обновления
|
||||||
|
prev_sorting = tbl.isSortingEnabled()
|
||||||
|
tbl.setSortingEnabled(False)
|
||||||
|
tbl.blockSignals(True)
|
||||||
|
tbl.setUpdatesEnabled(False)
|
||||||
|
|
||||||
|
# Подготовка размера
|
||||||
|
if tbl.rowCount() != n:
|
||||||
|
tbl.setRowCount(n)
|
||||||
|
|
||||||
|
# Предварительно решаем: показывать сырые или масштабированные значения
|
||||||
|
show_raw = self.chk_raw.isChecked()
|
||||||
|
|
||||||
|
# Готовим строки (ускоряет при больших объёмах)
|
||||||
|
# str() заранее, чтобы не повторять в цикле
|
||||||
|
idx_strs = [str(v) for v in idxs]
|
||||||
|
raw_strs = [str(v) for v in raws]
|
||||||
|
scaled_strs = raw_strs if show_raw else [f"{v:.6g}" for v in scaled]
|
||||||
|
|
||||||
|
# Флаги необновляемых ячеек (только выбор/просмотр)
|
||||||
|
flags_ro = QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled
|
||||||
|
|
||||||
|
# Локальный шорткат для быстрой установки текста в ячейку
|
||||||
|
def _set_text(row, col, text):
|
||||||
|
item = tbl.item(row, col)
|
||||||
|
if item is None:
|
||||||
|
item = QtWidgets.QTableWidgetItem(text)
|
||||||
|
item.setFlags(flags_ro)
|
||||||
|
tbl.setItem(row, col, item)
|
||||||
|
else:
|
||||||
|
# обновим текст только при изменении (немного экономит на больших данных)
|
||||||
|
if item.text() != text:
|
||||||
|
item.setText(text)
|
||||||
|
if item.flags() != flags_ro:
|
||||||
|
item.setFlags(flags_ro)
|
||||||
|
|
||||||
|
# Основной цикл
|
||||||
|
for row in range(n):
|
||||||
|
iq_raw = iqs[row]
|
||||||
|
is_signed = (iq_raw & SIGN_BIT_MASK) != 0
|
||||||
|
frac_bits = iq_raw & FRAC_MASK_FULL
|
||||||
|
iq_disp = f"{frac_bits}{'s' if is_signed else 'u'}"
|
||||||
|
|
||||||
|
_set_text(row, 0, idx_strs[row])
|
||||||
|
_set_text(row, 1, names[row])
|
||||||
|
_set_text(row, 2, iq_disp)
|
||||||
|
_set_text(row, 3, raw_strs[row])
|
||||||
|
_set_text(row, 4, scaled_strs[row])
|
||||||
|
|
||||||
|
# Разморозка
|
||||||
|
tbl.blockSignals(False)
|
||||||
|
tbl.setUpdatesEnabled(True)
|
||||||
|
tbl.setSortingEnabled(prev_sorting)
|
||||||
|
tbl.viewport().update()
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------ POLLING --------------------------------
|
||||||
|
def _toggle_polling(self):
|
||||||
|
if self._polling:
|
||||||
|
self._poll_timer.stop()
|
||||||
|
self._polling = False
|
||||||
|
self.btn_poll.setText("Start Polling")
|
||||||
|
self.set_status("Idle", "idle")
|
||||||
|
self._log("[POLL] Stopped")
|
||||||
|
else:
|
||||||
|
interval = self.spin_interval.value()
|
||||||
|
self._poll_timer.start(interval)
|
||||||
|
self._polling = True
|
||||||
|
self.btn_poll.setText("Stop Polling")
|
||||||
|
self.set_status("Idle", "idle")
|
||||||
|
self._log(f"[POLL] Started interval={interval}ms")
|
||||||
|
|
||||||
|
self._set_ui_busy(False) # Обновить доступность кнопок
|
||||||
|
|
||||||
|
def _on_poll_timeout(self):
|
||||||
|
self.request_values()
|
||||||
|
|
||||||
|
def _toggle_ll_polling(self):
|
||||||
|
if self._ll_polling: # If currently polling, stop
|
||||||
|
self._ll_polling = False
|
||||||
|
self.ll_selector.btn_start_polling.setText("Start Polling")
|
||||||
|
self._ll_poll_timer.stop()
|
||||||
|
self._ll_polling_variables.clear()
|
||||||
|
self._ll_current_poll_index = -1
|
||||||
|
self._log("[LL Polling] Stopped.")
|
||||||
|
else: # If not polling, start
|
||||||
|
# Get all selected variables from the LowLevelSelectorWidget
|
||||||
|
self._ll_polling_variables = self.ll_selector.get_selected_variables_and_addresses()
|
||||||
|
if not self._ll_polling_variables:
|
||||||
|
self._log("[LL] No variables selected for polling. Aborting.")
|
||||||
|
self.set_status("Error.", "error")
|
||||||
|
return
|
||||||
|
|
||||||
|
self._ll_polling = True
|
||||||
|
self.ll_selector.btn_start_polling.setText("Stop Polling")
|
||||||
|
self._ll_current_poll_index = 0 # Start from the first variable
|
||||||
|
self._log(f"[LL Polling] Started. Polling {len(self._ll_polling_variables)} variables.")
|
||||||
|
|
||||||
|
# Start the timer. It will trigger _on_ll_poll_timeout, which starts the cycle.
|
||||||
|
# The first cycle starts immediately, subsequent cycles wait for the interval.
|
||||||
|
self._ll_poll_timer.setInterval(self.ll_selector.spin_interval.value())
|
||||||
|
self._ll_poll_timer.start() # Start the timer for recurrent cycles
|
||||||
|
|
||||||
|
# Immediately kick off the first variable read of the first cycle
|
||||||
|
self._start_ll_cycle()
|
||||||
|
self._set_ui_busy(False) # Обновить доступность кнопок
|
||||||
|
|
||||||
|
|
||||||
|
def _on_ll_poll_timeout(self):
|
||||||
|
"""Вызывается по таймеру для старта нового цикла."""
|
||||||
|
if self._ll_polling and not self._busy:
|
||||||
|
self._start_ll_cycle()
|
||||||
|
elif self._busy:
|
||||||
|
self._log("[LL Polling] Busy, skip cycle start.")
|
||||||
|
|
||||||
|
|
||||||
|
def _start_ll_cycle(self):
|
||||||
|
self._update_interval()
|
||||||
|
|
||||||
|
"""Запускает новый цикл опроса всех переменных."""
|
||||||
|
if not self._ll_polling or not self._ll_polling_variables:
|
||||||
|
return
|
||||||
|
self._ll_poll_index = 0
|
||||||
|
self._process_next_ll_variable_in_cycle()
|
||||||
|
|
||||||
|
def _on_ll_variable_prepared(self, var_info: dict):
|
||||||
|
"""Срабатывает при выборе переменной в селекторе."""
|
||||||
|
self._ll_current_var_info = var_info
|
||||||
|
|
||||||
|
def _process_next_ll_variable_in_cycle(self):
|
||||||
|
if not self._ll_polling: # Добавим проверку, чтобы избежать вызова, если LL polling отключен
|
||||||
|
return
|
||||||
|
|
||||||
|
if self._ll_poll_index < len(self._ll_polling_variables):
|
||||||
|
var_info = self._ll_polling_variables[self._ll_poll_index]
|
||||||
|
self._on_ll_variable_prepared(var_info)
|
||||||
|
self._ll_poll_index += 1
|
||||||
|
frame = self._build_lowlevel_request(var_info)
|
||||||
|
# --- НОВОЕ: Передаем var_info в метаданные транзакции для LL polling ---
|
||||||
|
meta = {'lowlevel': True, 'll_polling': True, 'll_var_info': var_info}
|
||||||
|
# Получаем адрес переменной, предполагаем что ключ называется 'addr' или 'address'
|
||||||
|
addr = var_info.get('addr') or var_info.get('address')
|
||||||
|
if addr is not None:
|
||||||
|
addr_str = f"0x{addr:06X}"
|
||||||
|
else:
|
||||||
|
addr_str = "addr unknown"
|
||||||
|
|
||||||
|
self.set_status(f"Polling LL: {addr_str} {var_info.get('name')}", "values")
|
||||||
|
self._enqueue_raw(frame, meta)
|
||||||
|
else:
|
||||||
|
# Цикл завершен, перезапускаем таймер для следующего полного цикла
|
||||||
|
self.ll_selector._populate_var_table()
|
||||||
|
# ------------------------------ HELPERS --------------------------------
|
||||||
|
def _toggle_index_base(self, st):
|
||||||
|
# ... (код без изменений)
|
||||||
|
val = self.spin_index.value()
|
||||||
|
if st == QtCore.Qt.Checked:
|
||||||
|
self.spin_index.setDisplayIntegerBase(16); self.spin_index.setPrefix("0x")
|
||||||
|
else:
|
||||||
|
self.spin_index.setDisplayIntegerBase(10); self.spin_index.setPrefix("")
|
||||||
|
self.spin_index.setValue(val)
|
||||||
|
|
||||||
|
def _set_ui_busy(self, busy: bool):
|
||||||
|
# Блокируем кнопки в зависимости от состояния 'busy' и 'polling'
|
||||||
|
|
||||||
|
# Watch tab
|
||||||
|
can_use_watch = not busy and not (self._polling or self._ll_polling)
|
||||||
|
#self.btn_update_service.setEnabled(can_use_watch)
|
||||||
|
self.btn_read_values.setEnabled(can_use_watch)
|
||||||
|
|
||||||
|
# LowLevel tab
|
||||||
|
can_use_ll = not busy and not (self._ll_polling or self._polling)
|
||||||
|
self.ll_selector.btn_read_once.setEnabled(can_use_ll)
|
||||||
|
|
||||||
|
def _on_serial_error(self, err):
|
||||||
|
# ... (код без изменений)
|
||||||
|
if err == QtSerialPort.QSerialPort.NoError: return
|
||||||
|
self._log(f"[SERIAL ERR] {self.serial.errorString()} ({err})")
|
||||||
|
if self._busy: self._end_txn()
|
||||||
|
|
||||||
|
# ------------------------------ LOGGING --------------------------------
|
||||||
|
def _select_csv_file(self):
|
||||||
|
"""Открывает диалог выбора файла для CSV и обновляет UI."""
|
||||||
|
if self.csv_logger.select_file(self): # Передаем self как parent для диалога
|
||||||
|
self.lbl_csv_filename.setText(self.csv_logger.filename)
|
||||||
|
self._log(f"CSV file set to: {self.csv_logger.filename}")
|
||||||
|
|
||||||
|
|
||||||
|
def _start_csv_logging(self):
|
||||||
|
"""Начинает запись данных в CSV. Устанавливает заголовки в зависимости от активной вкладки."""
|
||||||
|
if not self.serial.isOpen():
|
||||||
|
self._log("[CSV] Невозможно начать запись: COM порт не открыт.")
|
||||||
|
self.set_status("Port closed", "error")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Определяем активную вкладку и устанавливаем заголовки
|
||||||
|
current_tab_index = self.tabs.currentIndex()
|
||||||
|
varnames_for_csv = []
|
||||||
|
|
||||||
|
if self.tabs.tabText(current_tab_index) == "Watch":
|
||||||
|
# Для вкладки Watch берем имена из кэша, если они есть, иначе используем Index_X
|
||||||
|
base_index = self.spin_index.value()
|
||||||
|
count = self.spin_count.value()
|
||||||
|
for i in range(base_index, base_index + count):
|
||||||
|
if i in self._name_cache and self._name_cache[i][2]: # status, iq_raw, name, is_signed, frac_bits
|
||||||
|
varnames_for_csv.append(self._name_cache[i][2])
|
||||||
|
else:
|
||||||
|
varnames_for_csv.append(f"Index_{i}")
|
||||||
|
self._log(f"[CSV] Начинается запись для Watch переменных: {varnames_for_csv}")
|
||||||
|
elif self.tabs.tabText(current_tab_index) == "LowLevel":
|
||||||
|
# Для вкладки LowLevel берем имена из ll_selector
|
||||||
|
selected_vars = self.ll_selector.get_selected_variables_and_addresses()
|
||||||
|
varnames_for_csv = [var['name'] for var in selected_vars if 'name' in var]
|
||||||
|
if not varnames_for_csv:
|
||||||
|
self._log("[CSV] Внимание: На вкладке LowLevel не выбраны переменные для записи.")
|
||||||
|
self._log(f"[CSV] Начинается запись для LowLevel переменных: {varnames_for_csv}")
|
||||||
|
else:
|
||||||
|
self._log("[CSV] Неизвестная активная вкладка. Невозможно определить заголовки CSV.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if not varnames_for_csv:
|
||||||
|
self._log("[CSV] Нет переменных для записи в CSV. Запись не начата.")
|
||||||
|
return
|
||||||
|
|
||||||
|
self.csv_logger.set_titles(varnames_for_csv)
|
||||||
|
self._csv_logging_active = True
|
||||||
|
self.btn_start_csv_logging.setEnabled(False)
|
||||||
|
self.btn_stop_csv_logging.setEnabled(True)
|
||||||
|
self.set_status("CSV Logging ACTIVATED", "service")
|
||||||
|
self._log("[CSV] Запись данных в CSV началась.")
|
||||||
|
|
||||||
|
|
||||||
|
def _stop_csv_logging(self):
|
||||||
|
"""Останавливает запись данных в CSV."""
|
||||||
|
self._csv_logging_active = False
|
||||||
|
self.btn_start_csv_logging.setEnabled(True)
|
||||||
|
self.btn_stop_csv_logging.setEnabled(False)
|
||||||
|
self.set_status("CSV Logging STOPPED", "service")
|
||||||
|
self._log("[CSV] Запись данных в CSV остановлена.")
|
||||||
|
|
||||||
|
def _save_csv_data(self):
|
||||||
|
"""Сохраняет все собранные данные в CSV файл."""
|
||||||
|
if self._csv_logging_active:
|
||||||
|
self._log("[CSV] Запись активна. Сначала остановите запись.")
|
||||||
|
self.set_status("Stop logging first", "error")
|
||||||
|
return
|
||||||
|
self.csv_logger.write_to_csv()
|
||||||
|
self.set_status("CSV data saved", "service")
|
||||||
|
|
||||||
|
def _log(self, msg: str):
|
||||||
|
# ... (код без изменений)
|
||||||
|
if 'ERR' in msg:
|
||||||
|
self.set_status(msg, 'error')
|
||||||
|
if 'OK' in msg:
|
||||||
|
self.set_status('Idle', 'idle')
|
||||||
|
if not self.log_spoiler.getState():
|
||||||
|
return
|
||||||
|
ts = datetime.datetime.now().strftime('%H:%M:%S.%f')[:-3]
|
||||||
|
self.txt_log.append(f"{ts} {msg}")
|
||||||
|
|
||||||
|
def _log_frame(self, data: bytes, *, tx: bool):
|
||||||
|
# ... (код без изменений)
|
||||||
|
if not self.log_spoiler.getState():
|
||||||
|
return
|
||||||
|
tag = 'TX' if tx else 'RX'
|
||||||
|
hexs = ' '.join(f"{b:02X}" for b in data)
|
||||||
|
ascii_part = ''.join(chr(b) if 32 <= b < 127 else '.' for b in data)
|
||||||
|
self._log(f"[{tag}] {hexs} |{ascii_part}|")
|
||||||
|
|
||||||
|
def _update_interval(self):
|
||||||
|
now = time.perf_counter()
|
||||||
|
if self._last_txn_timestamp is not None:
|
||||||
|
delta_ms = (now - self._last_txn_timestamp) * 1000
|
||||||
|
# Обновляем UI только если он уже создан
|
||||||
|
if hasattr(self, 'lbl_actual_interval'):
|
||||||
|
self.lbl_actual_interval.setText(f"{delta_ms:.1f} ms")
|
||||||
|
self._last_txn_timestamp = now
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------- Demo harness ---
|
||||||
|
class _DemoWindow(QtWidgets.QMainWindow):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
base_path = get_base_path()
|
||||||
|
icon_path = os.path.join(base_path, "icon.ico")
|
||||||
|
if os.path.exists(icon_path):
|
||||||
|
self.setWindowIcon(QtGui.QIcon(icon_path))
|
||||||
|
self.setWindowTitle("DebugVar Terminal")
|
||||||
|
self.term = DebugTerminalWidget(self)
|
||||||
|
self.setCentralWidget(self.term)
|
||||||
|
self.resize(1000, 600)
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self.setCentralWidget(None)
|
||||||
|
if self.term:
|
||||||
|
self.term.deleteLater(); self.term = None
|
||||||
|
super().closeEvent(event)
|
||||||
|
|
||||||
|
# ------------------------------- Demo --------------------------------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
win = _DemoWindow(); win.show()
|
||||||
|
sys.exit(app.exec_())
|
||||||
428
Src/var_selector_table.py
Normal file
428
Src/var_selector_table.py
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
# variable_select_widget.py
|
||||||
|
import pickle
|
||||||
|
import hashlib
|
||||||
|
from typing import List, Dict, Any, Optional
|
||||||
|
|
||||||
|
from PySide2.QtWidgets import (
|
||||||
|
QWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QLineEdit,
|
||||||
|
QHeaderView, QCompleter
|
||||||
|
)
|
||||||
|
from PySide2.QtGui import QKeyEvent
|
||||||
|
from PySide2.QtCore import Qt, QStringListModel
|
||||||
|
|
||||||
|
from path_hints import PathHints, canonical_key, split_path_tokens
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# utils
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def compute_vars_hash(vars_list):
|
||||||
|
return hashlib.sha1(pickle.dumps(vars_list)).hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def is_lazy_item(item: QTreeWidgetItem) -> bool:
|
||||||
|
return item.childCount() == 1 and item.child(0).text(0) == 'lazy_marker'
|
||||||
|
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# VariableSelectWidget
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
class VariableSelectWidget(QWidget):
|
||||||
|
"""
|
||||||
|
Виджет выбора переменных с деревом + строкой поиска + автодополнением.
|
||||||
|
Подсказки полностью через PathHints.
|
||||||
|
ВАЖНО: ожидается, что в данных (vars_list) каждое var['name'] — ПОЛНЫЙ ПУТЬ
|
||||||
|
(например: 'project.adc.status'), даже внутри children.
|
||||||
|
"""
|
||||||
|
|
||||||
|
ROLE_NAME = Qt.UserRole # локальный хвост (display)
|
||||||
|
ROLE_VAR_DICT = Qt.UserRole + 100 # исходный dict
|
||||||
|
ROLE_FULLPATH = Qt.UserRole + 200 # полный путь
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
# данные
|
||||||
|
self.expanded_vars: List[Dict[str, Any]] = []
|
||||||
|
self.is_autocomplete_on = True
|
||||||
|
self.manual_completion_active = False
|
||||||
|
self._bckspc_pressed = False
|
||||||
|
self._vars_hash: Optional[str] = None
|
||||||
|
|
||||||
|
# индекс: canonical_full_path -> item
|
||||||
|
self._item_by_canon: Dict[str, QTreeWidgetItem] = {}
|
||||||
|
|
||||||
|
# подсказки
|
||||||
|
self.hints = PathHints()
|
||||||
|
|
||||||
|
# --- UI ---
|
||||||
|
self.search_input = QLineEdit(self)
|
||||||
|
self.search_input.setPlaceholderText("Поиск...")
|
||||||
|
|
||||||
|
self.tree = QTreeWidget(self)
|
||||||
|
self.tree.setHeaderLabels(["Имя переменной", "Тип"])
|
||||||
|
self.tree.setSelectionMode(QTreeWidget.ExtendedSelection)
|
||||||
|
self.tree.setRootIsDecorated(True)
|
||||||
|
self.tree.setUniformRowHeights(True)
|
||||||
|
self.tree.setStyleSheet("""
|
||||||
|
QTreeWidget::item:selected { background-color: #87CEFA; color: black; }
|
||||||
|
QTreeWidget::item:hover { background-color: #D3D3D3; }
|
||||||
|
""")
|
||||||
|
self.tree.itemExpanded.connect(self.on_item_expanded)
|
||||||
|
|
||||||
|
self.completer = QCompleter(self)
|
||||||
|
self.completer.setCompletionMode(QCompleter.PopupCompletion)
|
||||||
|
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
|
||||||
|
self.completer.setFilterMode(Qt.MatchContains)
|
||||||
|
self.completer.setWidget(self.search_input)
|
||||||
|
self.completer.activated[str].connect(self.insert_completion)
|
||||||
|
|
||||||
|
# layout
|
||||||
|
lay = QVBoxLayout(self)
|
||||||
|
lay.setContentsMargins(0, 0, 0, 0)
|
||||||
|
lay.addWidget(self.search_input)
|
||||||
|
lay.addWidget(self.tree)
|
||||||
|
|
||||||
|
# signals
|
||||||
|
self.search_input.textChanged.connect(self.on_search_text_changed)
|
||||||
|
self.search_input.installEventFilter(self)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# public api
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def set_autocomplete(self, enabled: bool):
|
||||||
|
self.is_autocomplete_on = enabled
|
||||||
|
|
||||||
|
def set_data(self, vars_list: List[Dict[str, Any]]):
|
||||||
|
"""
|
||||||
|
Загружаем список переменных (формат: см. класс docstring).
|
||||||
|
"""
|
||||||
|
# deepcopy
|
||||||
|
self.expanded_vars = pickle.loads(pickle.dumps(vars_list, protocol=pickle.HIGHEST_PROTOCOL))
|
||||||
|
|
||||||
|
# rebuild hints из полного списка узлов (каждый узел уже с full_path)
|
||||||
|
self._rebuild_hints_from_vars(self.expanded_vars)
|
||||||
|
|
||||||
|
# rebuild tree
|
||||||
|
self.populate_tree(self.expanded_vars)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# hints builder: дети уже содержат ПОЛНЫЙ ПУТЬ
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def _rebuild_hints_from_vars(self, vars_list: List[Dict[str, Any]]):
|
||||||
|
paths: List[tuple] = []
|
||||||
|
|
||||||
|
def walk(node: Dict[str, Any]):
|
||||||
|
full = node.get('name', '')
|
||||||
|
if full:
|
||||||
|
paths.append((full, node.get('type')))
|
||||||
|
for ch in node.get('children', []) or []:
|
||||||
|
walk(ch)
|
||||||
|
|
||||||
|
for v in vars_list:
|
||||||
|
walk(v)
|
||||||
|
|
||||||
|
self.hints.set_paths(paths)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# tree building
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def populate_tree(self, vars_list=None):
|
||||||
|
if vars_list is None:
|
||||||
|
vars_list = self.expanded_vars
|
||||||
|
|
||||||
|
new_hash = compute_vars_hash(vars_list)
|
||||||
|
if self._vars_hash == new_hash:
|
||||||
|
return
|
||||||
|
self._vars_hash = new_hash
|
||||||
|
|
||||||
|
self.tree.setUpdatesEnabled(False)
|
||||||
|
self.tree.blockSignals(True)
|
||||||
|
self.tree.clear()
|
||||||
|
self._item_by_canon.clear()
|
||||||
|
|
||||||
|
# построим top-level из входного списка: определяем по глубине токенов
|
||||||
|
# (vars_list может содержать и глубокие узлы; выберем корни = те, чей full_path не имеет родителя в списке)
|
||||||
|
full_to_node = {v['name']: v for v in vars_list}
|
||||||
|
# но safer: просто добавляем все как top-level, если ты уже передаёшь только корни.
|
||||||
|
# Если в твоих данных vars_list == корни, просто сделаем:
|
||||||
|
for v in vars_list:
|
||||||
|
self._add_tree_item_lazy(None, v)
|
||||||
|
|
||||||
|
self.tree.setUpdatesEnabled(True)
|
||||||
|
self.tree.blockSignals(False)
|
||||||
|
|
||||||
|
header = self.tree.header()
|
||||||
|
header.setSectionResizeMode(QHeaderView.Interactive)
|
||||||
|
header.setSectionResizeMode(1, QHeaderView.Stretch)
|
||||||
|
self.tree.setColumnWidth(0, 400)
|
||||||
|
|
||||||
|
def on_item_expanded(self, item: QTreeWidgetItem):
|
||||||
|
if is_lazy_item(item):
|
||||||
|
item.removeChild(item.child(0))
|
||||||
|
var = item.data(0, self.ROLE_VAR_DICT)
|
||||||
|
if var:
|
||||||
|
for ch in var.get('children', []) or []:
|
||||||
|
self._add_tree_item_lazy(item, ch)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# item creation (var['name'] — ПОЛНЫЙ ПУТЬ)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def _add_tree_item_lazy(self, parent: Optional[QTreeWidgetItem], var: Dict[str, Any]):
|
||||||
|
full_path = var.get('name', '')
|
||||||
|
type_str = var.get('type', '')
|
||||||
|
|
||||||
|
# здесь оставляем полный путь для отображения
|
||||||
|
item = QTreeWidgetItem([full_path, type_str])
|
||||||
|
item.setData(0, self.ROLE_NAME, full_path) # теперь ROLE_NAME = полный путь
|
||||||
|
item.setData(0, self.ROLE_VAR_DICT, var)
|
||||||
|
item.setData(0, self.ROLE_FULLPATH, full_path)
|
||||||
|
|
||||||
|
if "(bitfield:" in type_str:
|
||||||
|
item.setDisabled(True)
|
||||||
|
self._set_tool(item, "Битовые поля недоступны для выбора")
|
||||||
|
|
||||||
|
# метаданные
|
||||||
|
for i, attr in enumerate(['file', 'extern', 'static']):
|
||||||
|
item.setData(0, Qt.UserRole + 1 + i, var.get(attr))
|
||||||
|
|
||||||
|
# в дерево
|
||||||
|
if parent is None:
|
||||||
|
self.tree.addTopLevelItem(item)
|
||||||
|
else:
|
||||||
|
parent.addChild(item)
|
||||||
|
|
||||||
|
# lazy children
|
||||||
|
if var.get('children'):
|
||||||
|
dummy = QTreeWidgetItem(["lazy_marker"])
|
||||||
|
item.addChild(dummy)
|
||||||
|
|
||||||
|
# индекс
|
||||||
|
self._item_by_canon[canonical_key(full_path)] = item
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _tail_token(full_path: str) -> str:
|
||||||
|
toks = split_path_tokens(full_path)
|
||||||
|
return toks[-1] if toks else full_path
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# filtering
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def filter_tree(self):
|
||||||
|
"""
|
||||||
|
Быстрый фильтр:
|
||||||
|
- без разделителей → substring по ЛОКАЛЬНОМУ имени top-level
|
||||||
|
- с разделителями → структурный (по токенам full_path)
|
||||||
|
"""
|
||||||
|
text = (self.search_input.text() or '').strip()
|
||||||
|
low = text.lower()
|
||||||
|
parts = split_path_tokens(low) if low else []
|
||||||
|
|
||||||
|
# простой режим (нет ., ->, [):
|
||||||
|
if low and all(x not in low for x in ('.', '->', '[')):
|
||||||
|
for i in range(self.tree.topLevelItemCount()):
|
||||||
|
it = self.tree.topLevelItem(i)
|
||||||
|
full = (it.data(0, self.ROLE_FULLPATH) or '').lower()
|
||||||
|
it.setHidden(low not in full)
|
||||||
|
return
|
||||||
|
|
||||||
|
# структурный
|
||||||
|
for i in range(self.tree.topLevelItemCount()):
|
||||||
|
it = self.tree.topLevelItem(i)
|
||||||
|
self._show_matching_path(it, parts, 0)
|
||||||
|
|
||||||
|
def _show_matching_path(self, item: QTreeWidgetItem, path_parts: List[str], level: int = 0):
|
||||||
|
"""
|
||||||
|
Сравниваем введённый путь (разбитый на токены) с ПОЛНЫМ ПУТЁМ узла.
|
||||||
|
Алгоритм: берём полный путь узла, разбиваем в токены, берём уровень level,
|
||||||
|
и сравниваем с соответствующим токеном path_parts[level].
|
||||||
|
"""
|
||||||
|
full = (item.data(0, self.ROLE_FULLPATH) or '').lower()
|
||||||
|
node_parts = split_path_tokens(full)
|
||||||
|
|
||||||
|
if level >= len(path_parts):
|
||||||
|
item.setHidden(False)
|
||||||
|
item.setExpanded(False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if level >= len(node_parts):
|
||||||
|
item.setHidden(True)
|
||||||
|
return False
|
||||||
|
|
||||||
|
search_part = path_parts[level]
|
||||||
|
node_part = node_parts[level]
|
||||||
|
|
||||||
|
if search_part == node_part:
|
||||||
|
item.setHidden(False)
|
||||||
|
matched_any = False
|
||||||
|
self.on_item_expanded(item)
|
||||||
|
for i in range(item.childCount()):
|
||||||
|
ch = item.child(i)
|
||||||
|
if self._show_matching_path(ch, path_parts, level + 1):
|
||||||
|
matched_any = True
|
||||||
|
item.setExpanded(matched_any)
|
||||||
|
return matched_any or item.childCount() == 0
|
||||||
|
|
||||||
|
elif node_part.startswith(search_part):
|
||||||
|
item.setHidden(False)
|
||||||
|
item.setExpanded(False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif search_part in node_part and (level == len(path_parts) - 1):
|
||||||
|
item.setHidden(False)
|
||||||
|
item.setExpanded(False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
else:
|
||||||
|
item.setHidden(True)
|
||||||
|
return False
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# completions (ONLY PathHints)
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def update_completions(self, text: Optional[str] = None) -> List[str]:
|
||||||
|
if text is None:
|
||||||
|
text = self.search_input.text()
|
||||||
|
suggestions = self.hints.suggest(text)
|
||||||
|
self.completer.setModel(QStringListModel(suggestions))
|
||||||
|
if suggestions:
|
||||||
|
self.completer.complete()
|
||||||
|
else:
|
||||||
|
self.completer.popup().hide()
|
||||||
|
return suggestions
|
||||||
|
|
||||||
|
def insert_completion(self, full_path: str):
|
||||||
|
text = self.hints.add_separator(full_path)
|
||||||
|
if not self._bckspc_pressed:
|
||||||
|
self.search_input.setText(text)
|
||||||
|
self.search_input.setCursorPosition(len(text))
|
||||||
|
self.run_completions(text)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# events
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def eventFilter(self, obj, event):
|
||||||
|
if obj == self.search_input and isinstance(event, QKeyEvent):
|
||||||
|
if event.key() == Qt.Key_Space and event.modifiers() & Qt.ControlModifier:
|
||||||
|
self.manual_completion_active = True
|
||||||
|
self.run_completions(self.search_input.text())
|
||||||
|
elif event.key() == Qt.Key_Escape:
|
||||||
|
if not self.is_autocomplete_on:
|
||||||
|
self.manual_completion_active = False
|
||||||
|
self.completer.popup().hide()
|
||||||
|
return True
|
||||||
|
if event.key() == Qt.Key_Backspace:
|
||||||
|
self._bckspc_pressed = True
|
||||||
|
else:
|
||||||
|
self._bckspc_pressed = False
|
||||||
|
return super().eventFilter(obj, event)
|
||||||
|
|
||||||
|
def run_completions(self, text: str):
|
||||||
|
if not self.is_autocomplete_on and not self.manual_completion_active:
|
||||||
|
self.completer.popup().hide()
|
||||||
|
return
|
||||||
|
self.update_completions(text)
|
||||||
|
|
||||||
|
def on_search_text_changed(self, text: str):
|
||||||
|
self.completer.setWidget(self.search_input)
|
||||||
|
self.filter_tree()
|
||||||
|
if text is None:
|
||||||
|
text = self.search_input.text()
|
||||||
|
if self.is_autocomplete_on:
|
||||||
|
self.run_completions(text)
|
||||||
|
else:
|
||||||
|
if self.manual_completion_active:
|
||||||
|
self.run_completions(text)
|
||||||
|
else:
|
||||||
|
self.completer.popup().hide()
|
||||||
|
|
||||||
|
def focusInEvent(self, event):
|
||||||
|
if self.completer.widget() != self.search_input:
|
||||||
|
self.completer.setWidget(self.search_input)
|
||||||
|
super().focusInEvent(event)
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self.completer.setWidget(None)
|
||||||
|
self.completer.deleteLater()
|
||||||
|
super().closeEvent(event)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# lookup by full path
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def find_item_by_fullpath(self, path: str) -> Optional[QTreeWidgetItem]:
|
||||||
|
return self._item_by_canon.get(canonical_key(path))
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# tooltips
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def _set_tool(self, item: QTreeWidgetItem, text: str):
|
||||||
|
item.setToolTip(0, text)
|
||||||
|
item.setToolTip(1, text)
|
||||||
|
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
# selection helpers
|
||||||
|
# ------------------------------------------------------------------
|
||||||
|
def get_all_items(self):
|
||||||
|
"""Все leaf-узлы (подгружаем lazy)."""
|
||||||
|
def collect_leaf(parent):
|
||||||
|
leaves = []
|
||||||
|
for i in range(parent.childCount()):
|
||||||
|
ch = parent.child(i)
|
||||||
|
if ch.isHidden():
|
||||||
|
continue
|
||||||
|
self.on_item_expanded(ch)
|
||||||
|
if ch.childCount() == 0:
|
||||||
|
t = ch.text(1)
|
||||||
|
if t and 'bitfield' in t.lower():
|
||||||
|
continue
|
||||||
|
leaves.append(ch)
|
||||||
|
else:
|
||||||
|
leaves.extend(collect_leaf(ch))
|
||||||
|
return leaves
|
||||||
|
|
||||||
|
out = []
|
||||||
|
for i in range(self.tree.topLevelItemCount()):
|
||||||
|
top = self.tree.topLevelItem(i)
|
||||||
|
self.on_item_expanded(top)
|
||||||
|
if top.childCount() == 0:
|
||||||
|
t = top.text(1)
|
||||||
|
if t and 'bitfield' in t.lower():
|
||||||
|
continue
|
||||||
|
out.append(top)
|
||||||
|
else:
|
||||||
|
out.extend(collect_leaf(top))
|
||||||
|
return out
|
||||||
|
|
||||||
|
def _get_internal_selected_items(self):
|
||||||
|
selected = self.tree.selectedItems()
|
||||||
|
all_items = []
|
||||||
|
def collect(item):
|
||||||
|
self.on_item_expanded(item)
|
||||||
|
res = [item]
|
||||||
|
for i in range(item.childCount()):
|
||||||
|
res.extend(collect(item.child(i)))
|
||||||
|
return res
|
||||||
|
for it in selected:
|
||||||
|
all_items.extend(collect(it))
|
||||||
|
return all_items
|
||||||
|
|
||||||
|
def get_selected_items(self):
|
||||||
|
selected = self.tree.selectedItems()
|
||||||
|
leaves = []
|
||||||
|
for it in selected:
|
||||||
|
self.on_item_expanded(it)
|
||||||
|
if all(it.child(i).isHidden() or not it.child(i).isSelected() for i in range(it.childCount())):
|
||||||
|
t = it.data(0, self.ROLE_NAME)
|
||||||
|
if t and isinstance(t, str) and 'bitfield' in t.lower():
|
||||||
|
continue
|
||||||
|
leaves.append(it)
|
||||||
|
return leaves
|
||||||
|
|
||||||
|
def get_all_var_names(self):
|
||||||
|
return [it.data(0, self.ROLE_FULLPATH) for it in self.get_all_items() if it.data(0, self.ROLE_FULLPATH)]
|
||||||
|
|
||||||
|
def _get_internal_selected_var_names(self):
|
||||||
|
return [it.data(0, self.ROLE_FULLPATH) for it in self._get_internal_selected_items() if it.data(0, self.ROLE_FULLPATH)]
|
||||||
|
|
||||||
|
def get_selected_var_names(self):
|
||||||
|
return [it.data(0, self.ROLE_FULLPATH) for it in self.get_selected_items() if it.data(0, self.ROLE_FULLPATH)]
|
||||||
392
Src/var_selector_window.py
Normal file
392
Src/var_selector_window.py
Normal file
@@ -0,0 +1,392 @@
|
|||||||
|
import re
|
||||||
|
import lxml.etree as ET
|
||||||
|
from PySide2.QtWidgets import (
|
||||||
|
QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton,
|
||||||
|
QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout, QSizePolicy
|
||||||
|
)
|
||||||
|
from PySide2.QtGui import QKeySequence, QKeyEvent
|
||||||
|
from PySide2.QtCore import Qt, QStringListModel, QSettings
|
||||||
|
import var_table
|
||||||
|
import var_setup
|
||||||
|
import myXML
|
||||||
|
import time
|
||||||
|
import var_selector_table
|
||||||
|
|
||||||
|
|
||||||
|
array_re = re.compile(r'^(\w+)\[(\d+)\]$')
|
||||||
|
|
||||||
|
class VariableSelectorDialog(QDialog):
|
||||||
|
def __init__(self, table, all_vars, structs, typedefs, xml_path=None, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle("Выбор переменных")
|
||||||
|
self.setAttribute(Qt.WA_DeleteOnClose)
|
||||||
|
self.resize(1200, 500)
|
||||||
|
self.selected_names = []
|
||||||
|
self._bckspc_pressed = False # флаг подавления добавления разделителя
|
||||||
|
self.table = table
|
||||||
|
self.all_vars = all_vars
|
||||||
|
self.structs = structs
|
||||||
|
self.typedefs = typedefs
|
||||||
|
self.expanded_vars = []
|
||||||
|
self.var_map = {v['name']: v for v in all_vars}
|
||||||
|
self.node_index = {}
|
||||||
|
self.xml_path = xml_path # сохраняем путь к xml
|
||||||
|
self.manual_completion_active = False
|
||||||
|
|
||||||
|
# --- Добавляем чекбокс для автодополнения ---
|
||||||
|
self.autocomplete_checkbox = QCheckBox("Включить автодополнение")
|
||||||
|
self.autocomplete_checkbox.setChecked(True)
|
||||||
|
|
||||||
|
# Инициализируем QSettings с именем организации и приложения
|
||||||
|
self.settings = QSettings("SET", "DebugVarEdit_VarsSelector")
|
||||||
|
# Восстанавливаем сохранённое состояние чекбокса, если есть
|
||||||
|
checked = self.settings.value("autocomplete_enabled", True, type=bool)
|
||||||
|
self.autocomplete_checkbox.setChecked(checked)
|
||||||
|
# При изменении состояния чекбокса сохраняем его
|
||||||
|
self.autocomplete_checkbox.stateChanged.connect(self.save_checkbox_state)
|
||||||
|
|
||||||
|
# Кнопки между таблицами
|
||||||
|
self.btn_right = QPushButton(">")
|
||||||
|
self.btn_right.clicked.connect(self.on_move_right)
|
||||||
|
self.btn_left = QPushButton("<")
|
||||||
|
self.btn_left.clicked.connect(self.on_move_left)
|
||||||
|
|
||||||
|
# Создаем кнопки, они остаются в диалоге
|
||||||
|
self.btn_accept = QPushButton("Применить")
|
||||||
|
|
||||||
|
# Создаем экземпляр вашего готового виджета
|
||||||
|
self.vars_widget = var_selector_table.VariableSelectWidget(self)
|
||||||
|
self.vars_widget.tree.itemDoubleClicked.connect(self.on_left_tree_double_click)
|
||||||
|
self.vars_widget.setObjectName("LeftTable")
|
||||||
|
self.selected_vars_widget = var_selector_table.VariableSelectWidget(self)
|
||||||
|
self.selected_vars_widget.tree.itemDoubleClicked.connect(self.on_rigth_tree_double_click)
|
||||||
|
self.selected_vars_widget.setObjectName("RightTable")
|
||||||
|
|
||||||
|
# Подписи над таблицами
|
||||||
|
label_all = QLabel("Все переменные")
|
||||||
|
label_all.setStyleSheet("font-weight: bold; font-size: 14px;")
|
||||||
|
|
||||||
|
label_selected = QLabel("Выбранные переменные")
|
||||||
|
label_selected.setStyleSheet("font-weight: bold; font-size: 14px;")
|
||||||
|
|
||||||
|
|
||||||
|
# --- Лэйауты ---
|
||||||
|
main_layout = QVBoxLayout(self) # главный вертикальный layout окна
|
||||||
|
|
||||||
|
# Чекбокс автодополнения — первый в главном layout
|
||||||
|
main_layout.addWidget(self.autocomplete_checkbox)
|
||||||
|
|
||||||
|
# Подписи над таблицами
|
||||||
|
labels_layout = QHBoxLayout()
|
||||||
|
labels_layout.addWidget(label_all)
|
||||||
|
labels_layout.addStretch()
|
||||||
|
labels_layout.addWidget(label_selected)
|
||||||
|
main_layout.addLayout(labels_layout)
|
||||||
|
|
||||||
|
# Горизонтальный layout с таблицами и кнопками
|
||||||
|
tables_layout = QHBoxLayout()
|
||||||
|
|
||||||
|
# Левая таблица
|
||||||
|
self.vars_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
tables_layout.addWidget(self.vars_widget)
|
||||||
|
|
||||||
|
# Кнопки ">" и "<" между таблицами
|
||||||
|
middle_buttons_layout = QVBoxLayout()
|
||||||
|
middle_buttons_layout.addStretch()
|
||||||
|
middle_buttons_layout.addWidget(self.btn_right)
|
||||||
|
middle_buttons_layout.addWidget(self.btn_left)
|
||||||
|
middle_buttons_layout.addStretch()
|
||||||
|
tables_layout.addLayout(middle_buttons_layout)
|
||||||
|
|
||||||
|
# Правая таблица
|
||||||
|
self.selected_vars_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
tables_layout.addWidget(self.selected_vars_widget)
|
||||||
|
|
||||||
|
# Добавляем горизонтальный layout с таблицами в главный вертикальный
|
||||||
|
main_layout.addLayout(tables_layout)
|
||||||
|
|
||||||
|
# Кнопки "Добавить выбранные" и "Удалить выбранные" под таблицами
|
||||||
|
buttons_layout = QVBoxLayout()
|
||||||
|
buttons_layout.addWidget(self.btn_accept)
|
||||||
|
main_layout.addLayout(buttons_layout)
|
||||||
|
|
||||||
|
# Важно, если окно — QDialog или QWidget, установи layout
|
||||||
|
self.setLayout(main_layout)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Соединяем сигналы кнопок с методами диалога
|
||||||
|
self.btn_accept.clicked.connect(self.on_apply_clicked)
|
||||||
|
|
||||||
|
# Соединяем чекбокс с методом виджета
|
||||||
|
self.autocomplete_checkbox.stateChanged.connect(self.set_autocomplete_tables)
|
||||||
|
# Устанавливаем начальное состояние автодополнения в виджете
|
||||||
|
self.vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked())
|
||||||
|
self.selected_vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked())
|
||||||
|
|
||||||
|
# --- Код в конце __init__ ---
|
||||||
|
self.expanded_vars = var_setup.expand_vars(self.all_vars, self.structs, self.typedefs)
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
def on_move_right(self):
|
||||||
|
# Устанавливаем show_var=True для всех выбранных переменных из ЛЕВОЙ таблицы
|
||||||
|
selected = self.vars_widget._get_internal_selected_var_names()
|
||||||
|
if not selected:
|
||||||
|
return
|
||||||
|
|
||||||
|
def mark_selected_show_var(data):
|
||||||
|
for var in data:
|
||||||
|
if var['name'] in selected:
|
||||||
|
var['show_var'] = 'true'
|
||||||
|
var['enable'] = 'true'
|
||||||
|
if 'children' in var:
|
||||||
|
mark_selected_show_var(var['children'])
|
||||||
|
mark_selected_show_var(self.expanded_vars)
|
||||||
|
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
def on_move_left(self):
|
||||||
|
# Сбрасываем show_var=False для всех выбранных переменных из ПРАВОЙ таблицы
|
||||||
|
selected = self.selected_vars_widget._get_internal_selected_var_names()
|
||||||
|
if not selected:
|
||||||
|
return
|
||||||
|
|
||||||
|
def mark_selected_hide_var(data):
|
||||||
|
for var in data:
|
||||||
|
if var['name'] in selected:
|
||||||
|
var['show_var'] = 'false'
|
||||||
|
if 'children' in var:
|
||||||
|
mark_selected_hide_var(var['children'])
|
||||||
|
mark_selected_hide_var(self.expanded_vars)
|
||||||
|
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
def update_vars_widget(self):
|
||||||
|
t_start = time.perf_counter()
|
||||||
|
|
||||||
|
t1 = time.perf_counter()
|
||||||
|
self.selected_vars, self.unselected_vars = var_setup.split_vars_by_show_flag(self.expanded_vars)
|
||||||
|
|
||||||
|
t2 = time.perf_counter()
|
||||||
|
self.vars_widget.set_data(self.unselected_vars)
|
||||||
|
|
||||||
|
t3 = time.perf_counter()
|
||||||
|
self.vars_widget.filter_tree()
|
||||||
|
|
||||||
|
t4 = time.perf_counter()
|
||||||
|
self.selected_vars_widget.set_data(self.selected_vars)
|
||||||
|
|
||||||
|
t5 = time.perf_counter()
|
||||||
|
self.selected_vars_widget.filter_tree()
|
||||||
|
|
||||||
|
def on_apply_clicked(self):
|
||||||
|
# Получаем имена всех переменных из правой таблицы (selected_vars_widget)
|
||||||
|
right_var_names = set(self.selected_vars_widget.get_all_var_names())
|
||||||
|
all_items = self.selected_vars_widget.get_all_items()
|
||||||
|
if not all_items:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Устанавливаем show_var=true и enable=true для переменных из правой таблицы
|
||||||
|
def add_or_update_var(item):
|
||||||
|
name = item.text(0)
|
||||||
|
type_str = item.text(1)
|
||||||
|
|
||||||
|
if name in self.var_map:
|
||||||
|
var = self.var_map[name]
|
||||||
|
var['show_var'] = 'true'
|
||||||
|
var['enable'] = 'true'
|
||||||
|
else:
|
||||||
|
file_val = item.data(0, Qt.UserRole + 1)
|
||||||
|
extern_val = item.data(0, Qt.UserRole + 2)
|
||||||
|
static_val = item.data(0, Qt.UserRole + 3)
|
||||||
|
new_var = {
|
||||||
|
'name': name,
|
||||||
|
'type': type_str,
|
||||||
|
'show_var': 'true',
|
||||||
|
'enable': 'true',
|
||||||
|
'shortname': name,
|
||||||
|
'pt_type': '',
|
||||||
|
'iq_type': 't_iq_none',
|
||||||
|
'return_type': 't_iq_none',
|
||||||
|
'file': file_val,
|
||||||
|
'extern': str(extern_val).lower() if extern_val else 'false',
|
||||||
|
'static': str(static_val).lower() if static_val else 'false',
|
||||||
|
}
|
||||||
|
self.all_vars.append(new_var)
|
||||||
|
self.var_map[name] = new_var
|
||||||
|
|
||||||
|
for item in all_items:
|
||||||
|
add_or_update_var(item)
|
||||||
|
|
||||||
|
# Сбрасываем show_var и enable у всех переменных, которых нет в правой таблице
|
||||||
|
for var in self.all_vars:
|
||||||
|
if var['name'] not in right_var_names:
|
||||||
|
var['show_var'] = 'false'
|
||||||
|
var['enable'] = 'false'
|
||||||
|
|
||||||
|
# Обновляем expanded_vars чтобы отразить новые show_var и enable
|
||||||
|
def update_expanded_vars(data):
|
||||||
|
for v in data:
|
||||||
|
name = v['name']
|
||||||
|
if name in self.var_map:
|
||||||
|
v['show_var'] = self.var_map[name]['show_var']
|
||||||
|
v['enable'] = self.var_map[name]['enable']
|
||||||
|
if 'children' in v:
|
||||||
|
update_expanded_vars(v['children'])
|
||||||
|
update_expanded_vars(self.expanded_vars)
|
||||||
|
|
||||||
|
# Обновляем отображение в виджетах
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
# Закрываем диалог
|
||||||
|
self.accept()
|
||||||
|
|
||||||
|
|
||||||
|
# Обнови on_left_tree_double_click:
|
||||||
|
def on_left_tree_double_click(self, item, column):
|
||||||
|
selected_names = [item.text(0)]
|
||||||
|
if not selected_names:
|
||||||
|
return
|
||||||
|
|
||||||
|
def mark_selected_show_var(data):
|
||||||
|
for var in data:
|
||||||
|
if var['name'] in selected_names:
|
||||||
|
var['show_var'] = 'true'
|
||||||
|
var['enable'] = 'true'
|
||||||
|
if 'children' in var:
|
||||||
|
mark_selected_show_var(var['children'])
|
||||||
|
mark_selected_show_var(self.expanded_vars)
|
||||||
|
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
# Добавь обработчик двойного клика справа (если нужно):
|
||||||
|
def on_rigth_tree_double_click(self, item, column):
|
||||||
|
selected_names = [item.text(0)]
|
||||||
|
if not selected_names:
|
||||||
|
return
|
||||||
|
|
||||||
|
def mark_selected_hide_var(data):
|
||||||
|
for var in data:
|
||||||
|
if var['name'] in selected_names:
|
||||||
|
var['show_var'] = 'false'
|
||||||
|
if 'children' in var:
|
||||||
|
mark_selected_hide_var(var['children'])
|
||||||
|
mark_selected_hide_var(self.expanded_vars)
|
||||||
|
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def keyPressEvent(self, event):
|
||||||
|
if event.key() == Qt.Key_Delete:
|
||||||
|
self.delete_selected_vars()
|
||||||
|
else:
|
||||||
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
|
def delete_selected_vars(self):
|
||||||
|
selected_names = self._get_selected_var_names()
|
||||||
|
if not selected_names:
|
||||||
|
print("nothing selected")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Обновляем var_map и all_vars
|
||||||
|
for name in selected_names:
|
||||||
|
if name in self.var_map:
|
||||||
|
self.var_map[name]['show_var'] = 'false'
|
||||||
|
self.var_map[name]['enable'] = 'false'
|
||||||
|
|
||||||
|
for v in self.all_vars:
|
||||||
|
if v['name'] == name:
|
||||||
|
v['show_var'] = 'false'
|
||||||
|
v['enable'] = 'false'
|
||||||
|
break
|
||||||
|
|
||||||
|
# Проверка пути к XML
|
||||||
|
if not hasattr(self, 'xml_path') or not self.xml_path:
|
||||||
|
from PySide2.QtWidgets import QMessageBox
|
||||||
|
#QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.")
|
||||||
|
return
|
||||||
|
|
||||||
|
root, tree = myXML.safe_parse_xml(self.xml_path)
|
||||||
|
if root is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
vars_section = root.find('variables')
|
||||||
|
if vars_section is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
for var_elem in vars_section.findall('var'):
|
||||||
|
name = var_elem.attrib.get('name')
|
||||||
|
if name in selected_names:
|
||||||
|
def set_text(tag, value):
|
||||||
|
el = var_elem.find(tag)
|
||||||
|
if el is None:
|
||||||
|
el = ET.SubElement(var_elem, tag)
|
||||||
|
el.text = value
|
||||||
|
set_text('show_var', 'false')
|
||||||
|
set_text('enable', 'false')
|
||||||
|
|
||||||
|
myXML.fwrite(root, self.xml_path)
|
||||||
|
|
||||||
|
self.table.populate(self.all_vars, self.structs, None)
|
||||||
|
|
||||||
|
# Проверка пути к XML
|
||||||
|
if not hasattr(self, 'xml_path') or not self.xml_path:
|
||||||
|
from PySide2.QtWidgets import QMessageBox
|
||||||
|
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно удалить переменные.")
|
||||||
|
return
|
||||||
|
|
||||||
|
root, tree = myXML.safe_parse_xml(self.xml_path)
|
||||||
|
if root is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
vars_section = root.find('variables')
|
||||||
|
if vars_section is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
removed_any = False
|
||||||
|
for var_elem in list(vars_section.findall('var')):
|
||||||
|
name = var_elem.attrib.get('name')
|
||||||
|
if name in selected_names:
|
||||||
|
vars_section.remove(var_elem)
|
||||||
|
removed_any = True
|
||||||
|
self.var_map.pop(name, None)
|
||||||
|
|
||||||
|
# Удаляем из all_vars (глобально)
|
||||||
|
self.all_vars[:] = [v for v in self.all_vars if v['name'] not in selected_names]
|
||||||
|
|
||||||
|
# Удаляем из expanded_vars (тоже глобально)
|
||||||
|
def filter_out_selected(vars_list):
|
||||||
|
filtered = []
|
||||||
|
for v in vars_list:
|
||||||
|
if v['name'] not in selected_names:
|
||||||
|
# Рекурсивно фильтруем детей, если есть
|
||||||
|
if 'children' in v:
|
||||||
|
v = v.copy()
|
||||||
|
v['children'] = filter_out_selected(v['children'])
|
||||||
|
filtered.append(v)
|
||||||
|
return filtered
|
||||||
|
|
||||||
|
self.expanded_vars[:] = filter_out_selected(self.expanded_vars)
|
||||||
|
if removed_any:
|
||||||
|
myXML.fwrite(root, self.xml_path)
|
||||||
|
|
||||||
|
self.update_vars_widget()
|
||||||
|
|
||||||
|
def _get_selected_var_names(self):
|
||||||
|
focused = self.focusWidget()
|
||||||
|
if focused and focused is self.vars_widget.tree:
|
||||||
|
return self.vars_widget.get_selected_var_names()
|
||||||
|
elif focused and focused is self.selected_vars_widget.tree:
|
||||||
|
return self.selected_vars_widget.get_selected_var_names()
|
||||||
|
else:
|
||||||
|
return []
|
||||||
|
|
||||||
|
def save_checkbox_state(self):
|
||||||
|
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def set_autocomplete_tables(self, state):
|
||||||
|
self.vars_widget.set_autocomplete(state)
|
||||||
|
self.selected_vars_widget.set_autocomplete(state)
|
||||||
@@ -1,11 +1,63 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import xml.etree.ElementTree as ET
|
import lxml.etree as ET
|
||||||
from generateVars import map_type_to_pt, get_iq_define, type_map
|
from generate_debug_vars import map_type_to_pt, get_iq_define, type_map
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import scanVars
|
import scan_vars
|
||||||
import myXML
|
import myXML
|
||||||
|
import pickle
|
||||||
|
|
||||||
|
|
||||||
|
# Вспомогательные функции, которые теперь будут использоваться виджетом
|
||||||
|
def split_path(path):
|
||||||
|
"""
|
||||||
|
Разбивает путь на компоненты:
|
||||||
|
- 'foo[2].bar[1]->baz' → ['foo', '[2]', 'bar', '[1]', 'baz']
|
||||||
|
Если видит '-' в конце строки (без '>' после) — обрезает этот '-'
|
||||||
|
"""
|
||||||
|
tokens = []
|
||||||
|
token = ''
|
||||||
|
i = 0
|
||||||
|
length = len(path)
|
||||||
|
while i < length:
|
||||||
|
c = path[i]
|
||||||
|
# Разделители: '->' и '.'
|
||||||
|
if c == '-' and i + 1 < length and path[i:i+2] == '->':
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
token = ''
|
||||||
|
i += 2
|
||||||
|
continue
|
||||||
|
elif c == '-' and i == length - 1:
|
||||||
|
# '-' на конце строки без '>' после — просто пропускаем его
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
elif c == '.':
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
token = ''
|
||||||
|
i += 1
|
||||||
|
continue
|
||||||
|
elif c == '[':
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
token = ''
|
||||||
|
idx = ''
|
||||||
|
while i < length and path[i] != ']':
|
||||||
|
idx += path[i]
|
||||||
|
i += 1
|
||||||
|
if i < length and path[i] == ']':
|
||||||
|
idx += ']'
|
||||||
|
i += 1
|
||||||
|
tokens.append(idx)
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
token += c
|
||||||
|
i += 1
|
||||||
|
if token:
|
||||||
|
tokens.append(token)
|
||||||
|
return tokens
|
||||||
|
|
||||||
|
|
||||||
def make_absolute_path(path, base_path):
|
def make_absolute_path(path, base_path):
|
||||||
@@ -86,7 +138,7 @@ def parse_vars(filename, typedef_map=None):
|
|||||||
'shortname': var.findtext('shortname', name),
|
'shortname': var.findtext('shortname', name),
|
||||||
'pt_type': pt_type,
|
'pt_type': pt_type,
|
||||||
'iq_type': iq_type,
|
'iq_type': iq_type,
|
||||||
'return_type': var.findtext('return_type', 'int'),
|
'return_type': var.findtext('return_type', 't_iq_none'),
|
||||||
'type': var_type,
|
'type': var_type,
|
||||||
'file': var.findtext('file', ''),
|
'file': var.findtext('file', ''),
|
||||||
'extern': var.findtext('extern', 'false') == 'true',
|
'extern': var.findtext('extern', 'false') == 'true',
|
||||||
@@ -239,7 +291,7 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
|
|||||||
return process_array(prefix, type_str, structs, typedefs, var_attrs, depth)
|
return process_array(prefix, type_str, structs, typedefs, var_attrs, depth)
|
||||||
|
|
||||||
# Ищем структуру по имени типа
|
# Ищем структуру по имени типа
|
||||||
base_type = scanVars.strip_ptr_and_array(type_str)
|
base_type = scan_vars.strip_ptr_and_array(type_str)
|
||||||
fields = structs.get(base_type)
|
fields = structs.get(base_type)
|
||||||
if not isinstance(fields, dict):
|
if not isinstance(fields, dict):
|
||||||
# Не структура и не массив — просто возвращаем пустой список
|
# Не структура и не массив — просто возвращаем пустой список
|
||||||
@@ -266,6 +318,12 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
|
|||||||
else:
|
else:
|
||||||
field_type_str = None
|
field_type_str = None
|
||||||
|
|
||||||
|
|
||||||
|
if '*' in field_type_str:
|
||||||
|
full_name_prefix = full_name + '*'
|
||||||
|
else:
|
||||||
|
full_name_prefix = full_name
|
||||||
|
|
||||||
# Обработка, если поле — строка (тип или массив)
|
# Обработка, если поле — строка (тип или массив)
|
||||||
if field_type_str:
|
if field_type_str:
|
||||||
base_subtype, sub_dims = parse_array_dims(field_type_str)
|
base_subtype, sub_dims = parse_array_dims(field_type_str)
|
||||||
@@ -311,7 +369,7 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
|
|||||||
|
|
||||||
if isinstance(field_value, dict):
|
if isinstance(field_value, dict):
|
||||||
# Это одиночная структура — раскрываем рекурсивно
|
# Это одиночная структура — раскрываем рекурсивно
|
||||||
sub_items = expand_struct_recursively(full_name, field_value, structs, typedefs, var_attrs, depth + 1)
|
sub_items = expand_struct_recursively(full_name_prefix, field_value, structs, typedefs, var_attrs, depth + 1)
|
||||||
child = {
|
child = {
|
||||||
'name': full_name,
|
'name': full_name,
|
||||||
'type': field_type_str,
|
'type': field_type_str,
|
||||||
@@ -353,7 +411,7 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
|
|||||||
'extern': var_attrs.get('extern'),
|
'extern': var_attrs.get('extern'),
|
||||||
'static': var_attrs.get('static'),
|
'static': var_attrs.get('static'),
|
||||||
}
|
}
|
||||||
subchildren = expand_struct_recursively(full_name, field_value, structs, typedefs, var_attrs, depth + 1)
|
subchildren = expand_struct_recursively(full_name_prefix, field_value, structs, typedefs, var_attrs, depth + 1)
|
||||||
if subchildren:
|
if subchildren:
|
||||||
child['children'] = subchildren
|
child['children'] = subchildren
|
||||||
children.append(child)
|
children.append(child)
|
||||||
@@ -399,3 +457,163 @@ def expand_vars(vars_list, structs, typedefs):
|
|||||||
|
|
||||||
return expanded
|
return expanded
|
||||||
|
|
||||||
|
|
||||||
|
def build_full_names(parts, full_name):
|
||||||
|
"""
|
||||||
|
Восстанавливает вложенные полные имена из списка частей,
|
||||||
|
ориентируясь на оригинальное полное имя (с '.', '->' и индексами).
|
||||||
|
|
||||||
|
Пример:
|
||||||
|
parts = ['arr', '[0]', '[1]', 'ptr', 'val']
|
||||||
|
full_name = 'arr[0][1].ptr->val'
|
||||||
|
|
||||||
|
→ [
|
||||||
|
'arr',
|
||||||
|
'arr[0]',
|
||||||
|
'arr[0][1]',
|
||||||
|
'arr[0][1].ptr',
|
||||||
|
'arr[0][1].ptr->val'
|
||||||
|
]
|
||||||
|
"""
|
||||||
|
names = []
|
||||||
|
acc = ''
|
||||||
|
idx = 0
|
||||||
|
for part in parts:
|
||||||
|
pos = full_name.find(part, idx)
|
||||||
|
if pos == -1:
|
||||||
|
acc += part
|
||||||
|
else:
|
||||||
|
acc = full_name[:pos + len(part)]
|
||||||
|
idx = pos + len(part)
|
||||||
|
names.append(acc)
|
||||||
|
return names
|
||||||
|
|
||||||
|
def find_var_by_name(tree, name):
|
||||||
|
for var in tree:
|
||||||
|
if var.get('name') == name:
|
||||||
|
return var
|
||||||
|
if 'children' in var:
|
||||||
|
found = find_var_by_name(var['children'], name)
|
||||||
|
if found:
|
||||||
|
return found
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def add_to_nested_tree(tree, var, path_parts, full_names=None, depth=0, source_tree=None):
|
||||||
|
if not path_parts:
|
||||||
|
return
|
||||||
|
|
||||||
|
if full_names is None:
|
||||||
|
full_names = build_full_names(path_parts, var['name'])
|
||||||
|
|
||||||
|
current_name = full_names[depth]
|
||||||
|
|
||||||
|
for child in tree:
|
||||||
|
if child.get('name') == current_name:
|
||||||
|
if depth == len(path_parts) - 1:
|
||||||
|
child.update(var)
|
||||||
|
return
|
||||||
|
if 'children' not in child:
|
||||||
|
child['children'] = []
|
||||||
|
add_to_nested_tree(child['children'], var, path_parts, full_names, depth + 1, source_tree)
|
||||||
|
return
|
||||||
|
|
||||||
|
# Ищем в source_tree (expanded_vars) родительский узел по current_name
|
||||||
|
parent_data = {}
|
||||||
|
if source_tree:
|
||||||
|
parent_var = find_var_by_name(source_tree, current_name)
|
||||||
|
if parent_var:
|
||||||
|
# Копируем все поля кроме детей (children)
|
||||||
|
parent_data = {k: v for k, v in parent_var.items() if k != 'children'}
|
||||||
|
|
||||||
|
new_node = {
|
||||||
|
'name': current_name,
|
||||||
|
'children': []
|
||||||
|
}
|
||||||
|
|
||||||
|
# Обновляем new_node данными родителя
|
||||||
|
new_node.update(parent_data)
|
||||||
|
|
||||||
|
if depth == len(path_parts) - 1:
|
||||||
|
new_node.update(var)
|
||||||
|
else:
|
||||||
|
add_to_nested_tree(new_node['children'], var, path_parts, full_names, depth + 1, source_tree)
|
||||||
|
|
||||||
|
tree.append(new_node)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def split_vars_by_show_flag(expanded_vars):
|
||||||
|
unselected_vars = pickle.loads(pickle.dumps(expanded_vars, protocol=pickle.HIGHEST_PROTOCOL))
|
||||||
|
selected_vars = []
|
||||||
|
|
||||||
|
def find_and_remove(var_list, target_name):
|
||||||
|
"""Удаляет элемент по полному имени и возвращает его"""
|
||||||
|
for i, var in enumerate(var_list):
|
||||||
|
if var.get("name") == target_name:
|
||||||
|
return var_list.pop(i)
|
||||||
|
if 'children' in var:
|
||||||
|
found = find_and_remove(var['children'], target_name)
|
||||||
|
if found:
|
||||||
|
return found
|
||||||
|
return None
|
||||||
|
|
||||||
|
def collect_selected_nodes(var):
|
||||||
|
"""Рекурсивно возвращает все show_var=true узлы (включая поддерево)"""
|
||||||
|
nodes = []
|
||||||
|
if var.get('show_var', 'false').lower() == 'true':
|
||||||
|
nodes.append(var)
|
||||||
|
for child in var.get('children', []):
|
||||||
|
nodes.extend(collect_selected_nodes(child))
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
def exists_by_path(tree, full_name):
|
||||||
|
"""
|
||||||
|
Проверяет, существует ли переменная в дереве, следуя по частям пути (например: project → adc → status).
|
||||||
|
Каждая часть ('project', 'project.adc', ...) должна иметь точное совпадение с 'name' в узле.
|
||||||
|
"""
|
||||||
|
path_parts = split_path(full_name)
|
||||||
|
full_names = build_full_names(path_parts, full_name)
|
||||||
|
|
||||||
|
current_level = tree
|
||||||
|
for name in full_names:
|
||||||
|
found = False
|
||||||
|
for var in current_level:
|
||||||
|
if var.get('name') == name:
|
||||||
|
current_level = var.get('children', [])
|
||||||
|
found = True
|
||||||
|
break
|
||||||
|
if not found:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
selected_nodes = []
|
||||||
|
for var in expanded_vars:
|
||||||
|
full_name = var['name']
|
||||||
|
# Проверка: если имя содержит вложенность, но целиком есть в корне — пропускаем
|
||||||
|
if ('.' in full_name or '[' in full_name or '->' in full_name):
|
||||||
|
path_parts = split_path(full_name)
|
||||||
|
if exists_by_path(expanded_vars, full_name):
|
||||||
|
# Удалим лишнюю копию из корня unselected_vars
|
||||||
|
find_and_remove(unselected_vars, full_name)
|
||||||
|
else:
|
||||||
|
add_to_nested_tree(unselected_vars, var, path_parts, source_tree=expanded_vars)
|
||||||
|
find_and_remove(unselected_vars, full_name)
|
||||||
|
selected_nodes.extend(collect_selected_nodes(var))
|
||||||
|
|
||||||
|
for node in selected_nodes:
|
||||||
|
full_name = node['name']
|
||||||
|
|
||||||
|
|
||||||
|
path_parts = split_path(full_name)
|
||||||
|
|
||||||
|
# Вырезать из unselected_vars
|
||||||
|
removed = find_and_remove(unselected_vars, full_name)
|
||||||
|
if removed:
|
||||||
|
add_to_nested_tree(selected_vars, removed, path_parts, source_tree=expanded_vars)
|
||||||
|
else:
|
||||||
|
# вдруг удалённый родитель — создаём вручную
|
||||||
|
add_to_nested_tree(selected_vars, node, path_parts, source_tree=expanded_vars)
|
||||||
|
|
||||||
|
return selected_vars, unselected_vars
|
||||||
498
Src/var_table.py
Normal file
498
Src/var_table.py
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
from PySide2.QtWidgets import (
|
||||||
|
QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter,
|
||||||
|
QAbstractItemView, QHeaderView, QLabel, QSpacerItem, QSizePolicy, QSpinBox,
|
||||||
|
QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QScrollArea, QWidget
|
||||||
|
)
|
||||||
|
from PySide2.QtGui import QColor, QBrush, QPalette
|
||||||
|
from PySide2.QtCore import Qt, QSettings
|
||||||
|
from enum import IntEnum
|
||||||
|
from generate_debug_vars import type_map
|
||||||
|
import time
|
||||||
|
from typing import Dict, List
|
||||||
|
|
||||||
|
class rows(IntEnum):
|
||||||
|
No = 0
|
||||||
|
include = 1
|
||||||
|
name = 2
|
||||||
|
type = 3
|
||||||
|
pt_type = 4
|
||||||
|
iq_type = 5
|
||||||
|
ret_type = 6
|
||||||
|
short_name = 7
|
||||||
|
|
||||||
|
class FilterDialog(QDialog):
|
||||||
|
def __init__(self, parent, options, selected, title="Выберите значения"):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle(title)
|
||||||
|
self.resize(250, 300)
|
||||||
|
self.selected = set(selected)
|
||||||
|
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
|
||||||
|
scroll = QScrollArea(self)
|
||||||
|
scroll.setWidgetResizable(True)
|
||||||
|
container = QWidget()
|
||||||
|
scroll.setWidget(container)
|
||||||
|
|
||||||
|
self.checkboxes = []
|
||||||
|
vbox = QVBoxLayout(container)
|
||||||
|
|
||||||
|
for opt in options:
|
||||||
|
cb = QCheckBox(opt)
|
||||||
|
cb.setChecked(opt in self.selected)
|
||||||
|
vbox.addWidget(cb)
|
||||||
|
self.checkboxes.append(cb)
|
||||||
|
|
||||||
|
layout.addWidget(scroll)
|
||||||
|
|
||||||
|
btn_layout = QHBoxLayout()
|
||||||
|
btn_ok = QPushButton("OK")
|
||||||
|
btn_cancel = QPushButton("Отмена")
|
||||||
|
btn_layout.addWidget(btn_ok)
|
||||||
|
btn_layout.addWidget(btn_cancel)
|
||||||
|
|
||||||
|
layout.addLayout(btn_layout)
|
||||||
|
|
||||||
|
btn_ok.clicked.connect(self.accept)
|
||||||
|
btn_cancel.clicked.connect(self.reject)
|
||||||
|
|
||||||
|
def get_selected(self):
|
||||||
|
return [cb.text() for cb in self.checkboxes if cb.isChecked()]
|
||||||
|
|
||||||
|
|
||||||
|
class SetSizeDialog(QDialog):
|
||||||
|
"""
|
||||||
|
Диалоговое окно для выбора числового значения (размера).
|
||||||
|
"""
|
||||||
|
def __init__(self, parent=None, initial_value=10, min_value=1, max_value=50, title="Укажите размер короткого имени",
|
||||||
|
label_text="Количество символов:"):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle(title)
|
||||||
|
self.setFixedSize(320, 120) # Задаем фиксированный размер для аккуратного вида
|
||||||
|
|
||||||
|
# Основной вертикальный макет
|
||||||
|
main_layout = QVBoxLayout(self)
|
||||||
|
|
||||||
|
# Макет для ввода значения
|
||||||
|
input_layout = QHBoxLayout()
|
||||||
|
label = QLabel(label_text, self)
|
||||||
|
|
||||||
|
self.spin_box = QSpinBox(self)
|
||||||
|
self.spin_box.setRange(min_value, max_value) # Устанавливаем диапазон допустимых значений
|
||||||
|
initial_value = parent._shortname_size
|
||||||
|
self.spin_box.setValue(initial_value) # Устанавливаем начальное значение
|
||||||
|
self.spin_box.setFocus() # Устанавливаем фокус на поле ввода
|
||||||
|
|
||||||
|
input_layout.addWidget(label)
|
||||||
|
input_layout.addWidget(self.spin_box)
|
||||||
|
main_layout.addLayout(input_layout)
|
||||||
|
|
||||||
|
# Добавляем пустое пространство для лучшего разделения
|
||||||
|
main_layout.addSpacerItem(QSpacerItem(20, 20, QSizePolicy.Minimum, QSizePolicy.Expanding))
|
||||||
|
|
||||||
|
# Макет для кнопок
|
||||||
|
btn_layout = QHBoxLayout()
|
||||||
|
btn_layout.addStretch() # Добавляем растягивающийся элемент, чтобы кнопки были справа
|
||||||
|
|
||||||
|
btn_ok = QPushButton("OK")
|
||||||
|
btn_cancel = QPushButton("Отмена")
|
||||||
|
|
||||||
|
btn_layout.addWidget(btn_ok)
|
||||||
|
btn_layout.addWidget(btn_cancel)
|
||||||
|
|
||||||
|
main_layout.addLayout(btn_layout)
|
||||||
|
|
||||||
|
# Подключение сигналов к слотам
|
||||||
|
btn_ok.clicked.connect(self.accept) # При нажатии "OK" диалог закроется со статусом "Accepted"
|
||||||
|
btn_cancel.clicked.connect(self.reject) # При нажатии "Отмена" - со статусом "Rejected"
|
||||||
|
|
||||||
|
def get_selected_size(self):
|
||||||
|
"""
|
||||||
|
Возвращает значение, выбранное в QSpinBox.
|
||||||
|
"""
|
||||||
|
return self.spin_box.value()
|
||||||
|
|
||||||
|
class CtrlScrollComboBox(QComboBox):
|
||||||
|
def wheelEvent(self, event):
|
||||||
|
if event.modifiers() & Qt.ControlModifier:
|
||||||
|
super().wheelEvent(event)
|
||||||
|
else:
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
|
class VariableTableWidget(QTableWidget):
|
||||||
|
def __init__(self, parent=None, show_value_instead_of_shortname=0):
|
||||||
|
# Таблица переменных
|
||||||
|
if show_value_instead_of_shortname:
|
||||||
|
super().__init__(0, 8, parent)
|
||||||
|
self.setHorizontalHeaderLabels([
|
||||||
|
'№',
|
||||||
|
'En',
|
||||||
|
'Name',
|
||||||
|
'Origin Type',
|
||||||
|
'Base Type',
|
||||||
|
'IQ Type',
|
||||||
|
'Return Type',
|
||||||
|
'Value'
|
||||||
|
])
|
||||||
|
self._show_value = True
|
||||||
|
else:
|
||||||
|
super().__init__(0, 8, parent)
|
||||||
|
self.setHorizontalHeaderLabels([
|
||||||
|
'№',
|
||||||
|
'En',
|
||||||
|
'Name',
|
||||||
|
'Origin Type',
|
||||||
|
'Base Type',
|
||||||
|
'IQ Type',
|
||||||
|
'Return Type',
|
||||||
|
'Short Name'
|
||||||
|
])
|
||||||
|
self._show_value = False
|
||||||
|
self.setEditTriggers(QAbstractItemView.AllEditTriggers)
|
||||||
|
self.var_list = []
|
||||||
|
|
||||||
|
# QSettings
|
||||||
|
self.settings = QSettings("SET", "DebugVarEdit_VarTable")
|
||||||
|
shortsize = self.settings.value("shortname_size", True, type=int)
|
||||||
|
self._shortname_size = shortsize
|
||||||
|
|
||||||
|
if(self._show_value):
|
||||||
|
self._shortname_size = 3
|
||||||
|
|
||||||
|
self.type_options = list(dict.fromkeys(type_map.values()))
|
||||||
|
self.pt_types_all = [t.replace('pt_', '') for t in self.type_options]
|
||||||
|
self.iq_types_all = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
|
||||||
|
self.iq_types = ['iq_none', 'iq', 'iq10', 'iq15', 'iq19', 'iq24']
|
||||||
|
type_options = [t for t in dict.fromkeys(type_map.values()) if 'arr' not in t and 'ptr' not in t
|
||||||
|
and 'struct' not in t and 'union' not in t and '64' not in t]
|
||||||
|
self.pt_types = [t.replace('pt_', '') for t in type_options]
|
||||||
|
|
||||||
|
self._iq_type_filter = list(self.iq_types)
|
||||||
|
self._pt_type_filter = list(self.pt_types)
|
||||||
|
self._ret_type_filter = list(self.iq_types)
|
||||||
|
|
||||||
|
header = self.horizontalHeader()
|
||||||
|
for col in range(self.columnCount()):
|
||||||
|
if col == self.columnCount() - 1:
|
||||||
|
header.setSectionResizeMode(col, QHeaderView.Stretch)
|
||||||
|
else:
|
||||||
|
header.setSectionResizeMode(col, QHeaderView.Interactive)
|
||||||
|
|
||||||
|
self.setColumnWidth(rows.No, 30)
|
||||||
|
self.setColumnWidth(rows.include, 30)
|
||||||
|
self.setColumnWidth(rows.pt_type, 85)
|
||||||
|
self.setColumnWidth(rows.iq_type, 85)
|
||||||
|
self.setColumnWidth(rows.ret_type, 85)
|
||||||
|
self.setColumnWidth(rows.name, 300)
|
||||||
|
self.setColumnWidth(rows.type, 100)
|
||||||
|
|
||||||
|
self._resizing = False
|
||||||
|
self.horizontalHeader().sectionResized.connect(self.on_section_resized)
|
||||||
|
self.horizontalHeader().sectionClicked.connect(self.on_header_clicked)
|
||||||
|
|
||||||
|
def populate(self, vars_list, structs, on_change_callback):
|
||||||
|
self.var_list = vars_list
|
||||||
|
self.setUpdatesEnabled(False)
|
||||||
|
self.blockSignals(True)
|
||||||
|
|
||||||
|
for var in vars_list:
|
||||||
|
pt_type = var.get('pt_type', '')
|
||||||
|
if 'struct' in pt_type or 'union' in pt_type:
|
||||||
|
var['show_var'] = 'false'
|
||||||
|
var['enable'] = 'false'
|
||||||
|
|
||||||
|
filtered_vars = [v for v in vars_list if v.get('show_var', 'false') == 'true']
|
||||||
|
self.setRowCount(len(filtered_vars))
|
||||||
|
self.verticalHeader().setVisible(False)
|
||||||
|
style_with_padding = "padding-left: 5px; padding-right: 5px; font-size: 14pt; font-family: 'Segoe UI';"
|
||||||
|
|
||||||
|
for row, var in enumerate(filtered_vars):
|
||||||
|
# №
|
||||||
|
no_item = QTableWidgetItem(str(row))
|
||||||
|
no_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
||||||
|
self.setItem(row, rows.No, no_item)
|
||||||
|
|
||||||
|
# Enable
|
||||||
|
cb = QCheckBox()
|
||||||
|
cb.setChecked(var.get('enable', 'false') == 'true')
|
||||||
|
cb.stateChanged.connect(on_change_callback)
|
||||||
|
cb.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.include, cb)
|
||||||
|
|
||||||
|
# Name
|
||||||
|
name_edit = QLineEdit(var['name'])
|
||||||
|
name_edit.textChanged.connect(on_change_callback)
|
||||||
|
name_edit.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.name, name_edit)
|
||||||
|
|
||||||
|
# Origin Type
|
||||||
|
origin_item = QTableWidgetItem(var.get('type', ''))
|
||||||
|
origin_item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
||||||
|
origin_item.setToolTip(var.get('type', ''))
|
||||||
|
origin_item.setForeground(QBrush(Qt.black))
|
||||||
|
self.setItem(row, rows.type, origin_item)
|
||||||
|
|
||||||
|
# pt_type
|
||||||
|
pt_combo = CtrlScrollComboBox()
|
||||||
|
pt_combo.addItems(self.pt_types)
|
||||||
|
value = var.get('pt_type', 'unknown').replace('pt_', '')
|
||||||
|
if value not in self.pt_types:
|
||||||
|
pt_combo.addItem(value)
|
||||||
|
pt_combo.setCurrentText(value)
|
||||||
|
pt_combo.currentTextChanged.connect(on_change_callback)
|
||||||
|
pt_combo.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.pt_type, pt_combo)
|
||||||
|
|
||||||
|
# iq_type
|
||||||
|
iq_combo = CtrlScrollComboBox()
|
||||||
|
iq_combo.addItems(self.iq_types)
|
||||||
|
value = var.get('iq_type', 'iq_none').replace('t_', '')
|
||||||
|
if value not in self.iq_types:
|
||||||
|
iq_combo.addItem(value)
|
||||||
|
iq_combo.setCurrentText(value)
|
||||||
|
iq_combo.currentTextChanged.connect(on_change_callback)
|
||||||
|
iq_combo.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.iq_type, iq_combo)
|
||||||
|
|
||||||
|
# return_type
|
||||||
|
ret_combo = CtrlScrollComboBox()
|
||||||
|
ret_combo.addItems(self.iq_types)
|
||||||
|
value = var.get('return_type', 'iq_none').replace('t_', '')
|
||||||
|
if value not in self.iq_types:
|
||||||
|
ret_combo.addItem(value)
|
||||||
|
ret_combo.setCurrentText(value)
|
||||||
|
ret_combo.currentTextChanged.connect(on_change_callback)
|
||||||
|
ret_combo.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.ret_type, ret_combo)
|
||||||
|
|
||||||
|
# Последний столбец
|
||||||
|
if self._show_value:
|
||||||
|
if self._show_value:
|
||||||
|
val = var.get('value', '')
|
||||||
|
if val is None:
|
||||||
|
val = ''
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
f_val = float(val)
|
||||||
|
# Форматируем число с учетом self._shortname_size
|
||||||
|
if f_val.is_integer():
|
||||||
|
val = str(int(f_val))
|
||||||
|
else:
|
||||||
|
precision = getattr(self, "_shortname_size", 3) # по умолчанию 3
|
||||||
|
val = f"{f_val:.{precision}f}"
|
||||||
|
except ValueError:
|
||||||
|
# Если значение не число (строка и т.п.), оставляем как есть
|
||||||
|
val = str(val)
|
||||||
|
|
||||||
|
val_edit = QLineEdit(val)
|
||||||
|
val_edit.textChanged.connect(on_change_callback)
|
||||||
|
val_edit.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.short_name, val_edit)
|
||||||
|
else:
|
||||||
|
short_name_val = var.get('shortname', var['name'])
|
||||||
|
short_name_edit = QLineEdit(short_name_val)
|
||||||
|
short_name_edit.textChanged.connect(on_change_callback)
|
||||||
|
short_name_edit.setStyleSheet(style_with_padding)
|
||||||
|
self.setCellWidget(row, rows.short_name, short_name_edit)
|
||||||
|
|
||||||
|
self.blockSignals(False)
|
||||||
|
self.setUpdatesEnabled(True)
|
||||||
|
self.check()
|
||||||
|
|
||||||
|
def check(self):
|
||||||
|
warning_color = QColor("#FFFACD")
|
||||||
|
error_color = QColor("#FFB6C1")
|
||||||
|
tooltip_shortname = "Short Name длиннее 10 символов — будет обрезано при генерации"
|
||||||
|
tooltip_missing = 'Имя переменной не найдено среди переменных. Добавьте её через кнопку "Добавить переменные"'
|
||||||
|
|
||||||
|
var_names_set = {v.get('name') for v in self.var_list if v.get('name')}
|
||||||
|
|
||||||
|
t0 = time.time()
|
||||||
|
self.setUpdatesEnabled(False)
|
||||||
|
for row in range(self.rowCount()):
|
||||||
|
t1 = time.time()
|
||||||
|
name_widget = self.cellWidget(row, rows.name)
|
||||||
|
t2 = time.time()
|
||||||
|
name = name_widget.text() if name_widget else ""
|
||||||
|
|
||||||
|
short_name_edit = self.cellWidget(row, rows.short_name)
|
||||||
|
t3 = time.time()
|
||||||
|
shortname = short_name_edit.text() if short_name_edit else ""
|
||||||
|
|
||||||
|
long_shortname = len(shortname) > self._shortname_size
|
||||||
|
found = name in var_names_set
|
||||||
|
|
||||||
|
color = None
|
||||||
|
tooltip = ""
|
||||||
|
if not found:
|
||||||
|
color = error_color
|
||||||
|
tooltip = tooltip_missing
|
||||||
|
elif long_shortname:
|
||||||
|
if not self._show_value:
|
||||||
|
color = warning_color
|
||||||
|
tooltip = tooltip_shortname
|
||||||
|
|
||||||
|
self.highlight_row(row, color, tooltip)
|
||||||
|
t4 = time.time()
|
||||||
|
|
||||||
|
self.setUpdatesEnabled(True)
|
||||||
|
#print(f"Row {row}: cellWidget(name) {t2-t1:.4f}s, cellWidget(shortname) {t3-t2:.4f}s, highlight_row {t4-t3:.4f}s")
|
||||||
|
|
||||||
|
|
||||||
|
def read_data(self):
|
||||||
|
result = []
|
||||||
|
for row in range(self.rowCount()):
|
||||||
|
cb = self.cellWidget(row, rows.include)
|
||||||
|
name = self.cellWidget(row, rows.name).text()
|
||||||
|
pt = self.cellWidget(row, rows.pt_type).currentText()
|
||||||
|
iq = self.cellWidget(row, rows.iq_type).currentText()
|
||||||
|
ret = self.cellWidget(row, rows.ret_type).currentText()
|
||||||
|
shortname = self.cellWidget(row, rows.short_name).text()
|
||||||
|
origin_type = self.item(row, rows.type).text()
|
||||||
|
|
||||||
|
result.append({
|
||||||
|
'show_var': True,
|
||||||
|
'enable': cb.isChecked(),
|
||||||
|
'name': name,
|
||||||
|
'pt_type': f'pt_{pt}',
|
||||||
|
'iq_type': f't_{iq}',
|
||||||
|
'return_type': f't_{ret}',
|
||||||
|
'shortname': shortname,
|
||||||
|
'type': origin_type,
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def on_header_clicked(self, logicalIndex):
|
||||||
|
if logicalIndex == rows.pt_type:
|
||||||
|
dlg = FilterDialog(self, self.pt_types_all, self._pt_type_filter, "Выберите базовые типы")
|
||||||
|
if dlg.exec_():
|
||||||
|
self._pt_type_filter = dlg.get_selected()
|
||||||
|
self.update_comboboxes({rows.pt_type: self._pt_type_filter})
|
||||||
|
|
||||||
|
elif logicalIndex == rows.iq_type:
|
||||||
|
dlg = FilterDialog(self, self.iq_types_all, self._iq_type_filter, "Выберите IQ типы")
|
||||||
|
if dlg.exec_():
|
||||||
|
self._iq_type_filter = dlg.get_selected()
|
||||||
|
self.update_comboboxes({rows.iq_type: self._iq_type_filter})
|
||||||
|
|
||||||
|
elif logicalIndex == rows.ret_type:
|
||||||
|
dlg = FilterDialog(self, self.iq_types_all, self._ret_type_filter, "Выберите IQ типы")
|
||||||
|
if dlg.exec_():
|
||||||
|
self._ret_type_filter = dlg.get_selected()
|
||||||
|
self.update_comboboxes({rows.ret_type: self._ret_type_filter})
|
||||||
|
|
||||||
|
elif logicalIndex == rows.short_name:
|
||||||
|
if self._show_value:
|
||||||
|
dlg = SetSizeDialog(self, title="Укажите точность", label_text="Кол-во знаков после запятой", initial_value=3)
|
||||||
|
else:
|
||||||
|
dlg = SetSizeDialog(self)
|
||||||
|
|
||||||
|
if dlg.exec_():
|
||||||
|
self._shortname_size = dlg.get_selected_size()
|
||||||
|
if not self._show_value:
|
||||||
|
self.settings.setValue("shortname_size", self._shortname_size)
|
||||||
|
self.check()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def update_comboboxes(self, columns_filters: Dict[int, List[str]]):
|
||||||
|
"""
|
||||||
|
Обновляет combobox-ячейки в указанных столбцах таблицы.
|
||||||
|
|
||||||
|
:param columns_filters: dict, где ключ — индекс столбца,
|
||||||
|
значение — список допустимых вариантов для combobox.
|
||||||
|
"""
|
||||||
|
for row in range(self.rowCount()):
|
||||||
|
for col, allowed_items in columns_filters.items():
|
||||||
|
combo = self.cellWidget(row, col)
|
||||||
|
if combo:
|
||||||
|
current = combo.currentText()
|
||||||
|
combo.blockSignals(True)
|
||||||
|
combo.clear()
|
||||||
|
|
||||||
|
combo.addItems(allowed_items)
|
||||||
|
if current not in allowed_items:
|
||||||
|
combo.addItem(current)
|
||||||
|
combo.setCurrentText(current)
|
||||||
|
combo.blockSignals(False)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def on_section_resized(self, logicalIndex, oldSize, newSize):
|
||||||
|
if self._resizing:
|
||||||
|
return # предотвращаем рекурсию
|
||||||
|
|
||||||
|
min_width = 50
|
||||||
|
delta = newSize - oldSize
|
||||||
|
right_index = logicalIndex + 1
|
||||||
|
|
||||||
|
if right_index >= self.columnCount():
|
||||||
|
# Если правая колока - нет соседа, ограничиваем минимальную ширину
|
||||||
|
if newSize < min_width:
|
||||||
|
self._resizing = True
|
||||||
|
self.setColumnWidth(logicalIndex, min_width)
|
||||||
|
self._resizing = False
|
||||||
|
return
|
||||||
|
|
||||||
|
self._resizing = True
|
||||||
|
try:
|
||||||
|
right_width = self.columnWidth(right_index)
|
||||||
|
new_right_width = right_width - delta
|
||||||
|
|
||||||
|
# Если соседняя колонка станет уже минимальной - подкорректируем левую
|
||||||
|
if new_right_width < min_width:
|
||||||
|
new_right_width = min_width
|
||||||
|
newSize = oldSize + (right_width - min_width)
|
||||||
|
self.setColumnWidth(logicalIndex, newSize)
|
||||||
|
|
||||||
|
self.setColumnWidth(right_index, new_right_width)
|
||||||
|
finally:
|
||||||
|
self._resizing = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def highlight_row(self, row: int, color: QColor = None, tooltip: str = ""):
|
||||||
|
"""
|
||||||
|
Подсвечивает строку таблицы цветом `color`, не меняя шрифт.
|
||||||
|
Работает с QLineEdit, QComboBox, QCheckBox (включая обёртки).
|
||||||
|
Если `color=None`, сбрасывает подсветку.
|
||||||
|
"""
|
||||||
|
css_reset = "background-color: none; font: inherit;"
|
||||||
|
css_color = f"background-color: {color.name()};" if color else css_reset
|
||||||
|
|
||||||
|
for col in range(self.columnCount()):
|
||||||
|
item = self.item(row, col)
|
||||||
|
widget = self.cellWidget(row, col)
|
||||||
|
|
||||||
|
if item is not None:
|
||||||
|
current_bg = item.background().color() if item.background() else None
|
||||||
|
if color and current_bg != color:
|
||||||
|
item.setBackground(QBrush(color))
|
||||||
|
item.setToolTip(tooltip)
|
||||||
|
elif not color and current_bg is not None:
|
||||||
|
item.setBackground(QBrush(Qt.NoBrush))
|
||||||
|
item.setToolTip("")
|
||||||
|
elif widget is not None:
|
||||||
|
if widget.styleSheet() != css_color:
|
||||||
|
widget.setStyleSheet(css_color)
|
||||||
|
current_tip = widget.toolTip()
|
||||||
|
if color and current_tip != tooltip:
|
||||||
|
widget.setToolTip(tooltip)
|
||||||
|
elif not color and current_tip:
|
||||||
|
widget.setToolTip("")
|
||||||
|
|
||||||
|
def get_selected_var_names(self):
|
||||||
|
selected_indexes = self.selectedIndexes()
|
||||||
|
selected_rows = set(index.row() for index in selected_indexes)
|
||||||
|
names = []
|
||||||
|
|
||||||
|
for row in selected_rows:
|
||||||
|
name_widget = self.cellWidget(row, rows.name)
|
||||||
|
if name_widget:
|
||||||
|
name = name_widget.text()
|
||||||
|
if name:
|
||||||
|
names.append(name)
|
||||||
|
return names
|
||||||
671
debug_tools.c
671
debug_tools.c
@@ -1,390 +1,416 @@
|
|||||||
#include "debug_tools.h"
|
#include "debug_tools.h"
|
||||||
#include "IQmathLib.h"
|
|
||||||
|
|
||||||
static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var);
|
#if !defined(GLOBAL_Q)
|
||||||
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var);
|
#define GLOBAL_Q 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
DebugLowLevel_t debug_ll = DEBUG_LOWLEVEL_INIT; ///< Ñòðóêòóðà îòëàäêè íèæíåãî óðîâíÿ (èíèöèàëèçàöèÿ)
|
||||||
|
|
||||||
|
static int getDebugVar(DebugVar_t *var, int32_t *int_var, float *float_var);
|
||||||
|
static int convertDebugVarToIQx(DebugVar_t *var, int32_t *ret_var);
|
||||||
|
static int iqTypeToQ(DebugVarIQType_t t);
|
||||||
|
static int is_addr_in_allowed_ranges(uint32_t addr_val, const AddrRange_t *ranges, int count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ìàññèâ äîïóñòèìûõ äèàïàçîíîâ àäðåñîâ äëÿ îòëàäî÷íîãî ÷òåíèÿ
|
||||||
|
*
|
||||||
|
* Âêëþ÷àåò â ñåáÿ íàáîð äèàïàçîíîâ ïàìÿòè, ðàçðåø¸ííûõ äëÿ äîñòóïà
|
||||||
|
* ôóíêöèåé Debug_LowLevel_ReadVar.
|
||||||
|
*/
|
||||||
|
static const AddrRange_t debug_allowed_ranges[] = ALLOWED_ADDRESS_RANGES;
|
||||||
|
/**
|
||||||
|
* @brief Êîëè÷åñòâî ýëåìåíòîâ â ìàññèâå debug_allowed_ranges
|
||||||
|
*/
|
||||||
|
static const int debug_allowed_ranges_count = sizeof(debug_allowed_ranges) / sizeof(debug_allowed_ranges[0]);
|
||||||
|
|
||||||
|
|
||||||
int Debug_LowLevel_ReadVar(DebugVar_t *var_ll, long *return_long)
|
///////////////////////////----EXAPLE-----//////////////////////////////
|
||||||
|
int var_numb = 1; ///< Ïðèìåð ïåðåìåííîé äëÿ îòëàäêè
|
||||||
|
DebugVarName_t var_name; ///< Èìÿ ïåðåìåííîé
|
||||||
|
int32_t return_var; ///< Ïåðåìåííàÿ äëÿ âîçâðàòà ðåçóëüòàòà
|
||||||
|
int32_t return_ll_var; ///< Âîçâðàùàåìîå çíà÷åíèå ñ íèæíåãî óðîâíÿ
|
||||||
|
int result; ///< Ïåðåìåííàÿ ðåçóëüòàòà
|
||||||
|
DateTime_t ext_date = {2025, 11, 07, 16, 50}; ///< Ïðèìåð âíåøíåé äàòû ñáîðêè
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ïðèìåð èñïîëüçîâàíèÿ ôóíêöèé îòëàäêè.
|
||||||
|
* @details Äåìîíñòðàöèîííàÿ ôóíêöèÿ äëÿ ðàáîòû ñ ïåðåìåííûìè îòëàäêè.
|
||||||
|
*/
|
||||||
|
void Debug_Test_Example(void)
|
||||||
{
|
{
|
||||||
if (var_ll == NULL)
|
return;
|
||||||
return 1;
|
result = Debug_ReadVar(var_numb, &return_var);
|
||||||
|
result = Debug_ReadVarName(var_numb, var_name, 0);
|
||||||
|
|
||||||
char *addr = var_ll->Ptr;
|
|
||||||
unsigned long addr_val = (unsigned long)addr;
|
|
||||||
// Ðàçðåø¸ííûå äèàïàçîíû ïàìÿòè íà TMS320F2812
|
|
||||||
if (!(
|
|
||||||
(addr_val <= 0x0007FF) || // RAMM0 + RAMM1
|
|
||||||
(addr_val >= 0x008000 && addr_val <= 0x009FFF) || // L0 + L1 SARAM
|
|
||||||
(addr_val >= 0x3F8000 && addr_val <= 0x3F9FFF) || // PRAMH0 + DRAMH0
|
|
||||||
(addr_val >= 0x3D8000 && addr_val <= 0x3EFFFF) || // Flash A-F
|
|
||||||
(addr_val >= 0x3FF000 && addr_val <= 0x3FFFFF) // Boot ROM / Reset
|
|
||||||
)) {
|
|
||||||
return 2; // àäðåñ âíå äîïóñòèìîãî äèàïàçîíà, èãíîðèðóåì
|
|
||||||
}
|
|
||||||
|
|
||||||
convertDebugVarToIQx(var_ll, return_long);
|
if(Debug_LowLevel_Initialize(&ext_date) == 0)
|
||||||
|
result = Debug_LowLevel_ReadVar(&return_ll_var);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////----PUBLIC-----//////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò ïåðåìåííóþ ïî èíäåêñó.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param return_32b – óêàçàòåëü äëÿ âîçâðàòà ðåçóëüòàòà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
* @details Èñïîëüçóåòñÿ äëÿ ÷òåíèÿ çíà÷åíèé ïåðåìåííûõ ïî èõ èíäåêñó.
|
||||||
|
*/
|
||||||
|
int Debug_ReadVar(int var_ind, int32_t *return_32b)
|
||||||
|
{
|
||||||
|
int32_t tmp_var;
|
||||||
|
|
||||||
|
if(return_32b == NULL)
|
||||||
|
return DEBUG_ERR_INTERNAL;
|
||||||
|
if (var_ind >= DebugVar_Qnt)
|
||||||
|
return DEBUG_ERR_VAR_NUMB;
|
||||||
|
if((dbg_vars[var_ind].ptr_type == pt_struct) || (dbg_vars[var_ind].ptr_type == pt_union) ||
|
||||||
|
(dbg_vars[var_ind].ptr_type == pt_unknown))
|
||||||
|
return DEBUG_ERR_INVALID_VAR;
|
||||||
|
|
||||||
|
return convertDebugVarToIQx(&dbg_vars[var_ind], return_32b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò âîçâðàùàåìûé òèï (IQ) ïåðåìåííîé ïî èíäåêñó.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param vartype – óêàçàòåëü äëÿ âîçâðàòà òèïà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
* @details Èñïîëüçóåòñÿ äëÿ ÷òåíèÿ âîçâðàùàåìîãî òèïà (IQ) ïåðåìåííûõ ïî èõ èíäåêñó.
|
||||||
|
*/
|
||||||
|
int Debug_ReadVarReturnType(int var_ind, int *vartype)
|
||||||
|
{
|
||||||
|
int rettype;
|
||||||
|
if(vartype == NULL)
|
||||||
|
return DEBUG_ERR_INTERNAL;
|
||||||
|
if (var_ind >= DebugVar_Qnt)
|
||||||
|
return DEBUG_ERR_VAR_NUMB;
|
||||||
|
if((dbg_vars[var_ind].ptr_type == pt_struct) || (dbg_vars[var_ind].ptr_type == pt_union) ||
|
||||||
|
(dbg_vars[var_ind].ptr_type == pt_unknown))
|
||||||
|
return DEBUG_ERR_INVALID_VAR;
|
||||||
|
|
||||||
|
*vartype = iqTypeToQ(dbg_vars[var_ind].return_type);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
int Debug_ReadVar(DebugVar_t *var, long *return_long)
|
* @brief ×èòàåò òèï ïåðåìåííîé ïî èíäåêñó.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param vartype – óêàçàòåëü äëÿ âîçâðàòà òèïà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
* @details Èñïîëüçóåòñÿ äëÿ ÷òåíèÿ òèïà ïåðåìåííûõ ïî èõ èíäåêñó.
|
||||||
|
*/
|
||||||
|
int Debug_ReadVarType(int var_ind, int *vartype)
|
||||||
{
|
{
|
||||||
long tmp_var;
|
int rettype;
|
||||||
if (var == NULL)
|
if(vartype == NULL)
|
||||||
return 1;
|
return DEBUG_ERR_INTERNAL;
|
||||||
if((var->ptr_type == pt_struct) || (var->ptr_type == pt_union) ||
|
if (var_ind >= DebugVar_Qnt)
|
||||||
(var->ptr_type == pt_unknown) || (var->return_type == pt_unknown))
|
return DEBUG_ERR_VAR_NUMB;
|
||||||
return 1;
|
if((dbg_vars[var_ind].ptr_type == pt_struct) || (dbg_vars[var_ind].ptr_type == pt_union) ||
|
||||||
|
(dbg_vars[var_ind].ptr_type == pt_unknown))
|
||||||
|
return DEBUG_ERR_INVALID_VAR;
|
||||||
|
|
||||||
convertDebugVarToIQx(var, return_long);
|
*vartype = dbg_vars[var_ind].ptr_type;
|
||||||
|
|
||||||
return 0;
|
switch(dbg_vars[var_ind].ptr_type)
|
||||||
}
|
|
||||||
|
|
||||||
int Debug_ReadVarName(DebugVar_t *var, char *name_ptr)
|
|
||||||
{
|
|
||||||
if((var == NULL)||(name_ptr == NULL))
|
|
||||||
return 1;
|
|
||||||
int i;
|
|
||||||
// Êîïèðîâàíèå ñ çàùèòîé îò ïåðåïîëíåíèÿ è ÿâíîé îñòàíîâêîé ïî '\0'
|
|
||||||
for (i = 0; i < sizeof(var->name); i++)
|
|
||||||
{
|
{
|
||||||
name_ptr[i] = var->name[i];
|
case pt_int8:
|
||||||
if (var->name[i] == '\0')
|
case pt_int16:
|
||||||
|
case pt_int32:
|
||||||
|
case pt_float:
|
||||||
|
*vartype = dbg_vars[var_ind].ptr_type | DEBUG_SIGNED_VAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*vartype = dbg_vars[var_ind].ptr_type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Ãàðàíòèðîâàííîå çàâåðøåíèå ñòðîêè (íà ñëó÷àé, åñëè â var->name íå áûëî '\0')
|
|
||||||
name_ptr[sizeof(var->name) - 1] = '\0';
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò èìÿ ïåðåìåííîé ïî èíäåêñó.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param name_ptr – óêàçàòåëü íà áóôåð èìåíè (DebugVarName_t).
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
* @details Êîïèðóåò èìÿ ïåðåìåííîé â ïðåäîñòàâëåííûé áóôåð.
|
||||||
|
*/
|
||||||
|
int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr, int *length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(name_ptr == NULL)
|
||||||
|
return DEBUG_ERR_INTERNAL;
|
||||||
|
|
||||||
|
if (var_ind >= DebugVar_Qnt)
|
||||||
|
return DEBUG_ERR_VAR_NUMB;
|
||||||
|
|
||||||
int Debug_LowLevel_Initialize(const uint8_t* external_date)
|
// Êîïèðîâàíèå ñ çàùèòîé îò ïåðåïîëíåíèÿ è ÿâíîé îñòàíîâêîé ïî '\0'
|
||||||
|
for (i = 0; i < sizeof(dbg_vars[var_ind].name); i++)
|
||||||
|
{
|
||||||
|
name_ptr[i] = dbg_vars[var_ind].name[i];
|
||||||
|
if (dbg_vars[var_ind].name[i] == '\0')
|
||||||
|
{
|
||||||
|
if(length != NULL)
|
||||||
|
*length = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Ãàðàíòèðîâàííîå çàâåðøåíèå ñòðîêè (íà ñëó÷àé, åñëè â var->name íå áûëî '\0')
|
||||||
|
name_ptr[sizeof(dbg_vars[var_ind].name) - 1] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò çíà÷åíèå ïåðåìåííîé îòëàäêè ñ íèæíåãî óðîâíÿ.
|
||||||
|
* @param return_32b – óêàçàòåëü íà ïåðåìåííóþ, êóäà çàïèñûâàåòñÿ ðåçóëüòàò.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà, 2: íåäîïóñòèìûé àäðåñ.
|
||||||
|
* @details Èñïîëüçóåò àäðåññ, ïåðåäàâàåìûé ñ òåðìèíàëêè äëÿ ïîëó÷åíèÿ çíà÷åíèÿ.
|
||||||
|
*/
|
||||||
|
int Debug_LowLevel_ReadVar(int32_t *return_32b)
|
||||||
|
{
|
||||||
|
uint8_t *addr = debug_ll.dbg_var.Ptr;
|
||||||
|
uint32_t addr_val = (uint32_t)addr;
|
||||||
|
|
||||||
|
if (return_32b == NULL)
|
||||||
|
return DEBUG_ERR_INTERNAL;
|
||||||
|
if (debug_ll.isVerified == 0)
|
||||||
|
return DEBUG_ERR_DATATIME;
|
||||||
|
|
||||||
|
if (is_addr_in_allowed_ranges(addr_val, debug_allowed_ranges, debug_allowed_ranges_count) != 0)
|
||||||
|
{
|
||||||
|
return DEBUG_ERR_ADDR; // Çàïðåù¸ííûé àäðåñ — íåëüçÿ ÷èòàòü
|
||||||
|
}
|
||||||
|
|
||||||
|
return convertDebugVarToIQx(&debug_ll.dbg_var, return_32b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Èíèöèàëèçàöèÿ îòëàäêè íà íèæíåì óðîâíå ïî äàòå ñáîðêè.
|
||||||
|
* @param external_date – ñòðóêòóðà ñ äàòîé DateTime_t
|
||||||
|
* @return int – 0: ñîâïàäàåò, 1: íå ñîâïàäàåò, -1: îøèáêà.
|
||||||
|
* @details Ñðàâíèâàåò äàòó êîìïèëÿöèè ñ çàïðàøèâàåìîé è èíèöèàëèçèðóåò îòëàäî÷íóþ ïåðåìåííóþ.
|
||||||
|
*/
|
||||||
|
int Debug_LowLevel_Initialize(DateTime_t* external_date)
|
||||||
{
|
{
|
||||||
if (external_date == NULL) {
|
if (external_date == NULL) {
|
||||||
return -1;
|
return DEBUG_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ïðåîáðàçóåì external_date â ñòðóêòóðó
|
|
||||||
DateTimeHex ext;
|
|
||||||
ext.year = (external_date[0] << 8) | external_date[1];
|
|
||||||
ext.month = external_date[2];
|
|
||||||
ext.day = external_date[3];
|
|
||||||
ext.hour = external_date[4];
|
|
||||||
ext.minute = external_date[5];
|
|
||||||
|
|
||||||
// Ïàðñèì BUILD_FULL_DATE "YYYYMMDD_HHMM"
|
|
||||||
DateTimeHex build;
|
|
||||||
char buf[5] = {0};
|
|
||||||
|
|
||||||
// Ãîä
|
|
||||||
memcpy(buf, BUILD_FULL_DATE + 0, 4);
|
|
||||||
build.year = (uint16_t)atoi(buf);
|
|
||||||
|
|
||||||
// Ìåñÿö
|
|
||||||
memcpy(buf, BUILD_FULL_DATE + 4, 2);
|
|
||||||
build.month = (uint8_t)atoi(buf);
|
|
||||||
|
|
||||||
// Äåíü
|
|
||||||
memcpy(buf, BUILD_FULL_DATE + 6, 2);
|
|
||||||
build.day = (uint8_t)atoi(buf);
|
|
||||||
|
|
||||||
// ×àñ
|
|
||||||
memcpy(buf, BUILD_FULL_DATE + 9, 2);
|
|
||||||
build.hour = (uint8_t)atoi(buf);
|
|
||||||
|
|
||||||
// Ìèíóòû
|
|
||||||
memcpy(buf, BUILD_FULL_DATE + 11, 2);
|
|
||||||
build.minute = (uint8_t)atoi(buf);
|
|
||||||
|
|
||||||
// Ñðàâíåíèå âñåõ ïîëåé
|
// Ñðàâíåíèå âñåõ ïîëåé
|
||||||
if (ext.year == build.year &&
|
if (external_date->year == debug_ll.build_date.year &&
|
||||||
ext.month == build.month &&
|
external_date->month == debug_ll.build_date.month &&
|
||||||
ext.day == build.day &&
|
external_date->day == debug_ll.build_date.day &&
|
||||||
ext.hour == build.hour &&
|
external_date->hour == debug_ll.build_date.hour &&
|
||||||
ext.minute == build.minute)
|
external_date->minute == debug_ll.build_date.minute)
|
||||||
{
|
{
|
||||||
|
debug_ll.isVerified = 1;
|
||||||
return 0; // Ñîâïàëî
|
return 0; // Ñîâïàëî
|
||||||
}
|
}
|
||||||
|
debug_ll.isVerified = 0;
|
||||||
|
|
||||||
return 1; // Íå ñîâïàëî
|
return DEBUG_ERR_DATATIME; // Íå ñîâïàëî
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò âîçâðàùàåìûé òèï (IQ) íèçêîóðîâíåíî çàäàííîé ïåðåìåííîé.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param vartype – óêàçàòåëü äëÿ âîçâðàòà òèïà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
* @details Èñïîëüçóåòñÿ äëÿ ÷òåíèÿ âîçâðàùàåìîãî òèïà (IQ) ïåðåìåííûõ ïî èõ èíäåêñó.
|
||||||
|
*/
|
||||||
|
int Debug_LowLevel_ReadVarReturnType(int *vartype)
|
||||||
|
{
|
||||||
|
int rettype;
|
||||||
|
if(vartype == NULL)
|
||||||
|
return DEBUG_ERR_INTERNAL;
|
||||||
|
if((debug_ll.dbg_var.ptr_type == pt_struct) || (debug_ll.dbg_var.ptr_type == pt_union) ||
|
||||||
|
(debug_ll.dbg_var.ptr_type == pt_unknown))
|
||||||
|
return DEBUG_ERR_INVALID_VAR;
|
||||||
|
|
||||||
|
*vartype = iqTypeToQ(debug_ll.dbg_var.return_type);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò òèï íèçêîóðîâíåíî çàäàííîé ïåðåìåííîé.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param vartype – óêàçàòåëü äëÿ âîçâðàòà òèïà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
*/
|
||||||
|
int Debug_LowLevel_ReadVarType(int *vartype)
|
||||||
|
{
|
||||||
|
int rettype;
|
||||||
|
if(vartype == NULL)
|
||||||
|
return DEBUG_ERR_INTERNAL;
|
||||||
|
if((debug_ll.dbg_var.ptr_type == pt_struct) || (debug_ll.dbg_var.ptr_type == pt_union) ||
|
||||||
|
(debug_ll.dbg_var.ptr_type == pt_unknown))
|
||||||
|
return DEBUG_ERR_INVALID_VAR;
|
||||||
|
|
||||||
|
*vartype = debug_ll.dbg_var.ptr_type;
|
||||||
|
|
||||||
|
switch(debug_ll.dbg_var.ptr_type)
|
||||||
|
{
|
||||||
|
case pt_int8:
|
||||||
|
case pt_int16:
|
||||||
|
case pt_int32:
|
||||||
|
case pt_float:
|
||||||
|
*vartype = debug_ll.dbg_var.ptr_type | DEBUG_SIGNED_VAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
*vartype = debug_ll.dbg_var.ptr_type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////----INTERNAL FUNCTIONS-----////////////////////////
|
/////////////////////----INTERNAL FUNCTIONS-----////////////////////////
|
||||||
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var)
|
/**
|
||||||
|
* @brief Ïðåîáðàçóåò òèï IQ ïåðåìåííîé â ÷èñëî áèòîâ äëÿ ñäâèãà(Q-ôàêòîð).
|
||||||
|
* @param t – òèï IQ (ïåðå÷èñëåíèå DebugVarIQType_t).
|
||||||
|
* @return int – Q-ôàêòîð (íàïðèìåð, 24), 0: åñëè t_iq_none, -1: îøèáêà.
|
||||||
|
* @details Ñîïîñòàâëÿåò òèï IQ ïåðåìåííîé ñ ñîîòâåòñòâóþùèì Q-çíà÷åíèåì.
|
||||||
|
*/
|
||||||
|
static int iqTypeToQ(DebugVarIQType_t t)
|
||||||
{
|
{
|
||||||
long iq_numb, iq_united, iq_final;
|
if (t == t_iq_none)
|
||||||
|
return 0; // áåç IQ, float, int
|
||||||
|
else if (t == t_iq)
|
||||||
|
return GLOBAL_Q; // îáùèé IQ, íàïðèìåð 24
|
||||||
|
else if (t >= t_iq1 && t <= t_iq30)
|
||||||
|
return (int)t - (int)t_iq1 + 1; // íàïðèìåð t_iq1 -> 1, t_iq2 -> 2 è ò.ä.
|
||||||
|
else
|
||||||
|
return 0; // îøèáêà
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ïðåîáðàçóåò ïåðåìåííóþ îòëàäêè â IQ ôîðìàò.
|
||||||
|
* @param var – óêàçàòåëü íà ïåðåìåííóþ îòëàäêè.
|
||||||
|
* @param ret_var – óêàçàòåëü äëÿ âîçâðàòà çíà÷åíèÿ â ôîðìàòå 32 áèòà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà ÷òåíèÿ, 2: íåïðàâèëüíûé ôîðìàò, 3: ïåðåïîëíåíèå.
|
||||||
|
* @details Îïðåäåëÿåò ôîðìàò IQ ïåðåìåííîé, êîíâåðòèðóåò å¸ â 32b ñ ó÷¸òîì ìàñøòàáà.
|
||||||
|
*/
|
||||||
|
static int convertDebugVarToIQx(DebugVar_t *var, int32_t *ret_var)
|
||||||
|
{
|
||||||
|
int32_t iq_numb, iq_united, iq_final;
|
||||||
|
int64_t iq_united64 = 0;
|
||||||
|
int64_t iq_final64 = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
float float_numb;
|
float float_numb;
|
||||||
|
|
||||||
if(getDebugVar(var, &iq_numb, &float_numb) != 0)
|
status = getDebugVar(var, &iq_numb, &float_numb);
|
||||||
return 1;
|
if(status != 0)
|
||||||
|
return status;
|
||||||
|
|
||||||
// ïðèâåäåíèå ê îäíîìó IQ
|
int src_q = iqTypeToQ(var->iq_type);
|
||||||
switch(var->iq_type)
|
int dst_q = iqTypeToQ(var->return_type);
|
||||||
{
|
|
||||||
case t_iq_none:
|
// Êîíâåðòàöèÿ ê GLOBAL_Q (64-áèò)
|
||||||
if(var->ptr_type == pt_float)
|
if (var->iq_type == t_iq_none) {
|
||||||
{
|
if (var->ptr_type == pt_float) {
|
||||||
iq_united = _IQ(float_numb);
|
// float_numb óìíîæàåì íà 2^GLOBAL_Q
|
||||||
}
|
// Ðåçóëüòàò ïðèâîäèì ê 64 áèòà
|
||||||
else
|
iq_united64 = (int64_t)(float_numb * ((uint32_t)1 << GLOBAL_Q));
|
||||||
{
|
} else {
|
||||||
iq_united = _IQ(iq_numb);
|
iq_united64 = ((int64_t)iq_numb) << GLOBAL_Q;
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case t_iq1:
|
int shift = GLOBAL_Q - src_q;
|
||||||
iq_united = _IQ1toIQ(iq_numb);
|
if (shift >= 0)
|
||||||
break;
|
iq_united64 = ((int64_t)iq_numb) << shift;
|
||||||
case t_iq2:
|
else
|
||||||
iq_united = _IQ2toIQ(iq_numb);
|
iq_united64 = ((int64_t)iq_numb) >> (-shift);
|
||||||
break;
|
|
||||||
case t_iq3:
|
|
||||||
iq_united = _IQ3toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq4:
|
|
||||||
iq_united = _IQ4toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq5:
|
|
||||||
iq_united = _IQ5toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq6:
|
|
||||||
iq_united = _IQ6toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq7:
|
|
||||||
iq_united = _IQ7toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq8:
|
|
||||||
iq_united = _IQ8toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq9:
|
|
||||||
iq_united = _IQ9toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq10:
|
|
||||||
iq_united = _IQ10toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq11:
|
|
||||||
iq_united = _IQ11toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq12:
|
|
||||||
iq_united = _IQ12toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq13:
|
|
||||||
iq_united = _IQ13toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq14:
|
|
||||||
iq_united = _IQ14toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq15:
|
|
||||||
iq_united = _IQ15toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq16:
|
|
||||||
iq_united = _IQ16toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq17:
|
|
||||||
iq_united = _IQ17toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq18:
|
|
||||||
iq_united = _IQ18toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq19:
|
|
||||||
iq_united = _IQ19toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq20:
|
|
||||||
iq_united = _IQ20toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq21:
|
|
||||||
iq_united = _IQ21toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq22:
|
|
||||||
iq_united = _IQ22toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq23:
|
|
||||||
iq_united = _IQ23toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq24:
|
|
||||||
iq_united = _IQ24toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq25:
|
|
||||||
iq_united = _IQ25toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq26:
|
|
||||||
iq_united = _IQ26toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq27:
|
|
||||||
iq_united = _IQ27toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq28:
|
|
||||||
iq_united = _IQ28toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq29:
|
|
||||||
iq_united = _IQ29toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
case t_iq30:
|
|
||||||
iq_united = _IQ30toIQ(iq_numb);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ïðèâåäåíèå îáùåãî IQ ê çàïðàøèâàåìîìó
|
// Êîíâåðòàöèÿ èç GLOBAL_Q â öåëåâîé IQ (64-áèò)
|
||||||
switch(var->return_type)
|
if (var->return_type == t_iq_none) {
|
||||||
{
|
// Âîçâðàùàåì öåëîå, îòáðîñèâ äðîáíóþ ÷àñòü
|
||||||
case t_iq_none:
|
*ret_var = (uint32_t)(iq_united64 >> GLOBAL_Q);
|
||||||
iq_final = (int)_IQtoF(iq_united);
|
} else {
|
||||||
break;
|
int shift = dst_q - GLOBAL_Q;
|
||||||
case t_iq1:
|
if (shift >= 0)
|
||||||
iq_final = _IQtoIQ1(iq_united);
|
iq_final64 = iq_united64 << shift;
|
||||||
break;
|
else
|
||||||
case t_iq2:
|
iq_final64 = iq_united64 >> (-shift);
|
||||||
iq_final = _IQtoIQ2(iq_united);
|
|
||||||
break;
|
*ret_var = (int32_t)iq_final64;
|
||||||
case t_iq3:
|
|
||||||
iq_final = _IQtoIQ3(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq4:
|
|
||||||
iq_final = _IQtoIQ4(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq5:
|
|
||||||
iq_final = _IQtoIQ5(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq6:
|
|
||||||
iq_final = _IQtoIQ6(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq7:
|
|
||||||
iq_final = _IQtoIQ7(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq8:
|
|
||||||
iq_final = _IQtoIQ8(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq9:
|
|
||||||
iq_final = _IQtoIQ9(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq10:
|
|
||||||
iq_final = _IQtoIQ10(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq11:
|
|
||||||
iq_final = _IQtoIQ11(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq12:
|
|
||||||
iq_final = _IQtoIQ12(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq13:
|
|
||||||
iq_final = _IQtoIQ13(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq14:
|
|
||||||
iq_final = _IQtoIQ14(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq15:
|
|
||||||
iq_final = _IQtoIQ15(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq16:
|
|
||||||
iq_final = _IQtoIQ16(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq17:
|
|
||||||
iq_final = _IQtoIQ17(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq18:
|
|
||||||
iq_final = _IQtoIQ18(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq19:
|
|
||||||
iq_final = _IQtoIQ19(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq20:
|
|
||||||
iq_final = _IQtoIQ20(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq21:
|
|
||||||
iq_final = _IQtoIQ21(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq22:
|
|
||||||
iq_final = _IQtoIQ22(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq23:
|
|
||||||
iq_final = _IQtoIQ23(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq24:
|
|
||||||
iq_final = _IQtoIQ24(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq25:
|
|
||||||
iq_final = _IQtoIQ25(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq26:
|
|
||||||
iq_final = _IQtoIQ26(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq27:
|
|
||||||
iq_final = _IQtoIQ27(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq28:
|
|
||||||
iq_final = _IQtoIQ28(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq29:
|
|
||||||
iq_final = _IQtoIQ29(iq_united);
|
|
||||||
break;
|
|
||||||
case t_iq30:
|
|
||||||
iq_final = _IQtoIQ30(iq_united);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret_var = iq_final;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var)
|
* @brief Ïðî÷èòàòü çíà÷åíèå ïåðåìåííîé îòëàäêè.
|
||||||
|
* @param var – óêàçàòåëü íà ñòðóêòóðó DebugVar.
|
||||||
|
* @param int_var – óêàçàòåëü íà ïåðåìåííóþ òèïà 32 áèòà äëÿ âîçâðàòà öåëî÷èñëåííîãî çíà÷åíèÿ.
|
||||||
|
* @param float_var – óêàçàòåëü íà ïåðåìåííóþ òèïà float äëÿ âîçâðàòà çíà÷åíèÿ ñ ïëàâàþùåé òî÷êîé.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà óêàçàòåëåé èëè íåïîääåðæèâàåìûé òèï, 3/4: îøèáêà âûðàâíèâàíèÿ.
|
||||||
|
* @details  çàâèñèìîñòè îò òèïà ïåðåìåííîé ñ÷èòûâàåò å¸ çíà÷åíèå è ñîõðàíÿåò â ñîîòâåòñòâóþùåì óêàçàòåëå.
|
||||||
|
*/
|
||||||
|
static int getDebugVar(DebugVar_t *var, int32_t *int_var, float *float_var)
|
||||||
{
|
{
|
||||||
if (!var || !int_var || !float_var || !var->Ptr)
|
uint8_t *addr = var->Ptr;
|
||||||
return 1; // îøèáêà: null óêàçàòåëü
|
uint32_t addr_val = (uint32_t)addr;
|
||||||
|
|
||||||
char *addr = var->Ptr;
|
if (!var || !int_var || !float_var || !var->Ptr)
|
||||||
unsigned long addr_val = (unsigned long)addr;
|
return DEBUG_ERR_INTERNAL; // îøèáêà: null óêàçàòåëü
|
||||||
|
|
||||||
switch (var->ptr_type)
|
switch (var->ptr_type)
|
||||||
{
|
{
|
||||||
case pt_int8: // 8 áèò
|
case pt_int8: // 8 áèò
|
||||||
|
if ((addr_val & ALIGN_8BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile int8_t *)addr);
|
||||||
|
break;
|
||||||
case pt_uint8:
|
case pt_uint8:
|
||||||
// âûðàâíèâàíèå íå íóæíî äëÿ 8 áèò
|
if ((addr_val & ALIGN_8BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
*int_var = *((volatile char *)addr);
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile uint8_t *)addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case pt_int16: // 16 áèò (int)
|
case pt_int16: // 16 áèò (int)
|
||||||
|
if ((addr_val & ALIGN_16BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile int16_t *)addr);
|
||||||
|
break;
|
||||||
case pt_uint16:
|
case pt_uint16:
|
||||||
if (addr_val & 0x1) // ïðîâåðêà âûðàâíèâàíèÿ ïî 2 áàéòàì
|
if ((addr_val & ALIGN_16BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
return 2; // îøèáêà âûðàâíèâàíèÿ
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
*int_var = *((volatile int *)addr);
|
*int_var = *((volatile uint16_t *)addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case pt_int32: // 32 áèò (long)
|
case pt_int32: // 32 áèò
|
||||||
|
if ((addr_val & ALIGN_32BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile int32_t *)addr);
|
||||||
|
break;
|
||||||
case pt_uint32:
|
case pt_uint32:
|
||||||
if (addr_val & 0x3) // ïðîâåðêà âûðàâíèâàíèÿ ïî 4 áàéòàì
|
if ((addr_val & ALIGN_32BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
return 3; // îøèáêà âûðàâíèâàíèÿ
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
*int_var = *((volatile long *)addr);
|
*int_var = *((volatile uint32_t *)addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case pt_int64: // 64 áèò (long long)
|
|
||||||
// case pt_uint64:
|
|
||||||
// if (addr_val & 0x7) // ïðîâåðêà âûðàâíèâàíèÿ ïî 8 áàéòàì
|
|
||||||
// return 2; // îøèáêà âûðàâíèâàíèÿ
|
|
||||||
// // Òóò ïðîñòî ÷èòàåì, íî long long ìîæåò íå ïîìåñòèòüñÿ â *int_var
|
|
||||||
// // Ìîæíî çàìåíèòü ëîãèêó ïîä 64-áèòíîå ÷òåíèå ïðè íåîáõîäèìîñòè
|
|
||||||
// *int_var = *((volatile long long *)addr);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case pt_float: // float (4 áàéòà)
|
case pt_float: // float (4 áàéòà)
|
||||||
if (addr_val & 0x3) // ïðîâåðêà âûðàâíèâàíèÿ ïî 4 áàéòàì
|
if ((addr_val & ALIGN_FLOAT) != 0) // ïðîâåðêà âûðàâíèâàíèÿ
|
||||||
return 4; // îøèáêà âûðàâíèâàíèÿ
|
return DEBUG_ERR_ADDR_ALIGN; // îøèáêà âûðàâíèâàíèÿ
|
||||||
*float_var = *((volatile float *)addr);
|
*float_var = *((volatile float *)addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 1; // íåïîääåðæèâàåìûé òèï
|
return DEBUG_ERR_INVALID_VAR; // íåïîääåðæèâàåìûé òèï
|
||||||
// äëÿ óêàçàòåëåé è ìàññèâîâ íå ïîääåðæèâàåòñÿ ÷òåíèå
|
// äëÿ óêàçàòåëåé è ìàññèâîâ íå ïîääåðæèâàåòñÿ ÷òåíèå
|
||||||
// case pt_ptr_int8:
|
// case pt_ptr_int8:
|
||||||
// case pt_ptr_int16:
|
// case pt_ptr_int16:
|
||||||
@@ -402,3 +428,24 @@ static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var)
|
|||||||
|
|
||||||
return 0; // óñïåõ
|
return 0; // óñïåõ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ïðîâåðÿåò, âõîäèò ëè àäðåñ â îäèí èç äîïóñòèìûõ äèàïàçîíîâ
|
||||||
|
*
|
||||||
|
* @param addr_val - Çíà÷åíèå àäðåñà äëÿ ïðîâåðêè
|
||||||
|
* @param ranges - Óêàçàòåëü íà ìàññèâ äèàïàçîíîâ AddrRange_t
|
||||||
|
* @param count - Êîëè÷åñòâî äèàïàçîíîâ â ìàññèâå
|
||||||
|
* @return 0 åñëè àäðåñ íàõîäèòñÿ â îäíîì èç äèàïàçîíîâ, èíà÷å 1
|
||||||
|
*/
|
||||||
|
static int is_addr_in_allowed_ranges(uint32_t addr_val, const AddrRange_t *ranges, int count)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
if (addr_val >= ranges[i].start && addr_val <= ranges[i].end) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|||||||
153
debug_tools.h
153
debug_tools.h
@@ -1,8 +1,65 @@
|
|||||||
#ifndef DEBUG_TOOLS
|
#ifndef DEBUG_TOOLS
|
||||||
#define DEBUG_TOOLS
|
#define DEBUG_TOOLS
|
||||||
#include "IQmathLib.h"
|
#include <stdint.h>
|
||||||
#include "DSP281x_Device.h"
|
#include <limits.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define ALLOWED_ADDRESS_RANGES { \
|
||||||
|
{0x000000, 0x0007FF}, \
|
||||||
|
{0x008120, 0x009FFC}, \
|
||||||
|
{0x3F8000, 0x3F9FFF}, \
|
||||||
|
{0x3FF000, 0x3FFFFF}, \
|
||||||
|
{0x080002, 0x09FFFF}, \
|
||||||
|
{0x0F0000, 0x0FFEFF}, \
|
||||||
|
{0x100002, 0x103FFF}, \
|
||||||
|
{0x102000, 0x103FFF} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if UINT8_MAX // Åñëè åñòü òèï 8 áèò - çí÷à÷èò àäðåñàöèÿ ïî 8 áèò
|
||||||
|
|
||||||
|
#define ALIGN_8BIT 0x0 ///< Âûðàâíèâàíèå áåç îãðàíè÷åíèé (ëþáîé àäðåñ)
|
||||||
|
#define ALIGN_16BIT 0x1 ///< Âûðàâíèâàíèå: àäðåñ äîëæåí áûòü êðàòåí 2 (addr & 0x1 == 0)
|
||||||
|
#define ALIGN_32BIT 0x3 ///< Âûðàâíèâàíèå: àäðåñ äîëæåí áûòü êðàòåí 4 (addr & 0x3 == 0)
|
||||||
|
#define ALIGN_64BIT 0x7 ///< Âûðàâíèâàíèå: àäðåñ äîëæåí áûòü êðàòåí 8 (addr & 0x7 == 0)
|
||||||
|
#define ALIGN_FLOAT ALIGN_32BIT
|
||||||
|
|
||||||
|
#else // Åñëè íåò òèïà 8 áèò - çíà÷èò àäðåñàöèÿ ïî 16 áèò
|
||||||
|
|
||||||
|
#define ALIGN_8BIT 0x0 ///< Âûðàâíèâàíèå áåç îãðàíè÷åíèé (ëþáîé àäðåñ)
|
||||||
|
#define ALIGN_16BIT 0x0 ///< Âûðàâíèâàíèå áåç îãðàíè÷åíèé (ëþáîé àäðåñ)
|
||||||
|
#define ALIGN_32BIT 0x1 ///< Âûðàâíèâàíèå: àäðåñ äîëæåí áûòü êðàòåí 4 (addr & 0x1 == 0)
|
||||||
|
#define ALIGN_64BIT 0x3 ///< Âûðàâíèâàíèå: àäðåñ äîëæåí áûòü êðàòåí 8 (addr & 0x3 == 0)
|
||||||
|
#define ALIGN_FLOAT ALIGN_32BIT
|
||||||
|
|
||||||
|
#endif //STM32/TMS32
|
||||||
|
|
||||||
|
#if !UINT8_MAX
|
||||||
|
typedef unsigned char uint8_t;
|
||||||
|
typedef signed char int8_t;
|
||||||
|
#endif
|
||||||
|
#if !defined(NULL)
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEBUG_SIGNED_VAR (1<<7)
|
||||||
|
|
||||||
|
#define DEBUG_OK (0)
|
||||||
|
#define DEBUG_ERR (1<<7)
|
||||||
|
#define DEBUG_ERR_VAR_NUMB (1<<0) | DEBUG_ERR
|
||||||
|
#define DEBUG_ERR_INVALID_VAR (1<<1) | DEBUG_ERR
|
||||||
|
#define DEBUG_ERR_ADDR (1<<2) | DEBUG_ERR
|
||||||
|
#define DEBUG_ERR_ADDR_ALIGN (1<<3) | DEBUG_ERR
|
||||||
|
#define DEBUG_ERR_INTERNAL (1<<4) | DEBUG_ERR
|
||||||
|
#define DEBUG_ERR_DATATIME (1<<5) | DEBUG_ERR
|
||||||
|
#define DEBUG_ERR_RS (1<<6) | DEBUG_ERR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Òèï äàííûõ, íà êîòîðûé óêàçûâàåò óêàçàòåëü ïåðåìåííîé îòëàäêè.
|
||||||
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
pt_unknown, // unknown
|
pt_unknown, // unknown
|
||||||
@@ -14,7 +71,7 @@ typedef enum
|
|||||||
pt_uint16, // unsigned int
|
pt_uint16, // unsigned int
|
||||||
pt_uint32, // unsigned long
|
pt_uint32, // unsigned long
|
||||||
pt_uint64, // unsigned long
|
pt_uint64, // unsigned long
|
||||||
pt_float, // float
|
pt_float, // floatf
|
||||||
pt_struct, // struct
|
pt_struct, // struct
|
||||||
pt_union, // struct
|
pt_union, // struct
|
||||||
// pt_ptr_int8, // signed char*
|
// pt_ptr_int8, // signed char*
|
||||||
@@ -31,6 +88,9 @@ typedef enum
|
|||||||
// pt_arr_uint32, // unsigned long[]
|
// pt_arr_uint32, // unsigned long[]
|
||||||
}DebugVarPtrType_t;
|
}DebugVarPtrType_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Òèïû IQ-ïðåäñòàâëåíèÿ ïåðåìåííîé îòëàäêè.
|
||||||
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
t_iq_none,
|
t_iq_none,
|
||||||
@@ -67,30 +127,83 @@ typedef enum
|
|||||||
t_iq30
|
t_iq30
|
||||||
}DebugVarIQType_t;
|
}DebugVarIQType_t;
|
||||||
|
|
||||||
|
typedef char DebugVarName_t[11]; ///< Èìÿ ïåðåìåííîé îòëàäêè (äî 10 ñèìâîëîâ + \0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Îïèñàíèå ïåðåìåííîé îòëàäêè.
|
||||||
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char* Ptr;
|
uint8_t* Ptr; ///< Óêàçàòåëü íà çíà÷åíèå ïåðåìåííîé
|
||||||
DebugVarPtrType_t ptr_type;
|
DebugVarPtrType_t ptr_type; ///< Òèï çíà÷åíèÿ
|
||||||
DebugVarIQType_t iq_type;
|
DebugVarIQType_t iq_type; ///< Òèï IQ ïåðåìåííîé (åñëè åñòü)
|
||||||
DebugVarIQType_t return_type;
|
DebugVarIQType_t return_type;///< Òèï IQ âîçâðàùàåìîãî çíà÷åíèÿ
|
||||||
char name[11]; // 10 ñèìâîëîâ + '\0'
|
DebugVarName_t name; ///< Èìÿ ïåðåìåííîé
|
||||||
}DebugVar_t;
|
} DebugVar_t;
|
||||||
|
|
||||||
|
typedef long DebugValue_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ñòðóêòóðà äàòû è âðåìåíè.
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint16_t year;
|
uint16_t year; ///< Ãîä (íàïðèìåð, 2025)
|
||||||
uint8_t month;
|
uint8_t month; ///< Ìåñÿö (1-12)
|
||||||
uint8_t day;
|
uint8_t day; ///< Äåíü (1-31)
|
||||||
uint8_t hour;
|
uint8_t hour; ///< ×àñû (0-23)
|
||||||
uint8_t minute;
|
uint8_t minute; ///< Ìèíóòû (0-59)
|
||||||
} DateTimeHex;
|
} DateTime_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ñòðóêòóðà, îïèñûâàþùàÿ äèàïàçîí àäðåñîâ ïàìÿòè.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t start; ///< Íà÷àëüíûé àäðåñ äèàïàçîíà
|
||||||
|
uint32_t end; ///< Êîíå÷íûé àäðåñ äèàïàçîíà (âêëþ÷èòåëüíî)
|
||||||
|
} AddrRange_t;
|
||||||
|
/**
|
||||||
|
* @brief Ñòðóêòóðà íèæíåãî óðîâíÿ îòëàäêè.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DateTime_t build_date; ///< Äàòà ñáîðêè
|
||||||
|
unsigned int isVerified; ///< Ôëàã èíèöèàëèçàöèè íèçêîóðîâíåíîé îòëàäêè (0 — íåò, 1 — óñïåøíî)
|
||||||
|
DebugVar_t dbg_var; ///< Ïåðåìåííàÿ äëÿ îòëàäêè
|
||||||
|
}DebugLowLevel_t;
|
||||||
|
extern DebugLowLevel_t debug_ll; ///< Ãëîáàëüíûé ýêçåìïëÿð îòëàäêè íèæíåãî óðîâíÿ
|
||||||
|
|
||||||
|
|
||||||
extern int DebugVar_Qnt;
|
/** @brief Ìàêðîñ èíèöèàëèçàöèè äàòû */
|
||||||
extern DebugVar_t dbg_vars[];
|
#define DATE_INIT {BUILD_YEAR, BUILD_MONTH, BUILD_DATA, BUILD_HOURS, BUILD_MINUTES}
|
||||||
|
/** @brief Ìàêðîñ èíèöèàëèçàöèè ïåðåìåííîé îòëàäêè */
|
||||||
|
#define DEBUG_VAR_INIT {0, pt_uint16, t_iq_none, t_iq_none, "\0"}
|
||||||
|
/** @brief Ìàêðîñ èíèöèàëèçàöèè íèæíåãî óðîâíÿ îòëàäêè */
|
||||||
|
#define DEBUG_LOWLEVEL_INIT {DATE_INIT, 0, DEBUG_VAR_INIT}
|
||||||
|
|
||||||
int Debug_LowLevel_ReadVar(DebugVar_t *var_ll, long *return_long);
|
|
||||||
int Debug_ReadVar(DebugVar_t *var, long *return_long);
|
|
||||||
int Debug_ReadVarName(DebugVar_t *var, char *name_ptr);
|
|
||||||
|
|
||||||
|
extern int DebugVar_Qnt; ///< Êîëè÷åñòâî ïåðåìåííûõ îòëàäêè
|
||||||
|
extern DebugVar_t dbg_vars[]; ///< Ìàññèâ ïåðåìåííûõ îòëàäêè
|
||||||
|
|
||||||
|
|
||||||
|
/* Ïðèìåð èñïîëüçîâàíèÿ îòëàäêè */
|
||||||
|
void Debug_Test_Example(void);
|
||||||
|
|
||||||
|
/* ×èòàåò çíà÷åíèå ïåðåìåííîé ïî èíäåêñó */
|
||||||
|
int Debug_ReadVar(int var_ind, int32_t *return_long);
|
||||||
|
/* ×èòàåò èìÿ ïåðåìåííîé ïî èíäåêñó */
|
||||||
|
int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr, int *length);
|
||||||
|
/* ×èòàåò âîçâðàùàåìûé òèï (IQ) ïåðåìåííîé ïî èíäåêñó */
|
||||||
|
int Debug_ReadVarReturnType(int var_ind, int *vartype);
|
||||||
|
/* ×èòàåò òèï ïåðåìåííîé ïî èíäåêñó */
|
||||||
|
int Debug_ReadVarType(int var_ind, int *vartype);
|
||||||
|
|
||||||
|
|
||||||
|
/* ×èòàåò çíà÷åíèå ïåðåìåííîé ñ íèæíåãî óðîâíÿ */
|
||||||
|
int Debug_LowLevel_ReadVar(int32_t *return_long);
|
||||||
|
/* Èíèöèàëèçèðóåò îòëàäêó íèæíåãî óðîâíÿ */
|
||||||
|
int Debug_LowLevel_Initialize(DateTime_t *external_date);
|
||||||
|
/* ×èòàåò âîçâðàùàåìûé òèï (IQ) íèçêîóðîâíåíî çàäàííîé ïåðåìåííîé */
|
||||||
|
int Debug_LowLevel_ReadVarReturnType(int *vartype);
|
||||||
|
/* ×èòàåò òèï íèçêîóðîâíåíî çàäàííîé ïåðåìåííîé.*/
|
||||||
|
int Debug_LowLevel_ReadVarType(int *vartype);
|
||||||
#endif //DEBUG_TOOLS
|
#endif //DEBUG_TOOLS
|
||||||
|
|||||||
339
debug_vars.c
339
debug_vars.c
@@ -1,339 +0,0 @@
|
|||||||
// Ýòîò ôàéë ñãåíåðèðîâàí àâòîìàòè÷åñêè
|
|
||||||
#include "debug_tools.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Èíêëþäû äëÿ äîñòóïà ê ïåðåìåííûì
|
|
||||||
#include "vector.h"
|
|
||||||
#include "f281xpwm.h"
|
|
||||||
#include "log_can.h"
|
|
||||||
#include "RS_Functions_modbus.h"
|
|
||||||
#include "errors.h"
|
|
||||||
#include "pwm_vector_regul.h"
|
|
||||||
#include "xp_project.h"
|
|
||||||
#include "xp_write_xpwm_time.h"
|
|
||||||
#include "v_pwm24.h"
|
|
||||||
#include "adc_tools.h"
|
|
||||||
#include "rotation_speed.h"
|
|
||||||
#include "dq_to_alphabeta_cos.h"
|
|
||||||
#include "teta_calc.h"
|
|
||||||
#include "CAN_Setup.h"
|
|
||||||
#include "log_to_memory.h"
|
|
||||||
#include "log_params.h"
|
|
||||||
#include "CRC_Functions.h"
|
|
||||||
#include "global_time.h"
|
|
||||||
#include "RS_Functions.h"
|
|
||||||
#include "detect_phase_break2.h"
|
|
||||||
#include "x_parallel_bus.h"
|
|
||||||
#include "x_serial_bus.h"
|
|
||||||
#include "Spartan2E_Functions.h"
|
|
||||||
#include "xp_controller.h"
|
|
||||||
#include "xPeriphSP6_loader.h"
|
|
||||||
#include "xp_rotation_sensor.h"
|
|
||||||
#include "svgen_dq.h"
|
|
||||||
#include "pid_reg3.h"
|
|
||||||
#include "IQmathLib.h"
|
|
||||||
#include "doors_control.h"
|
|
||||||
#include "isolation.h"
|
|
||||||
#include "main22220.h"
|
|
||||||
#include "optical_bus.h"
|
|
||||||
#include "alarm_log_can.h"
|
|
||||||
#include "bender.h"
|
|
||||||
#include "can_watercool.h"
|
|
||||||
#include "detect_phase_break.h"
|
|
||||||
#include "modbus_read_table.h"
|
|
||||||
#include "rmp_cntl_my1.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Ýêñòåðíû äëÿ äîñòóïà ê ïåðåìåííûì
|
|
||||||
extern int ADC0finishAddr;
|
|
||||||
extern int ADC0startAddr;
|
|
||||||
extern int ADC1finishAddr;
|
|
||||||
extern int ADC1startAddr;
|
|
||||||
extern int ADC2finishAddr;
|
|
||||||
extern int ADC2startAddr;
|
|
||||||
extern int ADC_f[2][16];
|
|
||||||
extern int ADC_sf[2][16];
|
|
||||||
extern int ADDR_FOR_ALL;
|
|
||||||
extern int BUSY;
|
|
||||||
extern BENDER Bender[2];
|
|
||||||
extern int CAN_answer_wait[32];
|
|
||||||
extern int CAN_count_cycle_input_units[8];
|
|
||||||
extern int CAN_no_answer[32];
|
|
||||||
extern int CAN_refresh_cicle[32];
|
|
||||||
extern int CAN_request_sent[32];
|
|
||||||
extern int CAN_timeout[32];
|
|
||||||
extern int CAN_timeout_cicle[32];
|
|
||||||
extern int CNTRL_ADDR;
|
|
||||||
extern const int CNTRL_ADDR_UNIVERSAL;
|
|
||||||
extern _iq CONST_15;
|
|
||||||
extern _iq CONST_23;
|
|
||||||
extern int CanOpenUnites[30];
|
|
||||||
extern int CanTimeOutErrorTR;
|
|
||||||
extern XControll_reg Controll;
|
|
||||||
extern int Dpwm;
|
|
||||||
extern int Dpwm2;
|
|
||||||
extern int Dpwm4;
|
|
||||||
extern int EvaTimer1InterruptCount;
|
|
||||||
extern int EvaTimer2InterruptCount;
|
|
||||||
extern int EvbTimer3InterruptCount;
|
|
||||||
extern int EvbTimer4InterruptCount;
|
|
||||||
extern int Fpwm;
|
|
||||||
extern int IN0finishAddr;
|
|
||||||
extern int IN0startAddr;
|
|
||||||
extern int IN1finishAddr;
|
|
||||||
extern int IN1startAddr;
|
|
||||||
extern int IN2finishAddr;
|
|
||||||
extern int IN2startAddr;
|
|
||||||
extern float IQ_OUT_NOM;
|
|
||||||
extern long I_OUT_1_6_NOMINAL_IQ;
|
|
||||||
extern long I_OUT_1_8_NOMINAL_IQ;
|
|
||||||
extern float I_OUT_NOMINAL;
|
|
||||||
extern long I_OUT_NOMINAL_IQ;
|
|
||||||
extern long I_ZPT_NOMINAL_IQ;
|
|
||||||
extern _iq Id_out_max_full;
|
|
||||||
extern _iq Id_out_max_low_speed;
|
|
||||||
extern _iq Iq_out_max;
|
|
||||||
extern _iq Iq_out_nom;
|
|
||||||
extern const unsigned long K_LEM_ADC[20];
|
|
||||||
extern float KmodTerm;
|
|
||||||
extern int ROTfinishAddr;
|
|
||||||
extern unsigned int RS_Len[70];
|
|
||||||
extern const unsigned int R_ADC[20];
|
|
||||||
extern int RotPlaneStartAddr;
|
|
||||||
extern _iq SQRT_32;
|
|
||||||
extern int Unites[8][128];
|
|
||||||
extern int VAR_FREQ_PWM_XTICS;
|
|
||||||
extern int VAR_PERIOD_MAX_XTICS;
|
|
||||||
extern int VAR_PERIOD_MIN_BR_XTICS;
|
|
||||||
extern int VAR_PERIOD_MIN_XTICS;
|
|
||||||
extern int Zpwm;
|
|
||||||
extern WINDING a;
|
|
||||||
extern volatile AddrToSent addrToSent;
|
|
||||||
extern unsigned int adr_read_from_modbus3;
|
|
||||||
extern ALARM_LOG_CAN alarm_log_can;
|
|
||||||
extern ALARM_LOG_CAN_SETUP alarm_log_can_setup;
|
|
||||||
extern ANALOG_VALUE analog;
|
|
||||||
extern int ar_sa_all[3][6][4][7];
|
|
||||||
extern _iq ar_tph[7];
|
|
||||||
extern int block_size_counter_fast;
|
|
||||||
extern int block_size_counter_slow;
|
|
||||||
extern _iq break_result_1;
|
|
||||||
extern _iq break_result_2;
|
|
||||||
extern _iq break_result_3;
|
|
||||||
extern _iq break_result_4;
|
|
||||||
extern Byte byte;
|
|
||||||
extern long c_s;
|
|
||||||
extern int calibration1;
|
|
||||||
extern int calibration2;
|
|
||||||
extern test_functions callfunc;
|
|
||||||
extern CANOPEN_CAN_SETUP canopen_can_setup;
|
|
||||||
extern unsigned int capnum0;
|
|
||||||
extern unsigned int capnum1;
|
|
||||||
extern unsigned int capnum2;
|
|
||||||
extern unsigned int capnum3;
|
|
||||||
extern unsigned int chNum;
|
|
||||||
extern BREAK_PHASE_I chanell1;
|
|
||||||
extern BREAK_PHASE_I chanell2;
|
|
||||||
extern int cmd_3_or_16;
|
|
||||||
extern int compress_size;
|
|
||||||
extern ControlReg controlReg;
|
|
||||||
extern COS_FI_STRUCT cos_fi;
|
|
||||||
extern unsigned int count_error_sync;
|
|
||||||
extern int count_modbus_table_changed;
|
|
||||||
extern int count_run_pch;
|
|
||||||
extern WORD crc_16_tab[256];
|
|
||||||
extern char crypt[34];
|
|
||||||
extern int cur_position_buf_modbus16_can;
|
|
||||||
extern CYCLE cycle[32];
|
|
||||||
extern int delta_capnum;
|
|
||||||
extern int delta_error;
|
|
||||||
extern volatile DOORS_STATUS doors;
|
|
||||||
extern int enable_can;
|
|
||||||
extern int enable_can_recive_after_units_box;
|
|
||||||
extern _iq err_level_adc;
|
|
||||||
extern _iq err_level_adc_on_go;
|
|
||||||
extern unsigned int err_main;
|
|
||||||
extern int err_modbus16;
|
|
||||||
extern int err_modbus3;
|
|
||||||
extern ERRORS errors;
|
|
||||||
extern FLAG f;
|
|
||||||
extern volatile int fail;
|
|
||||||
extern FAULTS faults;
|
|
||||||
extern FIFO fifo;
|
|
||||||
extern ANALOG_VALUE filter;
|
|
||||||
extern int flag_buf;
|
|
||||||
extern int flag_enable_can_from_mpu;
|
|
||||||
extern int flag_enable_can_from_terminal;
|
|
||||||
extern int flag_on_off_pch;
|
|
||||||
extern unsigned int flag_received_first_mess_from_MPU;
|
|
||||||
extern unsigned int flag_reverse;
|
|
||||||
extern unsigned int flag_send_answer_rs;
|
|
||||||
extern int flag_test_tabe_filled;
|
|
||||||
extern int flag_we_int_pwm_on;
|
|
||||||
extern _iq freq1;
|
|
||||||
extern float freqTerm;
|
|
||||||
extern GLOBAL_TIME global_time;
|
|
||||||
extern int hb_logs_data;
|
|
||||||
extern int i;
|
|
||||||
extern BREAK2_PHASE i1_out;
|
|
||||||
extern BREAK2_PHASE i2_out;
|
|
||||||
extern int init_log[3];
|
|
||||||
extern _iq19 iq19_k_norm_ADC[20];
|
|
||||||
extern _iq19 iq19_zero_ADC[20];
|
|
||||||
extern _iq iq_alfa_coef;
|
|
||||||
extern _iq iq_k_norm_ADC[20];
|
|
||||||
extern IQ_LOGSPARAMS iq_logpar;
|
|
||||||
extern _iq iq_max;
|
|
||||||
extern _iq iq_norm_ADC[20];
|
|
||||||
extern ISOLATION isolation1;
|
|
||||||
extern ISOLATION isolation2;
|
|
||||||
extern _iq k1;
|
|
||||||
extern float kI_D;
|
|
||||||
extern float kI_D_Inv31;
|
|
||||||
extern float kI_Q;
|
|
||||||
extern float kI_Q_Inv31;
|
|
||||||
extern float kP_D;
|
|
||||||
extern float kP_D_Inv31;
|
|
||||||
extern float kP_Q;
|
|
||||||
extern float kP_Q_Inv31;
|
|
||||||
extern _iq koef_Base_stop_run;
|
|
||||||
extern _iq koef_Iabc_filter;
|
|
||||||
extern _iq koef_Im_filter;
|
|
||||||
extern _iq koef_Im_filter_long;
|
|
||||||
extern _iq koef_K_stop_run;
|
|
||||||
extern _iq koef_Krecup;
|
|
||||||
extern _iq koef_Min_recup;
|
|
||||||
extern _iq koef_TemperBSU_long_filter;
|
|
||||||
extern _iq koef_Ud_fast_filter;
|
|
||||||
extern _iq koef_Ud_long_filter;
|
|
||||||
extern _iq koef_Wlong;
|
|
||||||
extern _iq koef_Wout_filter;
|
|
||||||
extern _iq koef_Wout_filter_long;
|
|
||||||
extern long koeff_Fs_filter;
|
|
||||||
extern long koeff_Idq_filter;
|
|
||||||
extern _iq koeff_Iq_filter;
|
|
||||||
extern long koeff_Iq_filter_slow;
|
|
||||||
extern long koeff_Ud_filter;
|
|
||||||
extern long koeff_Uq_filter;
|
|
||||||
extern volatile unsigned long length;
|
|
||||||
extern _iq level_on_off_break[13][2];
|
|
||||||
extern logcan_TypeDef log_can;
|
|
||||||
extern LOG_CAN_SETUP log_can_setup;
|
|
||||||
extern TYPE_LOG_PARAMS log_params;
|
|
||||||
extern long logbuf_sync1[10];
|
|
||||||
extern LOGSPARAMS logpar;
|
|
||||||
extern int m_PWM;
|
|
||||||
extern MAILBOXS_CAN_SETUP mailboxs_can_setup;
|
|
||||||
extern int manufactorerAndProductID;
|
|
||||||
extern MODBUS_REG_STRUCT * modbus_table_can_in;
|
|
||||||
extern MODBUS_REG_STRUCT * modbus_table_can_out;
|
|
||||||
extern MODBUS_REG_STRUCT modbus_table_in[450];
|
|
||||||
extern MODBUS_REG_STRUCT modbus_table_out[450];
|
|
||||||
extern MODBUS_REG_STRUCT * modbus_table_rs_in;
|
|
||||||
extern MODBUS_REG_STRUCT * modbus_table_rs_out;
|
|
||||||
extern MODBUS_REG_STRUCT modbus_table_test[450];
|
|
||||||
extern MPU_CAN_SETUP mpu_can_setup;
|
|
||||||
extern NEW_CYCLE_FIFO new_cycle_fifo;
|
|
||||||
extern int no_write;
|
|
||||||
extern int no_write_slow;
|
|
||||||
extern int number_modbus_table_changed;
|
|
||||||
extern OPTICAL_BUS_DATA optical_read_data;
|
|
||||||
extern OPTICAL_BUS_DATA optical_write_data;
|
|
||||||
extern MODBUS_REG_STRUCT options_controller[200];
|
|
||||||
extern _iq pidCur_Ki;
|
|
||||||
extern PIDREG3 pidD;
|
|
||||||
extern PIDREG3 pidD2;
|
|
||||||
extern PIDREG3 pidFvect;
|
|
||||||
extern int pidFvectKi_test;
|
|
||||||
extern int pidFvectKp_test;
|
|
||||||
extern PIDREG3 pidPvect;
|
|
||||||
extern PIDREG3 pidQ;
|
|
||||||
extern PIDREG3 pidQ2;
|
|
||||||
extern PIDREG_KOEFFICIENTS pidReg_koeffs;
|
|
||||||
extern PIDREG3 pidTetta;
|
|
||||||
extern POWER_RATIO power_ratio;
|
|
||||||
extern int prev_flag_buf;
|
|
||||||
extern unsigned int prev_status_received;
|
|
||||||
extern T_project project;
|
|
||||||
extern PWMGEND pwmd;
|
|
||||||
extern T_controller_read r_c_sbus;
|
|
||||||
extern T_controller_read r_controller;
|
|
||||||
extern FIFO refo;
|
|
||||||
extern TMS_TO_TERMINAL_STRUCT reply;
|
|
||||||
extern TMS_TO_TERMINAL_TEST_ALL_STRUCT reply_test_all;
|
|
||||||
extern long return_var;
|
|
||||||
extern RMP_MY1 rmp_freq;
|
|
||||||
extern RMP_MY1 rmp_wrot;
|
|
||||||
extern T_rotation_sensor rotation_sensor;
|
|
||||||
extern ROTOR_VALUE rotor;
|
|
||||||
extern RS_DATA_STRUCT rs_a;
|
|
||||||
extern RS_DATA_STRUCT rs_b;
|
|
||||||
extern unsigned int sincronisationFault;
|
|
||||||
extern char size_cmd15;
|
|
||||||
extern char size_cmd16;
|
|
||||||
extern int size_fast_done;
|
|
||||||
extern int size_slow_done;
|
|
||||||
extern int stop_log;
|
|
||||||
extern int stop_log_slow;
|
|
||||||
extern SVGENDQ svgen_dq_1;
|
|
||||||
extern SVGENDQ svgen_dq_2;
|
|
||||||
extern SVGEN_PWM24 svgen_pwm24_1;
|
|
||||||
extern SVGEN_PWM24 svgen_pwm24_2;
|
|
||||||
extern unsigned int temp;
|
|
||||||
extern _iq temperature_limit_koeff;
|
|
||||||
extern INVERTER_TEMPERATURES temperature_warning_BI1;
|
|
||||||
extern INVERTER_TEMPERATURES temperature_warning_BI2;
|
|
||||||
extern RECTIFIER_TEMPERATURES temperature_warning_BV1;
|
|
||||||
extern RECTIFIER_TEMPERATURES temperature_warning_BV2;
|
|
||||||
extern TERMINAL_CAN_SETUP terminal_can_setup;
|
|
||||||
extern TETTA_CALC tetta_calc;
|
|
||||||
extern int timCNT_alg;
|
|
||||||
extern int timCNT_prev;
|
|
||||||
extern unsigned int time;
|
|
||||||
extern float time_alg;
|
|
||||||
extern long time_pause_enable_can_from_mpu;
|
|
||||||
extern long time_pause_enable_can_from_terminal;
|
|
||||||
extern int time_pause_logs;
|
|
||||||
extern int time_pause_titles;
|
|
||||||
extern volatile int tryNumb;
|
|
||||||
extern UNITES_CAN_SETUP unites_can_setup;
|
|
||||||
extern long var_numb;
|
|
||||||
extern VECTOR_CONTROL vect_control;
|
|
||||||
extern WaterCooler water_cooler;
|
|
||||||
extern _iq winding_displacement;
|
|
||||||
extern Word word;
|
|
||||||
extern WordReversed wordReversed;
|
|
||||||
extern WordToReverse wordToReverse;
|
|
||||||
extern X_PARALLEL_BUS x_parallel_bus_project;
|
|
||||||
extern X_SERIAL_BUS x_serial_bus_project;
|
|
||||||
extern unsigned int xeeprom_controll_fast;
|
|
||||||
extern unsigned int xeeprom_controll_store;
|
|
||||||
extern XPWM_TIME xpwm_time;
|
|
||||||
extern _iq zadan_Id_min;
|
|
||||||
extern int zero_ADC[20];
|
|
||||||
|
|
||||||
|
|
||||||
// Îïðåäåëåíèå ìàññèâà ñ óêàçàòåëÿìè íà ïåðåìåííûå äëÿ îòëàäêè
|
|
||||||
int DebugVar_Qnt = 19;
|
|
||||||
#pragma DATA_SECTION(dbg_vars,".dbgvar_info")
|
|
||||||
DebugVar_t dbg_vars[] = {\
|
|
||||||
{(char *)&ADC1startAddr, pt_int16, t_iq_none, pt_int16, "ADC1StrAdr" }, \
|
|
||||||
{(char *)&project.cds_tk[0].plane_address, pt_uint16, t_iq_none, pt_uint16, "tk0_Adr" }, \
|
|
||||||
{(char *)&ADC_sf[0][0], pt_int16, t_iq_none, pt_int16, "ADC_sf00" }, \
|
|
||||||
{(char *)&ADC_sf[0][1], pt_int16, t_iq_none, pt_int16, "ADC_sf01" }, \
|
|
||||||
{(char *)&ADC_sf[0][2], pt_int16, t_iq_none, pt_int16, "ADC_sf02" }, \
|
|
||||||
{(char *)&ADC_sf[0][3], pt_int16, t_iq_none, pt_int16, "ADC_sf03" }, \
|
|
||||||
{(char *)&ADC_sf[0][4], pt_int16, t_iq_none, pt_int16, "ADC_sf04" }, \
|
|
||||||
{(char *)&ADC_sf[0][5], pt_int16, t_iq_none, pt_int16, "ADC_sf05" }, \
|
|
||||||
{(char *)&ADC_sf[0][6], pt_int16, t_iq_none, pt_int16, "ADC_sf06" }, \
|
|
||||||
{(char *)&ADC_sf[0][7], pt_int16, t_iq_none, pt_int16, "ADC_sf07" }, \
|
|
||||||
{(char *)&ADC_sf[0][8], pt_int16, t_iq_none, pt_int16, "ADC_sf08" }, \
|
|
||||||
{(char *)&ADC_sf[0][9], pt_int16, t_iq_none, pt_int16, "ADC_sf09" }, \
|
|
||||||
{(char *)&ADC_sf[0][10], pt_int16, t_iq_none, pt_int16, "ADC_sf010" }, \
|
|
||||||
{(char *)&ADC_sf[0][11], pt_int16, t_iq_none, pt_int16, "ADC_sf011" }, \
|
|
||||||
{(char *)&ADC_sf[0][12], pt_int16, t_iq_none, pt_int16, "ADC_sf012" }, \
|
|
||||||
{(char *)&ADC_sf[0][13], pt_int16, t_iq_none, pt_int16, "ADC_sf013" }, \
|
|
||||||
{(char *)&ADC_sf[0][14], pt_int16, t_iq_none, pt_int16, "ADC_sf014" }, \
|
|
||||||
{(char *)&ADC_sf[0][15], pt_int16, t_iq_none, pt_int16, "ADC_sf015" }, \
|
|
||||||
{(char *)&project.cds_tk[0].read.sbus.mask_protect_tk.all, pt_uint16, t_iq_none, pt_uint16, "project.cd" }, \
|
|
||||||
};
|
|
||||||
417
parse_xml/Src/parse_xml.py
Normal file
417
parse_xml/Src/parse_xml.py
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
# pyinstaller --onefile --distpath ./parse_xml --workpath ./parse_xml/build --specpath ./build parse_xml/Src/parse_xml.py
|
||||||
|
# python -m nuitka --standalone --onefile --output-dir=./parse_xml parse_xml/Src/parse_xml.py
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
import xml.dom.minidom
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("Usage: python parse_xml.exe <input.xml> <info.txt> [output.xml]")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
input_path = sys.argv[1]
|
||||||
|
info_path = sys.argv[2]
|
||||||
|
|
||||||
|
base_type_sizes = {
|
||||||
|
"char": 2,
|
||||||
|
"short": 2,
|
||||||
|
"int": 2,
|
||||||
|
"long": 4,
|
||||||
|
"long long": 8,
|
||||||
|
"float": 4,
|
||||||
|
"double": 8,
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(sys.argv) >= 4:
|
||||||
|
output_path = sys.argv[3]
|
||||||
|
else:
|
||||||
|
input_dir = os.path.dirname(os.path.abspath(input_path))
|
||||||
|
output_path = os.path.join(input_dir, "simplified.xml")
|
||||||
|
|
||||||
|
tree = ET.parse(input_path)
|
||||||
|
root = tree.getroot()
|
||||||
|
|
||||||
|
def extract_timestamp(info_path):
|
||||||
|
with open(info_path, "r", encoding="utf-8") as f:
|
||||||
|
for line in f:
|
||||||
|
if "Time Stamp:" in line:
|
||||||
|
parts = line.split("Time Stamp:")
|
||||||
|
if len(parts) > 1:
|
||||||
|
timestamp = parts[1].strip()
|
||||||
|
return timestamp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
die_by_id = {die.attrib.get("id"): die for die in root.iter("die") if "id" in die.attrib}
|
||||||
|
|
||||||
|
def get_attr(die, attr_type):
|
||||||
|
for attr in die.findall("attribute"):
|
||||||
|
type_elem = attr.find("type")
|
||||||
|
if type_elem is not None and type_elem.text == attr_type:
|
||||||
|
return attr.find("value")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_die_size(die):
|
||||||
|
"""Вернуть размер DIE в байтах из атрибута DW_AT_byte_size или по ключевым словам имени типа."""
|
||||||
|
|
||||||
|
# Сначала пытаемся получить размер из DW_AT_byte_size
|
||||||
|
for attr in die.findall("attribute"):
|
||||||
|
type_elem = attr.find("type")
|
||||||
|
if type_elem is not None and type_elem.text == "DW_AT_byte_size":
|
||||||
|
const_elem = attr.find("value/const")
|
||||||
|
if const_elem is not None:
|
||||||
|
return int(const_elem.text, 0)
|
||||||
|
|
||||||
|
# Если не нашли, пробуем определить размер по ключевым словам в имени типа
|
||||||
|
name_elem = die.find("attribute[@name='DW_AT_name']/value/const")
|
||||||
|
if name_elem is not None:
|
||||||
|
type_name = name_elem.text.lower()
|
||||||
|
|
||||||
|
for key, size in base_type_sizes.items():
|
||||||
|
if key in type_name:
|
||||||
|
return size
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def resolve_type_die(type_id):
|
||||||
|
"""Получить DIE типа, разрешая typedef, const и volatile."""
|
||||||
|
visited = set()
|
||||||
|
while type_id and type_id not in visited:
|
||||||
|
visited.add(type_id)
|
||||||
|
die = die_by_id.get(type_id)
|
||||||
|
if die is None:
|
||||||
|
return None
|
||||||
|
tag = die.findtext("tag")
|
||||||
|
if tag in ("DW_TAG_volatile_type", "DW_TAG_const_type", "DW_TAG_typedef", "DW_TAG_TI_far_type"):
|
||||||
|
ref = get_attr(die, "DW_AT_type")
|
||||||
|
if ref is not None and ref.find("ref") is not None:
|
||||||
|
type_id = ref.find("ref").attrib.get("idref")
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return die
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Словарь для простых базовых типов по тегам (пример)
|
||||||
|
base_types_map = {
|
||||||
|
"DW_TAG_base_type": lambda die: die.find("attribute[@type='DW_AT_name']/value/string").text if die.find("attribute[@type='DW_AT_name']/value/string") is not None else "unknown",
|
||||||
|
"DW_TAG_structure_type": lambda die: "struct",
|
||||||
|
"DW_TAG_union_type": lambda die: "union",
|
||||||
|
"DW_TAG_pointer_type": lambda die: "pointer",
|
||||||
|
"DW_TAG_array_type": lambda die: "array",
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_type_name(type_id):
|
||||||
|
die = resolve_type_die(type_id)
|
||||||
|
if die is None:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
tag = die.findtext("tag")
|
||||||
|
|
||||||
|
if tag == "DW_TAG_pointer_type":
|
||||||
|
ref = get_attr(die, "DW_AT_type")
|
||||||
|
if ref is not None and ref.find("ref") is not None:
|
||||||
|
pointee_id = ref.find("ref").attrib.get("idref")
|
||||||
|
name = get_type_name(pointee_id)
|
||||||
|
return name + "*" if name != "unknown" else name
|
||||||
|
else:
|
||||||
|
return "void*"
|
||||||
|
|
||||||
|
elif tag == "DW_TAG_base_type":
|
||||||
|
name_attr = get_attr(die, "DW_AT_name")
|
||||||
|
if name_attr is not None:
|
||||||
|
return name_attr.findtext("string")
|
||||||
|
else:
|
||||||
|
return "base_type_unknown"
|
||||||
|
|
||||||
|
elif tag == "DW_TAG_structure_type":
|
||||||
|
name_attr = get_attr(die, "DW_AT_name")
|
||||||
|
name = name_attr.findtext("string") if name_attr is not None else "anonymous_struct"
|
||||||
|
return f"struct {name}"
|
||||||
|
|
||||||
|
elif tag == "DW_TAG_union_type":
|
||||||
|
name_attr = get_attr(die, "DW_AT_name")
|
||||||
|
name = name_attr.findtext("string") if name_attr is not None else "anonymous_union"
|
||||||
|
return f"union {name}"
|
||||||
|
|
||||||
|
elif tag == "DW_TAG_array_type":
|
||||||
|
ref = get_attr(die, "DW_AT_type")
|
||||||
|
if ref is not None and ref.find("ref") is not None:
|
||||||
|
element_type_id = ref.find("ref").attrib.get("idref")
|
||||||
|
element_type_name = get_type_name(element_type_id)
|
||||||
|
return f"{element_type_name}[]"
|
||||||
|
else:
|
||||||
|
return "array[]"
|
||||||
|
|
||||||
|
# Добавляем поддержку enum
|
||||||
|
elif tag == "DW_TAG_enumeration_type":
|
||||||
|
name_attr = get_attr(die, "DW_AT_name")
|
||||||
|
name = name_attr.findtext("string") if name_attr is not None else "anonymous_enum"
|
||||||
|
return f"enum {name}"
|
||||||
|
|
||||||
|
else:
|
||||||
|
return "unknown"
|
||||||
|
|
||||||
|
def parse_offset(offset_text):
|
||||||
|
if offset_text and offset_text.startswith("DW_OP_plus_uconst "):
|
||||||
|
return int(offset_text.split()[-1], 0)
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_type_die(array_die):
|
||||||
|
"""Спускаемся по цепочке DW_AT_type, пока не дойдем до не-массива (базового типа)."""
|
||||||
|
current_die = array_die
|
||||||
|
while True:
|
||||||
|
ref = get_attr(current_die, "DW_AT_type")
|
||||||
|
if ref is None or ref.find("ref") is None:
|
||||||
|
break
|
||||||
|
next_die = resolve_type_die(ref.find("ref").attrib.get("idref"))
|
||||||
|
if next_die is None:
|
||||||
|
break
|
||||||
|
if next_die.findtext("tag") == "DW_TAG_array_type":
|
||||||
|
current_die = next_die
|
||||||
|
else:
|
||||||
|
return next_die
|
||||||
|
return current_die
|
||||||
|
|
||||||
|
def get_array_dimensions(array_die):
|
||||||
|
dims = []
|
||||||
|
# Итерируем по всем DIE с тегом DW_TAG_subrange_type, потомки текущего массива
|
||||||
|
for child in array_die.findall("die"):
|
||||||
|
if child.findtext("tag") != "DW_TAG_subrange_type":
|
||||||
|
continue
|
||||||
|
|
||||||
|
dim_size = None
|
||||||
|
ub_attr = get_attr(child, "DW_AT_upper_bound")
|
||||||
|
if ub_attr is not None:
|
||||||
|
# Попробуем разные варианты получить значение upper_bound
|
||||||
|
# 1) value/const
|
||||||
|
val_const = ub_attr.find("const")
|
||||||
|
if val_const is not None:
|
||||||
|
try:
|
||||||
|
dim_size = int(val_const.text, 0) + 1
|
||||||
|
#print(f"[DEBUG] Found DW_AT_upper_bound const: {val_const.text}, size={dim_size}")
|
||||||
|
except Exception as e:
|
||||||
|
a=1#print(f"[WARN] Error parsing upper_bound const: {e}")
|
||||||
|
else:
|
||||||
|
# 2) value/block (DW_OP_constu / DW_OP_plus_uconst, etc.)
|
||||||
|
val_block = ub_attr.find("block")
|
||||||
|
if val_block is not None:
|
||||||
|
block_text = val_block.text
|
||||||
|
# Можно попытаться парсить DWARF expr (например DW_OP_plus_uconst 7)
|
||||||
|
if block_text and "DW_OP_plus_uconst" in block_text:
|
||||||
|
try:
|
||||||
|
parts = block_text.split()
|
||||||
|
val = int(parts[-1], 0)
|
||||||
|
dim_size = val + 1
|
||||||
|
#print(f"[DEBUG] Parsed upper_bound block: {val} + 1 = {dim_size}")
|
||||||
|
except Exception as e:
|
||||||
|
a=1#print(f"[WARN] Error parsing upper_bound block: {e}")
|
||||||
|
else:
|
||||||
|
a=1#print(f"[WARN] Unexpected DW_AT_upper_bound block content: {block_text}")
|
||||||
|
else:
|
||||||
|
a=1#print(f"[WARN] DW_AT_upper_bound has no const or block value")
|
||||||
|
|
||||||
|
if dim_size is None:
|
||||||
|
# fallback по DW_AT_count — редко встречается
|
||||||
|
ct_attr = get_attr(child, "DW_AT_count")
|
||||||
|
if ct_attr is not None:
|
||||||
|
val_const = ct_attr.find("value/const")
|
||||||
|
if val_const is not None:
|
||||||
|
try:
|
||||||
|
dim_size = int(val_const.text, 0)
|
||||||
|
#print(f"[DEBUG] Found DW_AT_count: {dim_size}")
|
||||||
|
except Exception as e:
|
||||||
|
a=1#print(f"[WARN] Error parsing DW_AT_count const: {e}")
|
||||||
|
|
||||||
|
if dim_size is None:
|
||||||
|
print("[DEBUG] No dimension size found for this subrange, defaulting to 0")
|
||||||
|
dim_size = 0
|
||||||
|
|
||||||
|
dims.append(dim_size)
|
||||||
|
|
||||||
|
# Если не нашли измерений — пытаемся вычислить размер массива по общему размеру
|
||||||
|
if not dims:
|
||||||
|
arr_size = get_die_size(array_die)
|
||||||
|
elem_size = None
|
||||||
|
element_type_ref = get_attr(array_die, "DW_AT_type")
|
||||||
|
if element_type_ref is not None and element_type_ref.find("ref") is not None:
|
||||||
|
element_type_id = element_type_ref.find("ref").attrib.get("idref")
|
||||||
|
elem_die = resolve_type_die(element_type_id)
|
||||||
|
if elem_die is not None:
|
||||||
|
elem_size = get_die_size(elem_die)
|
||||||
|
#print(f"[DEBUG] Fallback: arr_size={arr_size}, elem_size={elem_size}")
|
||||||
|
|
||||||
|
if arr_size is not None and elem_size:
|
||||||
|
dim_calc = arr_size // elem_size
|
||||||
|
dims.append(dim_calc)
|
||||||
|
#print(f"[DEBUG] Calculated dimension size from total size: {dim_calc}")
|
||||||
|
else:
|
||||||
|
dims.append(0)
|
||||||
|
print("[DEBUG] Could not calculate dimension size, set 0")
|
||||||
|
|
||||||
|
# Рекурсивно обрабатываем вложенные массивы
|
||||||
|
element_type_ref = get_attr(array_die, "DW_AT_type")
|
||||||
|
if element_type_ref is not None and element_type_ref.find("ref") is not None:
|
||||||
|
element_type_id = element_type_ref.find("ref").attrib.get("idref")
|
||||||
|
element_type_die = resolve_type_die(element_type_id)
|
||||||
|
if element_type_die is not None and element_type_die.findtext("tag") == "DW_TAG_array_type":
|
||||||
|
dims.extend(get_array_dimensions(element_type_die))
|
||||||
|
|
||||||
|
#print(f"[DEBUG] Array dimensions: {dims}")
|
||||||
|
return dims
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def handle_array_type(member_elem, resolved_type, offset=0):
|
||||||
|
dims = get_array_dimensions(resolved_type)
|
||||||
|
|
||||||
|
base_die = get_base_type_die(resolved_type)
|
||||||
|
base_name = "unknown"
|
||||||
|
base_size = None
|
||||||
|
if base_die is not None:
|
||||||
|
base_id = base_die.attrib.get("id")
|
||||||
|
if base_id:
|
||||||
|
base_name = get_type_name(base_id)
|
||||||
|
base_size = get_die_size(base_die)
|
||||||
|
else:
|
||||||
|
base_name = get_type_name(base_die.attrib.get("id", ""))
|
||||||
|
#print(f"[DEBUG] Base type name: {base_name}, base size: {base_size}")
|
||||||
|
|
||||||
|
member_elem.set("type", base_name + "[]" * len(dims))
|
||||||
|
|
||||||
|
if base_size is None:
|
||||||
|
base_size = 0
|
||||||
|
|
||||||
|
total_elements = 1
|
||||||
|
for d in dims:
|
||||||
|
if d == 0:
|
||||||
|
total_elements = 0
|
||||||
|
print(f"[WARN] Dimension size is zero, setting total elements to 0")
|
||||||
|
break
|
||||||
|
total_elements *= d
|
||||||
|
|
||||||
|
total_size = total_elements * base_size if base_size is not None else 0
|
||||||
|
if total_size:
|
||||||
|
member_elem.set("size", str(base_size if base_size is not None else 1))
|
||||||
|
else:
|
||||||
|
arr_size = get_die_size(resolved_type)
|
||||||
|
if arr_size:
|
||||||
|
member_elem.set("size", str(arr_size))
|
||||||
|
#print(f"[DEBUG] Used fallback size from resolved_type: {arr_size}")
|
||||||
|
else:
|
||||||
|
print(f"[WARN] Could not determine total size for array")
|
||||||
|
|
||||||
|
for i, dim in enumerate(dims, 1):
|
||||||
|
member_elem.set(f"size{i}", str(dim))
|
||||||
|
#print(f"[DEBUG] Setting size{i} = {dim}")
|
||||||
|
|
||||||
|
member_elem.set("kind", "array")
|
||||||
|
|
||||||
|
if base_die is not None and base_die.findtext("tag") == "DW_TAG_structure_type":
|
||||||
|
add_members_recursive(member_elem, base_die, offset)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def add_members_recursive(parent_elem, struct_die, base_offset=0):
|
||||||
|
is_union = struct_die.findtext("tag") == "DW_TAG_union_type"
|
||||||
|
size = get_die_size(struct_die)
|
||||||
|
if size is not None:
|
||||||
|
parent_elem.set("size", hex(size))
|
||||||
|
|
||||||
|
for member in struct_die.findall("die"):
|
||||||
|
if member.findtext("tag") != "DW_TAG_member":
|
||||||
|
continue
|
||||||
|
|
||||||
|
name_attr = get_attr(member, "DW_AT_name")
|
||||||
|
offset_attr = get_attr(member, "DW_AT_data_member_location")
|
||||||
|
type_attr = get_attr(member, "DW_AT_type")
|
||||||
|
if name_attr is None or offset_attr is None or type_attr is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = name_attr.findtext("string")
|
||||||
|
offset = parse_offset(offset_attr.findtext("block")) + base_offset
|
||||||
|
type_id = type_attr.find("ref").attrib.get("idref")
|
||||||
|
resolved_type = resolve_type_die(type_id)
|
||||||
|
type_name = get_type_name(type_id)
|
||||||
|
if type_name == "unknown":
|
||||||
|
continue
|
||||||
|
|
||||||
|
member_elem = ET.SubElement(parent_elem, "member", name=name, offset=hex(offset), type=type_name)
|
||||||
|
if is_union:
|
||||||
|
member_elem.set("kind", "union")
|
||||||
|
|
||||||
|
if resolved_type is not None:
|
||||||
|
tag = resolved_type.findtext("tag")
|
||||||
|
if tag == "DW_TAG_array_type":
|
||||||
|
handle_array_type(member_elem, resolved_type, offset)
|
||||||
|
elif tag in ("DW_TAG_structure_type", "DW_TAG_union_type"):
|
||||||
|
member_elem.set("type", type_name)
|
||||||
|
add_members_recursive(member_elem, resolved_type, offset)
|
||||||
|
elif tag == "DW_TAG_pointer_type":
|
||||||
|
# Проверяем тип, на который указывает указатель
|
||||||
|
pointee_ref = get_attr(resolved_type, "DW_AT_type")
|
||||||
|
if pointee_ref is not None and pointee_ref.find("ref") is not None:
|
||||||
|
pointee_id = pointee_ref.find("ref").attrib.get("idref")
|
||||||
|
pointee_die = resolve_type_die(pointee_id)
|
||||||
|
if pointee_die is not None:
|
||||||
|
pointee_tag = pointee_die.findtext("tag")
|
||||||
|
if pointee_tag in ("DW_TAG_structure_type", "DW_TAG_union_type"):
|
||||||
|
# Добавляем подэлементы для структуры, на которую указывает указатель
|
||||||
|
pointer_elem = ET.SubElement(member_elem, "pointee", type=get_type_name(pointee_id))
|
||||||
|
add_members_recursive(pointer_elem, pointee_die, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
output_root = ET.Element("variables")
|
||||||
|
for die in root.iter("die"):
|
||||||
|
if die.findtext("tag") != "DW_TAG_variable":
|
||||||
|
continue
|
||||||
|
|
||||||
|
name_attr = get_attr(die, "DW_AT_name")
|
||||||
|
addr_attr = get_attr(die, "DW_AT_location")
|
||||||
|
type_attr = get_attr(die, "DW_AT_type")
|
||||||
|
if name_attr is None or addr_attr is None or type_attr is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
name = name_attr.findtext("string")
|
||||||
|
if "$" in name:
|
||||||
|
continue
|
||||||
|
|
||||||
|
addr_text = addr_attr.findtext("block")
|
||||||
|
if not addr_text or not addr_text.startswith("DW_OP_addr "):
|
||||||
|
continue
|
||||||
|
|
||||||
|
addr = int(addr_text.split()[-1], 0)
|
||||||
|
type_id = type_attr.find("ref").attrib.get("idref")
|
||||||
|
resolved_type = resolve_type_die(type_id)
|
||||||
|
type_name = get_type_name(type_id)
|
||||||
|
if 0x800 <= addr < 0x8000 or type_name == "unknown":
|
||||||
|
continue
|
||||||
|
|
||||||
|
var_elem = ET.SubElement(output_root, "variable", name=name, address=hex(addr), type=type_name)
|
||||||
|
if resolved_type is not None:
|
||||||
|
tag = resolved_type.findtext("tag")
|
||||||
|
if tag == "DW_TAG_array_type":
|
||||||
|
handle_array_type(var_elem, resolved_type)
|
||||||
|
elif tag in ("DW_TAG_structure_type", "DW_TAG_union_type"):
|
||||||
|
add_members_recursive(var_elem, resolved_type)
|
||||||
|
|
||||||
|
timestamp = extract_timestamp(info_path)
|
||||||
|
timestamp_elem = ET.Element("timestamp")
|
||||||
|
timestamp_elem.text = timestamp
|
||||||
|
output_root.insert(0, timestamp_elem)
|
||||||
|
|
||||||
|
rough_string = ET.tostring(output_root, encoding="utf-8")
|
||||||
|
pretty_xml = xml.dom.minidom.parseString(rough_string).toprettyxml(indent=" ")
|
||||||
|
with open(output_path, "w", encoding="utf-8") as f:
|
||||||
|
f.write(pretty_xml)
|
||||||
|
|
||||||
|
os.remove(input_path)
|
||||||
|
os.remove(info_path)
|
||||||
|
print(f"Simplified and formatted XML saved to: {output_path}")
|
||||||
BIN
parse_xml/parse_xml.exe
Normal file
BIN
parse_xml/parse_xml.exe
Normal file
Binary file not shown.
20181
structs.xml
20181
structs.xml
File diff suppressed because it is too large
Load Diff
4868
vars.xml
4868
vars.xml
@@ -1,4868 +0,0 @@
|
|||||||
<?xml version='1.0' encoding='utf-8'?>
|
|
||||||
<analysis makefile_path="Debug/makefile" proj_path="F:/Work/Projects/TMS/TMS_new_bus" structs_path="Src/DebugTools/structs.xml">
|
|
||||||
<variables>
|
|
||||||
<var name="ADC1startAddr">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC1StrAdr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC2finishAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ADC2finishAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC2startAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ADC2startAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_f">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ADC_f</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[2][16]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ADC_sf</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[2][16]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADDR_FOR_ALL">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ADDR_FOR_ALL</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="BUSY">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>BUSY</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Bender">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Bender</shortname>
|
|
||||||
<pt_type>pt_arr_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>BENDER[2]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_answer_wait">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_answer_wait</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_count_cycle_input_units">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_count_cycle_input_units</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[8]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_no_answer">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_no_answer</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_refresh_cicle">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_refresh_cicle</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_request_sent">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_request_sent</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_timeout">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_timeout</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_timeout_cicle">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CAN_timeout_cicle</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CNTRL_ADDR">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CNTRL_ADDR</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CNTRL_ADDR_UNIVERSAL">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CNTRL_ADDR_UNIVERSAL</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>const int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CONST_15">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CONST_15</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/mathlib.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CONST_23">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CONST_23</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/mathlib.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CanOpenUnites">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CanOpenUnites</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[30]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="CanTimeOutErrorTR">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>CanTimeOutErrorTR</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Controll">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Controll</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>XControll_reg</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Dpwm">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Dpwm</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Dpwm2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Dpwm2</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Dpwm4">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Dpwm4</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="EvaTimer1InterruptCount">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>EvaTimer1InterruptCount</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="EvaTimer2InterruptCount">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>EvaTimer2InterruptCount</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="EvbTimer3InterruptCount">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>EvbTimer3InterruptCount</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="EvbTimer4InterruptCount">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>EvbTimer4InterruptCount</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Fpwm">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Fpwm</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Gott">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Gott</shortname>
|
|
||||||
<pt_type>pt_arr_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char[8][16]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="IN0finishAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IN0finishAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="IN0startAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IN0startAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="IN1finishAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IN1finishAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="IN1startAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IN1startAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="IN2finishAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IN2finishAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="IN2startAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IN2startAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="IQ_OUT_NOM">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>IQ_OUT_NOM</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_1_6_NOMINAL_IQ">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>I_OUT_1_6_NOMINAL_IQ</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_1_8_NOMINAL_IQ">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>I_OUT_1_8_NOMINAL_IQ</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_NOMINAL">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>I_OUT_NOMINAL</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_NOMINAL_IQ">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>I_OUT_NOMINAL_IQ</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="I_ZPT_NOMINAL_IQ">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>I_ZPT_NOMINAL_IQ</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Id_out_max_full">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Id_out_max_full</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Id_out_max_low_speed">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Id_out_max_low_speed</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Iq_out_max">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Iq_out_max</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Iq_out_nom">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Iq_out_nom</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="K_LEM_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>K_LEM_ADC</shortname>
|
|
||||||
<pt_type>pt_arr_uint32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>const unsigned long[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="KmodTerm">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>KmodTerm</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ROTfinishAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ROTfinishAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="RS_Len">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>RS_Len</shortname>
|
|
||||||
<pt_type>pt_arr_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int[70]</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="R_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>R_ADC</shortname>
|
|
||||||
<pt_type>pt_arr_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>const unsigned int[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="RotPlaneStartAddr">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>RotPlaneStartAddr</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="SQRT_32">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>SQRT_32</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/mathlib.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Unites">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Unites</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[8][128]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_FREQ_PWM_XTICS">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>VAR_FREQ_PWM_XTICS</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_PERIOD_MAX_XTICS">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>VAR_PERIOD_MAX_XTICS</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_PERIOD_MIN_BR_XTICS">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>VAR_PERIOD_MIN_BR_XTICS</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_PERIOD_MIN_XTICS">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>VAR_PERIOD_MIN_XTICS</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="Zpwm">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>Zpwm</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="a">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>a</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>WINDING</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="addrToSent">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>addrToSent</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>volatile AddrToSent</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="adr_read_from_modbus3">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>adr_read_from_modbus3</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="alarm_log_can">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>alarm_log_can</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ALARM_LOG_CAN</type>
|
|
||||||
<file>Src/myLibs/alarm_log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="alarm_log_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>alarm_log_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ALARM_LOG_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="analog">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>analog</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ANALOG_VALUE</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ar_sa_all">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ar_sa_all</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[3][6][4][7]</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ar_tph">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>ar_tph</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq[7]</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="biTemperatureLimits">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>biTemperatureLimits</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[12]</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="biTemperatureWarnings">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>biTemperatureWarnings</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[12]</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="block_size_counter_fast">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>block_size_counter_fast</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="block_size_counter_slow">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>block_size_counter_slow</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>break_result_1</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>break_result_2</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_3">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>break_result_3</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_4">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>break_result_4</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="bvTemperatureLimits">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>bvTemperatureLimits</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[12]</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="bvTemperatureWarnings">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>bvTemperatureWarnings</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[12]</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="byte">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>byte</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>Byte</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="c_s">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>c_s</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="calibration1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>calibration1</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="calibration2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>calibration2</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="callfunc">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>callfunc</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>test_functions</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="canopen_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>canopen_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>CANOPEN_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="capnum0">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>capnum0</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="capnum1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>capnum1</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="capnum2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>capnum2</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="capnum3">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>capnum3</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="chNum">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>chNum</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="chanell1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>chanell1</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>BREAK_PHASE_I</type>
|
|
||||||
<file>Src/main/detect_phase.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="chanell2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>chanell2</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>BREAK_PHASE_I</type>
|
|
||||||
<file>Src/main/detect_phase.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_3_or_16">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cmd_3_or_16</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_crc">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cmd_crc</shortname>
|
|
||||||
<pt_type>pt_arr_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char[4]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_finish1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cmd_finish1</shortname>
|
|
||||||
<pt_type>pt_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_finish2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cmd_finish2</shortname>
|
|
||||||
<pt_type>pt_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_start">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cmd_start</shortname>
|
|
||||||
<pt_type>pt_arr_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char[5]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_txt">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cmd_txt</shortname>
|
|
||||||
<pt_type>pt_arr_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char[4][8]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="compress_size">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>compress_size</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/alarm_log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="controlReg">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>controlReg</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ControlReg</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="cos_fi">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cos_fi</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>COS_FI_STRUCT</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="count_error_sync">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>count_error_sync</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="count_modbus_table_changed">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>count_modbus_table_changed</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_fill_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="count_run_pch">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>count_run_pch</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="counterSBWriteErrors">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>counterSBWriteErrors</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/x_serial_bus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="crc_16_tab">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>crc_16_tab</shortname>
|
|
||||||
<pt_type>pt_arr_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>WORD[256]</type>
|
|
||||||
<file>Src/myXilinx/CRC_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="crypt">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>crypt</shortname>
|
|
||||||
<pt_type>pt_arr_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char[34]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="cur_position_buf_modbus16">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cur_position_buf_modbus16</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/message_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="cur_position_buf_modbus16_can">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cur_position_buf_modbus16_can</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/message_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="cur_position_buf_modbus3">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cur_position_buf_modbus3</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/message_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="cycle">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>cycle</shortname>
|
|
||||||
<pt_type>pt_arr_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>CYCLE[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="data_to_umu1_7f">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>data_to_umu1_7f</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="data_to_umu1_8">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>data_to_umu1_8</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="data_to_umu2_7f">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>data_to_umu2_7f</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="data_to_umu2_8">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>data_to_umu2_8</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/init_protect_levels.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="delta_capnum">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>delta_capnum</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="delta_error">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>delta_error</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="doors">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>doors</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>volatile DOORS_STATUS</type>
|
|
||||||
<file>Src/main/doors_control.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="dq_to_ab">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>dq_to_ab</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>DQ_TO_ALPHABETA</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="enable_can">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>enable_can</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/message_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="enable_can_recive_after_units_box">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>enable_can_recive_after_units_box</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="err_level_adc">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>err_level_adc</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="err_level_adc_on_go">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>err_level_adc_on_go</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="err_main">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>err_main</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="err_modbus16">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>err_modbus16</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="err_modbus3">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>err_modbus3</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="errors">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>errors</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ERRORS</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="f">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>f</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>FLAG</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="fail">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>fail</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>volatile int</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="faults">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>faults</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>FAULTS</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="fifo">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>fifo</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>FIFO</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>filter</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ANALOG_VALUE</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_buf">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_buf</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_enable_can_from_mpu">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_enable_can_from_mpu</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_enable_can_from_terminal">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_enable_can_from_terminal</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_on_off_pch">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_on_off_pch</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_received_first_mess_from_MPU">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_received_first_mess_from_MPU</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_reverse">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_reverse</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_send_answer_rs">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_send_answer_rs</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_test_tabe_filled">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_test_tabe_filled</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_fill_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="flag_we_int_pwm_on">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>flag_we_int_pwm_on</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="freq1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>freq1</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="freqTerm">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>freqTerm</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="global_time">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>global_time</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>GLOBAL_TIME</type>
|
|
||||||
<file>Src/main/global_time.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="hb_logs_data">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>hb_logs_data</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="i">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>i</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="i1_out">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>i1_out</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>BREAK2_PHASE</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="i2_out">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>i2_out</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>BREAK2_PHASE</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="init_log">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>init_log</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[3]</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq19_k_norm_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq19_k_norm_ADC</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq19</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq19[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq19_zero_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq19_zero_ADC</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq19</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq19[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq_alfa_coef">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq_alfa_coef</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq_k_norm_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq_k_norm_ADC</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq_logpar">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq_logpar</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>IQ_LOGSPARAMS</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq_max">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq_max</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/svgen_dq_v2.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="iq_norm_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>iq_norm_ADC</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="isolation1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>isolation1</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ISOLATION</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="isolation2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>isolation2</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ISOLATION</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="k1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>k1</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kI_D">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kI_D</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kI_D_Inv31">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kI_D_Inv31</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kI_Q">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kI_Q</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kI_Q_Inv31">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kI_Q_Inv31</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kP_D">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kP_D</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kP_D_Inv31">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kP_D_Inv31</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kP_Q">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kP_Q</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kP_Q_Inv31">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kP_Q_Inv31</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kan">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kan</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Base_stop_run">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Base_stop_run</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Iabc_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Iabc_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Im_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Im_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Im_filter_long">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Im_filter_long</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_K_stop_run">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_K_stop_run</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Krecup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Krecup</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Min_recup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Min_recup</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_TemperBSU_long_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_TemperBSU_long_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Ud_fast_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Ud_fast_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Ud_long_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Ud_long_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Wlong">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Wlong</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Wout_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Wout_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Wout_filter_long">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koef_Wout_filter_long</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Fs_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koeff_Fs_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Idq_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koeff_Idq_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Iq_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koeff_Iq_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Iq_filter_slow">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koeff_Iq_filter_slow</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Ud_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koeff_Ud_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Uq_filter">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>koeff_Uq_filter</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="kom">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>kom</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="length">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>length</shortname>
|
|
||||||
<pt_type>pt_uint32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>volatile unsigned long</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="level_on_off_break">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>level_on_off_break</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq[13][2]</type>
|
|
||||||
<file>Src/main/break_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="log_can">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>log_can</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>logcan_TypeDef</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="log_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>log_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>LOG_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="log_params">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>log_params</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>TYPE_LOG_PARAMS</type>
|
|
||||||
<file>Src/myLibs/log_params.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="logbuf_sync1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>logbuf_sync1</shortname>
|
|
||||||
<pt_type>pt_arr_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long[10]</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="logpar">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>logpar</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>LOGSPARAMS</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="mPWM_a">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mPWM_a</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mPWM_b">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mPWM_b</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="m_PWM">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>m_PWM</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="mailboxs_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mailboxs_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MAILBOXS_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="manufactorerAndProductID">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>manufactorerAndProductID</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_can_in">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_can_in</shortname>
|
|
||||||
<pt_type>pt_ptr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_can_out">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_can_out</shortname>
|
|
||||||
<pt_type>pt_ptr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_in">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_in</shortname>
|
|
||||||
<pt_type>pt_arr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT[450]</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_out">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_out</shortname>
|
|
||||||
<pt_type>pt_arr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT[450]</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_rs_in">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_rs_in</shortname>
|
|
||||||
<pt_type>pt_ptr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_rs_out">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_rs_out</shortname>
|
|
||||||
<pt_type>pt_ptr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_test">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>modbus_table_test</shortname>
|
|
||||||
<pt_type>pt_arr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT[450]</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="mpu_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mpu_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MPU_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_100">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_100</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_1000">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_1000</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_1100">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_1100</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_1200">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_1200</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_1400">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_1400</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_1500">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_1500</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_2000">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_2000</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="mzz_limit_500">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>mzz_limit_500</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="new_cycle_fifo">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>new_cycle_fifo</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>NEW_CYCLE_FIFO</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="no_write">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>no_write</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="no_write_slow">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>no_write_slow</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="number_modbus_table_changed">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>number_modbus_table_changed</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_fill_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="optical_read_data">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>optical_read_data</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>OPTICAL_BUS_DATA</type>
|
|
||||||
<file>Src/main/optical_bus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="optical_write_data">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>optical_write_data</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>OPTICAL_BUS_DATA</type>
|
|
||||||
<file>Src/main/optical_bus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="options_controller">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>options_controller</shortname>
|
|
||||||
<pt_type>pt_arr_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>MODBUS_REG_STRUCT[200]</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidCur_Ki">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidCur_Ki</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidD">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidD</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidD2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidD2</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidFvect">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidFvect</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/regul_turns.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidFvectKi_test">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidFvectKi_test</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/message2.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidFvectKp_test">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidFvectKp_test</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/message2.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidPvect">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidPvect</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidQ">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidQ</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidQ2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidQ2</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidReg_koeffs">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidReg_koeffs</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG_KOEFFICIENTS</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pidTetta">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pidTetta</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/teta_calc.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="power_ratio">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>power_ratio</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>POWER_RATIO</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="prev_flag_buf">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>prev_flag_buf</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="prev_status_received">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>prev_status_received</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="project">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>project</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>T_project</type>
|
|
||||||
<file>Src/myXilinx/xp_project.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="pwmd">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>pwmd</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>PWMGEND</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="r_c_sbus">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>r_c_sbus</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>T_controller_read</type>
|
|
||||||
<file>Src/myXilinx/x_serial_bus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="r_controller">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>r_controller</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>T_controller_read</type>
|
|
||||||
<file>Src/myXilinx/xp_hwp.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="refo">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>refo</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>FIFO</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="reply">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>reply</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>TMS_TO_TERMINAL_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="reply_test_all">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>reply_test_all</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>TMS_TO_TERMINAL_TEST_ALL_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="return_var">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>return_var</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="rmp_freq">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>rmp_freq</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>RMP_MY1</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="rmp_wrot">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>rmp_wrot</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>RMP_MY1</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="rotation_sensor">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>rotation_sensor</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>T_rotation_sensor</type>
|
|
||||||
<file>Src/myXilinx/xp_rotation_sensor.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="rotor">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>rotor</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>ROTOR_VALUE</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="rs_a">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>rs_a</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>RS_DATA_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="rs_b">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>rs_b</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>RS_DATA_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="sincronisationFault">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>sincronisationFault</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="size_cmd15">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>size_cmd15</shortname>
|
|
||||||
<pt_type>pt_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="size_cmd16">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>size_cmd16</shortname>
|
|
||||||
<pt_type>pt_int8</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>char</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="size_fast_done">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>size_fast_done</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="size_slow_done">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>size_slow_done</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="stop_log">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>stop_log</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="stop_log_slow">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>stop_log_slow</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_dq_1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>svgen_dq_1</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>SVGENDQ</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_dq_2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>svgen_dq_2</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>SVGENDQ</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_pwm24_1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>svgen_pwm24_1</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>SVGEN_PWM24</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_pwm24_2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>svgen_pwm24_2</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>SVGEN_PWM24</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="temp">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>temp</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_limit_koeff">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>temperature_limit_koeff</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/errors_temperature.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BI1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>temperature_warning_BI1</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>INVERTER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BI2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>temperature_warning_BI2</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>INVERTER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BV1">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>temperature_warning_BV1</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>RECTIFIER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BV2">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>temperature_warning_BV2</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>RECTIFIER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="terminal_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>terminal_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>TERMINAL_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="tetta_calc">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>tetta_calc</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>TETTA_CALC</type>
|
|
||||||
<file>Src/VectorControl/teta_calc.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="timCNT_alg">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>timCNT_alg</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="timCNT_prev">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>timCNT_prev</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="time">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>time</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="timePauseBENDER_Messages">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>timePauseBENDER_Messages</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/main22220.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="timePauseCAN_Messages">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>timePauseCAN_Messages</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/main22220.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>True</static>
|
|
||||||
</var>
|
|
||||||
<var name="time_alg">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>time_alg</shortname>
|
|
||||||
<pt_type>pt_float</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_enable_can_from_mpu">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>time_pause_enable_can_from_mpu</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_enable_can_from_terminal">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>time_pause_enable_can_from_terminal</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_logs">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>time_pause_logs</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_titles">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>time_pause_titles</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="tryNumb">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>tryNumb</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>volatile int</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="unites_can_setup">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>unites_can_setup</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>UNITES_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="var_numb">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>var_numb</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="vect_control">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>vect_control</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>VECTOR_CONTROL</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="water_cooler">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>water_cooler</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>WaterCooler</type>
|
|
||||||
<file>Src/myLibs/can_watercool.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="winding_displacement">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>winding_displacement</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="word">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>word</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>Word</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="wordReversed">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>wordReversed</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>WordReversed</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="wordToReverse">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>wordToReverse</shortname>
|
|
||||||
<pt_type>pt_union</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>WordToReverse</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="x_parallel_bus_project">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>x_parallel_bus_project</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>X_PARALLEL_BUS</type>
|
|
||||||
<file>Src/myXilinx/x_parallel_bus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="x_serial_bus_project">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>x_serial_bus_project</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>X_SERIAL_BUS</type>
|
|
||||||
<file>Src/myXilinx/x_serial_bus.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="xeeprom_controll_fast">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>xeeprom_controll_fast</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="xeeprom_controll_store">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>xeeprom_controll_store</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="xpwm_time">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>xpwm_time</shortname>
|
|
||||||
<pt_type>pt_struct</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>XPWM_TIME</type>
|
|
||||||
<file>Src/myXilinx/xp_write_xpwm_time.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="zadan_Id_min">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>zadan_Id_min</shortname>
|
|
||||||
<pt_type>pt_int32</pt_type>
|
|
||||||
<iq_type>t_iq</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="zero_ADC">
|
|
||||||
<show_var>false</show_var>
|
|
||||||
<enable>false</enable>
|
|
||||||
<shortname>zero_ADC</shortname>
|
|
||||||
<pt_type>pt_arr_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>int</return_type>
|
|
||||||
<type>int[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="project.cds_tk[0].plane_address">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>tk0_Adr</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>UInt16</type>
|
|
||||||
<file>Src/myXilinx/xp_project.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][0]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf00</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][1]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf01</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][2]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf02</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][3]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf03</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][4]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf04</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][5]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf05</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][6]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf06</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][7]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf07</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][8]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf08</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][9]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf09</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][10]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf010</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][11]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf011</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][12]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf012</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][13]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf013</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][14]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf014</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf[0][15]">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>ADC_sf015</shortname>
|
|
||||||
<pt_type>pt_int16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>t_iq_none</return_type>
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
<var name="project.cds_tk[0].read.sbus.mask_protect_tk.all">
|
|
||||||
<show_var>true</show_var>
|
|
||||||
<enable>true</enable>
|
|
||||||
<shortname>project.cds_tk[0].read.sbus.mask_protect_tk.all</shortname>
|
|
||||||
<pt_type>pt_uint16</pt_type>
|
|
||||||
<iq_type>t_iq_none</iq_type>
|
|
||||||
<return_type>iq_none</return_type>
|
|
||||||
<type>UInt16</type>
|
|
||||||
<file>Src/myXilinx/xp_project.c</file>
|
|
||||||
<extern>false</extern>
|
|
||||||
<static>false</static>
|
|
||||||
</var>
|
|
||||||
</variables>
|
|
||||||
<includes>
|
|
||||||
<file>Src/main/vector.h</file>
|
|
||||||
<file>Src/main/f281xpwm.h</file>
|
|
||||||
<file>Src/myLibs/log_can.h</file>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.h</file>
|
|
||||||
<file>Src/main/errors.h</file>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.h</file>
|
|
||||||
<file>Src/myXilinx/xp_project.h</file>
|
|
||||||
<file>Src/myXilinx/xp_write_xpwm_time.h</file>
|
|
||||||
<file>Src/main/v_pwm24.h</file>
|
|
||||||
<file>Src/main/adc_tools.h</file>
|
|
||||||
<file>Src/main/rotation_speed.h</file>
|
|
||||||
<file>Src/VectorControl/dq_to_alphabeta_cos.h</file>
|
|
||||||
<file>Src/VectorControl/teta_calc.h</file>
|
|
||||||
<file>Src/myLibs/CAN_Setup.h</file>
|
|
||||||
<file>Src/myLibs/log_to_memory.h</file>
|
|
||||||
<file>Src/myLibs/log_params.h</file>
|
|
||||||
<file>Src/myXilinx/CRC_Functions.h</file>
|
|
||||||
<file>Src/main/global_time.h</file>
|
|
||||||
<file>Src/myXilinx/RS_Functions.h</file>
|
|
||||||
<file>Src/myLibs/detect_phase_break2.h</file>
|
|
||||||
<file>Src/myXilinx/x_parallel_bus.h</file>
|
|
||||||
<file>Src/myXilinx/x_serial_bus.h</file>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.h</file>
|
|
||||||
<file>Src/myXilinx/xp_controller.h</file>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.h</file>
|
|
||||||
<file>Src/myXilinx/xp_rotation_sensor.h</file>
|
|
||||||
<file>Src/myLibs/svgen_dq.h</file>
|
|
||||||
<file>Src/myLibs/pid_reg3.h</file>
|
|
||||||
<file>Src/myLibs/IQmathLib.h</file>
|
|
||||||
<file>Src/main/doors_control.h</file>
|
|
||||||
<file>Src/main/isolation.h</file>
|
|
||||||
<file>Src/main/main22220.h</file>
|
|
||||||
<file>Src/main/optical_bus.h</file>
|
|
||||||
<file>Src/myLibs/alarm_log_can.h</file>
|
|
||||||
<file>Src/myLibs/bender.h</file>
|
|
||||||
<file>Src/myLibs/can_watercool.h</file>
|
|
||||||
<file>Src/myLibs/detect_phase_break.h</file>
|
|
||||||
<file>Src/myLibs/modbus_read_table.h</file>
|
|
||||||
<file>Src/myLibs/rmp_cntl_my1.h</file>
|
|
||||||
</includes>
|
|
||||||
<externs>
|
|
||||||
<var name="ADC0finishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC0startAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC1finishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC1startAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC2finishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC2startAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_f">
|
|
||||||
<type>int[2][16]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADC_sf">
|
|
||||||
<type>int[2][16]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ADDR_FOR_ALL">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="BUSY">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Bender">
|
|
||||||
<type>BENDER[2]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_answer_wait">
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_count_cycle_input_units">
|
|
||||||
<type>int[8]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_no_answer">
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_refresh_cicle">
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_request_sent">
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_timeout">
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CAN_timeout_cicle">
|
|
||||||
<type>int[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CNTRL_ADDR">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CNTRL_ADDR_UNIVERSAL">
|
|
||||||
<type>const int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CONST_15">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/mathlib.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CONST_23">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/mathlib.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CanOpenUnites">
|
|
||||||
<type>int[30]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="CanTimeOutErrorTR">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Controll">
|
|
||||||
<type>XControll_reg</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Dpwm">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Dpwm2">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Dpwm4">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="EvaTimer1InterruptCount">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="EvaTimer2InterruptCount">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="EvbTimer3InterruptCount">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="EvbTimer4InterruptCount">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/281xEvTimersInit.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Fpwm">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IN0finishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IN0startAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IN1finishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IN1startAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IN2finishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IN2startAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="IQ_OUT_NOM">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_1_6_NOMINAL_IQ">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_1_8_NOMINAL_IQ">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_NOMINAL">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="I_OUT_NOMINAL_IQ">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="I_ZPT_NOMINAL_IQ">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Id_out_max_full">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Id_out_max_low_speed">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Iq_out_max">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Iq_out_nom">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/params_i_out.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="K_LEM_ADC">
|
|
||||||
<type>const unsigned long[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="KmodTerm">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ROTfinishAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="RS_Len">
|
|
||||||
<type>unsigned int[70]</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="R_ADC">
|
|
||||||
<type>const unsigned int[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="RotPlaneStartAddr">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="SQRT_32">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/mathlib.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Unites">
|
|
||||||
<type>int[8][128]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_FREQ_PWM_XTICS">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_PERIOD_MAX_XTICS">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_PERIOD_MIN_BR_XTICS">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="VAR_PERIOD_MIN_XTICS">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="Zpwm">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="a">
|
|
||||||
<type>WINDING</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="addrToSent">
|
|
||||||
<type>volatile AddrToSent</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="adr_read_from_modbus3">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="alarm_log_can">
|
|
||||||
<type>ALARM_LOG_CAN</type>
|
|
||||||
<file>Src/myLibs/alarm_log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="alarm_log_can_setup">
|
|
||||||
<type>ALARM_LOG_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="analog">
|
|
||||||
<type>ANALOG_VALUE</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ar_sa_all">
|
|
||||||
<type>int[3][6][4][7]</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="ar_tph">
|
|
||||||
<type>_iq[7]</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="block_size_counter_fast">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="block_size_counter_slow">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_1">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_2">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_3">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="break_result_4">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="byte">
|
|
||||||
<type>Byte</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="c_s">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="calibration1">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="calibration2">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="callfunc">
|
|
||||||
<type>test_functions</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="canopen_can_setup">
|
|
||||||
<type>CANOPEN_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="capnum0">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="capnum1">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="capnum2">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="capnum3">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="chNum">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/x_example_all.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="chanell1">
|
|
||||||
<type>BREAK_PHASE_I</type>
|
|
||||||
<file>Src/main/detect_phase.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="chanell2">
|
|
||||||
<type>BREAK_PHASE_I</type>
|
|
||||||
<file>Src/main/detect_phase.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="cmd_3_or_16">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="compress_size">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/alarm_log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="controlReg">
|
|
||||||
<type>ControlReg</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="cos_fi">
|
|
||||||
<type>COS_FI_STRUCT</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="count_error_sync">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="count_modbus_table_changed">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_fill_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="count_run_pch">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="crc_16_tab">
|
|
||||||
<type>WORD[256]</type>
|
|
||||||
<file>Src/myXilinx/CRC_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="crypt">
|
|
||||||
<type>char[34]</type>
|
|
||||||
<file>Src/myLibs/bender.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="cur_position_buf_modbus16_can">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/message_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="cycle">
|
|
||||||
<type>CYCLE[32]</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="delta_capnum">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="delta_error">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="doors">
|
|
||||||
<type>volatile DOORS_STATUS</type>
|
|
||||||
<file>Src/main/doors_control.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="enable_can">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/message_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="enable_can_recive_after_units_box">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="err_level_adc">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="err_level_adc_on_go">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="err_main">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="err_modbus16">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="err_modbus3">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="errors">
|
|
||||||
<type>ERRORS</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="f">
|
|
||||||
<type>FLAG</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="fail">
|
|
||||||
<type>volatile int</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="faults">
|
|
||||||
<type>FAULTS</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="fifo">
|
|
||||||
<type>FIFO</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="filter">
|
|
||||||
<type>ANALOG_VALUE</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_buf">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_enable_can_from_mpu">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_enable_can_from_terminal">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_on_off_pch">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_received_first_mess_from_MPU">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_reverse">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_send_answer_rs">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_test_tabe_filled">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_fill_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="flag_we_int_pwm_on">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="freq1">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="freqTerm">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="global_time">
|
|
||||||
<type>GLOBAL_TIME</type>
|
|
||||||
<file>Src/main/global_time.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="hb_logs_data">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="i">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="i1_out">
|
|
||||||
<type>BREAK2_PHASE</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="i2_out">
|
|
||||||
<type>BREAK2_PHASE</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="init_log">
|
|
||||||
<type>int[3]</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq19_k_norm_ADC">
|
|
||||||
<type>_iq19[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq19_zero_ADC">
|
|
||||||
<type>_iq19[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq_alfa_coef">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq_k_norm_ADC">
|
|
||||||
<type>_iq[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq_logpar">
|
|
||||||
<type>IQ_LOGSPARAMS</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq_max">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/myLibs/svgen_dq_v2.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="iq_norm_ADC">
|
|
||||||
<type>_iq[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="isolation1">
|
|
||||||
<type>ISOLATION</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="isolation2">
|
|
||||||
<type>ISOLATION</type>
|
|
||||||
<file>Src/main/isolation.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="k1">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kI_D">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kI_D_Inv31">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kI_Q">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kI_Q_Inv31">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kP_D">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kP_D_Inv31">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kP_Q">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="kP_Q_Inv31">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Base_stop_run">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Iabc_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Im_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Im_filter_long">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_K_stop_run">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Krecup">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Min_recup">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/break_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_TemperBSU_long_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Ud_fast_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Ud_long_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Wlong">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Wout_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koef_Wout_filter_long">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Fs_filter">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Idq_filter">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Iq_filter">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Iq_filter_slow">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Ud_filter">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="koeff_Uq_filter">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="length">
|
|
||||||
<type>volatile unsigned long</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="level_on_off_break">
|
|
||||||
<type>_iq[13][2]</type>
|
|
||||||
<file>Src/main/break_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="log_can">
|
|
||||||
<type>logcan_TypeDef</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="log_can_setup">
|
|
||||||
<type>LOG_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="log_params">
|
|
||||||
<type>TYPE_LOG_PARAMS</type>
|
|
||||||
<file>Src/myLibs/log_params.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="logbuf_sync1">
|
|
||||||
<type>long[10]</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="logpar">
|
|
||||||
<type>LOGSPARAMS</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="m_PWM">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="mailboxs_can_setup">
|
|
||||||
<type>MAILBOXS_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="manufactorerAndProductID">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_can_in">
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_can_out">
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_in">
|
|
||||||
<type>MODBUS_REG_STRUCT[450]</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_out">
|
|
||||||
<type>MODBUS_REG_STRUCT[450]</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_rs_in">
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_rs_out">
|
|
||||||
<type>MODBUS_REG_STRUCT *</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="modbus_table_test">
|
|
||||||
<type>MODBUS_REG_STRUCT[450]</type>
|
|
||||||
<file>Src/myLibs/modbus_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="mpu_can_setup">
|
|
||||||
<type>MPU_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="new_cycle_fifo">
|
|
||||||
<type>NEW_CYCLE_FIFO</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="no_write">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="no_write_slow">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="number_modbus_table_changed">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/modbus_fill_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="optical_read_data">
|
|
||||||
<type>OPTICAL_BUS_DATA</type>
|
|
||||||
<file>Src/main/optical_bus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="optical_write_data">
|
|
||||||
<type>OPTICAL_BUS_DATA</type>
|
|
||||||
<file>Src/main/optical_bus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="options_controller">
|
|
||||||
<type>MODBUS_REG_STRUCT[200]</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidCur_Ki">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidD">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidD2">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidFvect">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/regul_turns.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidFvectKi_test">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/message2.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidFvectKp_test">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/message2.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidPvect">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/regul_power.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidQ">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidQ2">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidReg_koeffs">
|
|
||||||
<type>PIDREG_KOEFFICIENTS</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pidTetta">
|
|
||||||
<type>PIDREG3</type>
|
|
||||||
<file>Src/VectorControl/teta_calc.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="power_ratio">
|
|
||||||
<type>POWER_RATIO</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="prev_flag_buf">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="prev_status_received">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="project">
|
|
||||||
<type>T_project</type>
|
|
||||||
<file>Src/myXilinx/xp_project.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="pwmd">
|
|
||||||
<type>PWMGEND</type>
|
|
||||||
<file>Src/main/PWMTMSHandle.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="r_c_sbus">
|
|
||||||
<type>T_controller_read</type>
|
|
||||||
<file>Src/myXilinx/x_serial_bus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="r_controller">
|
|
||||||
<type>T_controller_read</type>
|
|
||||||
<file>Src/myXilinx/xp_hwp.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="refo">
|
|
||||||
<type>FIFO</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="reply">
|
|
||||||
<type>TMS_TO_TERMINAL_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="reply_test_all">
|
|
||||||
<type>TMS_TO_TERMINAL_TEST_ALL_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions_modbus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="return_var">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="rmp_freq">
|
|
||||||
<type>RMP_MY1</type>
|
|
||||||
<file>Src/main/PWMTools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="rmp_wrot">
|
|
||||||
<type>RMP_MY1</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="rotation_sensor">
|
|
||||||
<type>T_rotation_sensor</type>
|
|
||||||
<file>Src/myXilinx/xp_rotation_sensor.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="rotor">
|
|
||||||
<type>ROTOR_VALUE</type>
|
|
||||||
<file>Src/main/rotation_speed.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="rs_a">
|
|
||||||
<type>RS_DATA_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="rs_b">
|
|
||||||
<type>RS_DATA_STRUCT</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="sincronisationFault">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myLibs/modbus_read_table.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="size_cmd15">
|
|
||||||
<type>char</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="size_cmd16">
|
|
||||||
<type>char</type>
|
|
||||||
<file>Src/myXilinx/RS_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="size_fast_done">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="size_slow_done">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="stop_log">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="stop_log_slow">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_to_memory.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_dq_1">
|
|
||||||
<type>SVGENDQ</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_dq_2">
|
|
||||||
<type>SVGENDQ</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_pwm24_1">
|
|
||||||
<type>SVGEN_PWM24</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="svgen_pwm24_2">
|
|
||||||
<type>SVGEN_PWM24</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="temp">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/main/sync_tools.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_limit_koeff">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/errors_temperature.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BI1">
|
|
||||||
<type>INVERTER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BI2">
|
|
||||||
<type>INVERTER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BV1">
|
|
||||||
<type>RECTIFIER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="temperature_warning_BV2">
|
|
||||||
<type>RECTIFIER_TEMPERATURES</type>
|
|
||||||
<file>Src/main/errors.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="terminal_can_setup">
|
|
||||||
<type>TERMINAL_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="tetta_calc">
|
|
||||||
<type>TETTA_CALC</type>
|
|
||||||
<file>Src/VectorControl/teta_calc.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="timCNT_alg">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="timCNT_prev">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="time">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="time_alg">
|
|
||||||
<type>float</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_enable_can_from_mpu">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_enable_can_from_terminal">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_logs">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="time_pause_titles">
|
|
||||||
<type>int</type>
|
|
||||||
<file>Src/myLibs/log_can.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="tryNumb">
|
|
||||||
<type>volatile int</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="unites_can_setup">
|
|
||||||
<type>UNITES_CAN_SETUP</type>
|
|
||||||
<file>Src/myLibs/CAN_Setup.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="var_numb">
|
|
||||||
<type>long</type>
|
|
||||||
<file>Src/main/Main.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="vect_control">
|
|
||||||
<type>VECTOR_CONTROL</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="water_cooler">
|
|
||||||
<type>WaterCooler</type>
|
|
||||||
<file>Src/myLibs/can_watercool.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="winding_displacement">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/main/v_pwm24.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="word">
|
|
||||||
<type>Word</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="wordReversed">
|
|
||||||
<type>WordReversed</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="wordToReverse">
|
|
||||||
<type>WordToReverse</type>
|
|
||||||
<file>Src/myXilinx/xPeriphSP6_loader.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="x_parallel_bus_project">
|
|
||||||
<type>X_PARALLEL_BUS</type>
|
|
||||||
<file>Src/myXilinx/x_parallel_bus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="x_serial_bus_project">
|
|
||||||
<type>X_SERIAL_BUS</type>
|
|
||||||
<file>Src/myXilinx/x_serial_bus.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="xeeprom_controll_fast">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="xeeprom_controll_store">
|
|
||||||
<type>unsigned int</type>
|
|
||||||
<file>Src/myXilinx/Spartan2E_Functions.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="xpwm_time">
|
|
||||||
<type>XPWM_TIME</type>
|
|
||||||
<file>Src/myXilinx/xp_write_xpwm_time.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="zadan_Id_min">
|
|
||||||
<type>_iq</type>
|
|
||||||
<file>Src/VectorControl/pwm_vector_regul.c</file>
|
|
||||||
</var>
|
|
||||||
<var name="zero_ADC">
|
|
||||||
<type>int[20]</type>
|
|
||||||
<file>Src/main/adc_tools.c</file>
|
|
||||||
</var>
|
|
||||||
</externs>
|
|
||||||
</analysis>
|
|
||||||
Reference in New Issue
Block a user