Compare commits
6 Commits
c32dc161f8
...
v1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
043359fe66 | ||
|
|
c55f38ef1c | ||
|
|
ae2c90160e | ||
|
|
4de53090a1 | ||
|
|
742c4e9e1b | ||
|
|
369cfa808c |
BIN
DebugVarEdit.exe
BIN
DebugVarEdit.exe
Binary file not shown.
68
README.md
68
README.md
@@ -1,21 +1,56 @@
|
|||||||
# DebugVarEdit — Утилита для генерации отладочных переменных C-проекта
|
# 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);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Переменные доступные для чтения определяются в **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" }, \
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
# DebugVarEdit - Настройка переменных
|
||||||
**DebugVarEdit** — графическое приложение для Windows, предназначенное для настройки и генерации отладочных переменных (`debug_vars.c`) на основе исходного C-проекта. Работает с `makefile` проекта, сохраняет изменения в XML и позволяет удобно редактировать переменные и их типы через интерфейс.
|
**DebugVarEdit** — графическое приложение для Windows, предназначенное для настройки и генерации отладочных переменных (`debug_vars.c`) на основе исходного C-проекта. Работает с `makefile` проекта, сохраняет изменения в XML и позволяет удобно редактировать переменные и их типы через интерфейс.
|
||||||
|
|
||||||
Программа — один исполняемый файл `DebugVarEdit.exe`, не требующий установки и дополнительных зависимостей.
|
Программа — один исполняемый файл `DebugVarEdit.exe`, не требующий установки и дополнительных зависимостей.
|
||||||
|
|
||||||
> Требуется Windows 7 или новее.
|
> Требуется Windows 7 или новее.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Как использовать
|
## Как использовать приложение
|
||||||
|
|
||||||
1. Запустите **DebugVarEdit.exe.**
|
1. Запустите **DebugVarEdit.exe.**
|
||||||
|
|
||||||
2. Укажите пути:
|
2. Укажите пути и контроллер:
|
||||||
- **Путь к XML** — новый или существующий файл настроек переменных;
|
- **Путь к XML** — новый или существующий файл настроек переменных;
|
||||||
- **Путь к проекту** — путь к корню проека (папка, которая является корнем для проекта в Code Composer);
|
- **Путь к проекту** — путь к корню проека (папка, которая является корнем для проекта в Code Composer);
|
||||||
- **Путь к makefile** — путь к `makefile` относительно корня проекта;
|
- **Путь к makefile** — путь к `makefile` относительно корня проекта;
|
||||||
- **Путь для debug_vars.c** — папка, куда будет сгенерирован файл `debug_vars.c` с переменными.
|
- **Путь для debug_vars.c** — папка, куда будет сгенерирован файл `debug_vars.c` с переменными.
|
||||||
|
- **МК** — TMS или STM. Они отличаются размером int, и также принятыми кодировками файлов (utf-8/cp1251)
|
||||||
|
|
||||||
3. Нажмите **Сканировать переменные**:
|
3. Нажмите **Сканировать переменные**:
|
||||||
- Программа проанализирует исходники, указанные в makefile, и найдёт все переменные.
|
- Программа проанализирует исходники, указанные в makefile, и найдёт все переменные.
|
||||||
@@ -59,7 +94,7 @@
|
|||||||
## Пример XML-файла
|
## Пример XML-файла
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<project proj_path="C:/myproj" makefile_path="Debug/Makefile" structs_path="debugVars/structs.xml">
|
<project proj_path="C:/myproj" makefile_path="Debug/Makefile" structs_path="Src/DebugTools/structs.xml">
|
||||||
<variables>
|
<variables>
|
||||||
<var name="g_myvar">
|
<var name="g_myvar">
|
||||||
<enable>true</enable>
|
<enable>true</enable>
|
||||||
@@ -77,6 +112,7 @@
|
|||||||
</project>
|
</project>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
---
|
---
|
||||||
|
|
||||||
# Для разработчиков
|
# Для разработчиков
|
||||||
@@ -85,34 +121,34 @@
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
Src
|
Src
|
||||||
|
├── build/
|
||||||
|
│ └── build_and_clean.py # Билдинг проекта в .exe (через nuitka или pyinstaller)
|
||||||
├── DebugVarEdit_GUI.py # Главное окно
|
├── DebugVarEdit_GUI.py # Главное окно
|
||||||
├── var_table.py # Таблица выбранных переменных
|
├── var_table.py # Таблица выбранных переменных
|
||||||
├── var_selector_window.py # Окно выбора переменных
|
├── var_selector_window.py # Окно выбора переменных
|
||||||
├── var_selector_table.py # Таблица переменных в окне выбора переменных
|
├── var_selector_table.py # Таблица переменных в окне выбора переменных
|
||||||
├── scan_progress_gui.py # Отображение процесса сканирования переменных
|
├── scan_progress_gui.py # Отображение процесса сканирования переменных
|
||||||
├── scan_vars.py # Сканирование переменных среди .c/.h файлов
|
├── scan_vars.py # Сканирование переменных среди .c/.h файлов
|
||||||
├── generate_debug_vars.py # Генерация debug_vars.c
|
├── generate_debug_vars.py # Генерация debug_vars.c
|
||||||
├── myXML.py # Утилиты для XML
|
├── myXML.py # Утилиты для XML
|
||||||
├── makefile_parser.py # Парсинг makefile на .c/.h файлы
|
├── makefile_parser.py # Парсинг makefile на .c/.h файлы
|
||||||
├── var_setup.py # Подготовка переменных для окна выбора переменных
|
├── var_setup.py # Подготовка переменных для окна выбора переменных
|
||||||
├── libclang.dll # Бибилиотека clang
|
├── libclang.dll # Бибилиотека clang
|
||||||
├── icon.ico # Иконка
|
├── icon.ico # Иконка
|
||||||
build
|
|
||||||
├── build_and_clean.py # Билдинг проекта в .exe (через nuitka или pyinstaller)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Зависимости
|
### Зависимости
|
||||||
|
|
||||||
Для запуска приложения:
|
Для запуска приложения:
|
||||||
- **Python 3.7+**
|
- **Python 3.7+**
|
||||||
- **clang** — используется для парсинга C-кода (требуется `libclang.dll`)
|
- **clang** — используется для парсинга C-кода (требуется `libclang.dll`, лежит в папке Src)
|
||||||
- **PySide2** — GUI-фреймворк
|
- **PySide2** — GUI-фреймворк
|
||||||
- **lxml** — работа с XML
|
- **lxml** — работа с XML
|
||||||
> Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7
|
> Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7
|
||||||
|
|
||||||
Для сборки `.exe`:
|
Для сборки `.exe`:
|
||||||
- **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей
|
- **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей
|
||||||
- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен)
|
- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен для запуска `.exe`)
|
||||||
|
|
||||||
|
|
||||||
### Сборка:
|
### Сборка:
|
||||||
@@ -132,5 +168,5 @@ build
|
|||||||
### Установка зависимостей
|
### Установка зависимостей
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pip install PySide2 lxml nuitka pyinstaller
|
pip install clang PySide2 lxml nuitka pyinstaller
|
||||||
```
|
```
|
||||||
@@ -5,13 +5,13 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import lxml.etree as ET
|
import lxml.etree as ET
|
||||||
from generate_debug_vars import type_map
|
from generate_debug_vars import type_map, choose_type_map
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
import threading
|
import threading
|
||||||
from generate_debug_vars import run_generate
|
from generate_debug_vars import run_generate
|
||||||
import var_setup
|
import var_setup
|
||||||
from var_selector_window import var_selector_windowDialog
|
from var_selector_window import VariableSelectorDialog
|
||||||
from var_table import var_tableWidget, rows
|
from var_table import VariableTableWidget, rows
|
||||||
from scan_progress_gui import ProcessOutputWindow
|
from scan_progress_gui import ProcessOutputWindow
|
||||||
import scan_vars
|
import scan_vars
|
||||||
import myXML
|
import myXML
|
||||||
@@ -21,8 +21,9 @@ 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
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ 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):
|
||||||
@@ -122,6 +124,32 @@ 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)
|
||||||
|
|
||||||
|
menubar.addMenu(self.target_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)
|
||||||
@@ -134,9 +162,10 @@ class VarEditor(QWidget):
|
|||||||
btn_open_output = QPushButton(open_output_title)
|
btn_open_output = QPushButton(open_output_title)
|
||||||
btn_open_output.clicked.connect(self.__open_output_file_with_program)
|
btn_open_output.clicked.connect(self.__open_output_file_with_program)
|
||||||
# Таблица
|
# Таблица
|
||||||
self.table = var_tableWidget()
|
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)
|
||||||
@@ -150,7 +179,20 @@ class VarEditor(QWidget):
|
|||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
return xml_path
|
return xml_path
|
||||||
@@ -208,7 +250,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_scan_vars_finished)
|
self.__after_scan_vars_finished, self)
|
||||||
self.proc_win.start_scan()
|
self.proc_win.start_scan()
|
||||||
|
|
||||||
|
|
||||||
@@ -241,7 +283,7 @@ 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:
|
||||||
@@ -358,15 +400,25 @@ class VarEditor(QWidget):
|
|||||||
super().keyPressEvent(event)
|
super().keyPressEvent(event)
|
||||||
|
|
||||||
def __browse_makefile(self):
|
def __browse_makefile(self):
|
||||||
|
if self.target == 'stm':
|
||||||
|
file_filter = "Makefile или Keil-проект (*.uvprojx *.uvproj makefile);;Все файлы (*)"
|
||||||
|
dialog_title = "Выберите Makefile или Keil-проект"
|
||||||
|
else: # 'TMS' или по умолчанию
|
||||||
|
file_filter = "Makefile (makefile);;Все файлы (*)"
|
||||||
|
dialog_title = "Выберите Makefile"
|
||||||
|
|
||||||
file_path, _ = QFileDialog.getOpenFileName(
|
file_path, _ = QFileDialog.getOpenFileName(
|
||||||
self, "Выберите Makefile", filter="Makefile (makefile);;All Files (*)"
|
self,
|
||||||
|
dialog_title,
|
||||||
|
filter=file_filter
|
||||||
)
|
)
|
||||||
if file_path and self.proj_path:
|
if file_path:
|
||||||
path = myXML.make_relative_path(file_path, self.proj_path)
|
if self.proj_path:
|
||||||
else:
|
path = myXML.make_relative_path(file_path, self.proj_path)
|
||||||
path = file_path
|
else:
|
||||||
self.makefile_edit.setText(path)
|
path = file_path
|
||||||
self.makefile_path = path
|
self.makefile_edit.setText(path)
|
||||||
|
self.makefile_path = path
|
||||||
|
|
||||||
def __browse_source_output(self):
|
def __browse_source_output(self):
|
||||||
dir_path = QFileDialog.getExistingDirectory(self, "Выберите папку для debug_vars.c")
|
dir_path = QFileDialog.getExistingDirectory(self, "Выберите папку для debug_vars.c")
|
||||||
@@ -438,12 +490,13 @@ class VarEditor(QWidget):
|
|||||||
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
|
||||||
|
|
||||||
dlg = var_selector_windowDialog(self.table, self.vars_list, self.structs, self.typedef_map, self.xml_path, self)
|
dlg = VariableSelectorDialog(self.table, self.vars_list, self.structs, self.typedef_map, self.xml_path, self)
|
||||||
if dlg.exec_():
|
if dlg.exec_():
|
||||||
self.write_to_xml()
|
self.write_to_xml()
|
||||||
self.update()
|
self.update()
|
||||||
|
|||||||
55
Src/README_DEVELOP.md
Normal file
55
Src/README_DEVELOP.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Для разработчиков
|
||||||
|
|
||||||
|
### Структура проекта:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
Src
|
||||||
|
├── build/
|
||||||
|
│ └── build_and_clean.py # Билдинг проекта в .exe (через nuitka или pyinstaller)
|
||||||
|
├── DebugVarEdit_GUI.py # Главное окно
|
||||||
|
├── 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
|
||||||
|
├── myXML.py # Утилиты для XML
|
||||||
|
├── makefile_parser.py # Парсинг makefile на .c/.h файлы
|
||||||
|
├── var_setup.py # Подготовка переменных для окна выбора переменных
|
||||||
|
├── libclang.dll # Бибилиотека clang
|
||||||
|
├── icon.ico # Иконка
|
||||||
|
```
|
||||||
|
|
||||||
|
### Зависимости
|
||||||
|
|
||||||
|
Для запуска приложения:
|
||||||
|
- **Python 3.7+**
|
||||||
|
- **clang** — используется для парсинга C-кода (требуется `libclang.dll`)
|
||||||
|
- **PySide2** — GUI-фреймворк
|
||||||
|
- **lxml** — работа с XML
|
||||||
|
> Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7
|
||||||
|
|
||||||
|
Для сборки `.exe`:
|
||||||
|
- **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей
|
||||||
|
- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен)
|
||||||
|
|
||||||
|
|
||||||
|
### Сборка:
|
||||||
|
Если вы хотите собрать `DebugVarEdit.exe` самостоятельно из исходников, используйте скрипт **build/build_and_clean.py**. Он автоматически собирает проект с помощью Nuitka или PyInstaller:
|
||||||
|
- Собирает проект в `DebugVarEdit.exe` в корневой папке.
|
||||||
|
- Включает:
|
||||||
|
- все необходимые `.dll` (например, `libclang.dll`),
|
||||||
|
- иконку (`icon.ico`),
|
||||||
|
- плагины PySide2.
|
||||||
|
- Очищает временные папки после сборки:
|
||||||
|
- `build_temp`
|
||||||
|
- `__pycache__`
|
||||||
|
- `DebugVarEdit_GUI.*`
|
||||||
|
|
||||||
|
> Все пути, имена файлов, временные папки и выбор между Nuitka и PyInstaller можно настроить в начале файла `build_and_clean.py`.
|
||||||
|
|
||||||
|
### Установка зависимостей
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install PySide2 lxml nuitka pyinstaller
|
||||||
|
```
|
||||||
@@ -12,9 +12,10 @@ 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,15 +285,20 @@ 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_]*(?:\.[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)
|
||||||
@@ -285,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
|
||||||
@@ -338,7 +503,7 @@ def generate_vars_file(proj_path, xml_path, output_dir):
|
|||||||
# Дополнительные поля, например комментарий
|
# Дополнительные поля, например комментарий
|
||||||
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:<57} {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)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
from lxml import etree as ET
|
||||||
|
|
||||||
|
|
||||||
def strip_single_line_comments(code):
|
def strip_single_line_comments(code):
|
||||||
@@ -66,89 +67,176 @@ def find_all_includes_recursive(c_files, include_dirs, processed_files=None):
|
|||||||
return include_files
|
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):
|
def parse_makefile(makefile_path, proj_path):
|
||||||
makefile_dir = os.path.dirname(makefile_path)
|
import os
|
||||||
project_root = proj_path
|
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:
|
with open(makefile_path, 'r', encoding='utf-8') as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
|
|
||||||
objs_lines = []
|
raw_entries = []
|
||||||
collecting = False
|
collecting = False
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
stripped = line.strip()
|
stripped = line.strip()
|
||||||
if stripped.startswith("ORDERED_OBJS") and "+=" in stripped:
|
|
||||||
parts = stripped.split("\\")
|
if (("ORDERED_OBJS" in stripped or "C_SOURCES" in stripped) and ("+=" in stripped or "=" in stripped)):
|
||||||
first_part = parts[0]
|
|
||||||
idx = first_part.find("+=")
|
|
||||||
tail = first_part[idx+2:].strip()
|
|
||||||
if tail:
|
|
||||||
objs_lines.append(tail)
|
|
||||||
collecting = True
|
collecting = True
|
||||||
if len(parts) > 1:
|
|
||||||
for p in parts[1:]:
|
|
||||||
p = p.strip()
|
|
||||||
if p:
|
|
||||||
objs_lines.append(p)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if collecting:
|
if collecting:
|
||||||
if stripped.endswith("\\"):
|
line_clean = stripped.rstrip("\\").strip()
|
||||||
objs_lines.append(stripped[:-1].strip())
|
if line_clean:
|
||||||
else:
|
line_clean = re.sub(r"\$\([^)]+\)", "", line_clean)
|
||||||
objs_lines.append(stripped)
|
line_clean = re.sub(r"\$\{[^}]+\}", "", line_clean)
|
||||||
|
raw_entries.append(line_clean)
|
||||||
|
|
||||||
|
if not stripped.endswith("\\"):
|
||||||
collecting = False
|
collecting = False
|
||||||
|
|
||||||
objs_str = ' '.join(objs_lines)
|
for entry in raw_entries:
|
||||||
|
for token in entry.split():
|
||||||
|
token = token.strip('"')
|
||||||
|
if not token:
|
||||||
|
continue
|
||||||
|
|
||||||
objs_str = re.sub(r"\$\([^)]+\)", "", objs_str)
|
token = token.replace("\\", "/")
|
||||||
|
|
||||||
objs = []
|
if token.endswith(".obj"):
|
||||||
for part in objs_str.split():
|
token = re.sub(r"\.obj$", ".c", token)
|
||||||
part = part.strip()
|
elif token.endswith(".o"):
|
||||||
if part.startswith('"') and part.endswith('"'):
|
token = re.sub(r"\.o$", ".c", token)
|
||||||
part = part[1:-1]
|
|
||||||
if part:
|
|
||||||
objs.append(part)
|
|
||||||
|
|
||||||
c_files = []
|
if token.endswith(".c"):
|
||||||
include_dirs = set()
|
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))
|
||||||
|
|
||||||
for obj_path in objs:
|
if not c_files:
|
||||||
if "DebugTools" in obj_path:
|
makefile_dir = os.path.dirname(os.path.abspath(makefile_path))
|
||||||
continue
|
objects_list_path = os.path.join(makefile_dir, "objects.list")
|
||||||
if "v120" in obj_path:
|
c_from_objects, inc_from_objects = parse_objects_list(objects_list_path, project_root)
|
||||||
continue
|
c_files.extend(c_from_objects)
|
||||||
if "v100" in obj_path:
|
include_dirs.update(inc_from_objects)
|
||||||
continue
|
|
||||||
|
|
||||||
if obj_path.startswith("Debug\\") or obj_path.startswith("Debug/"):
|
for line in lines:
|
||||||
rel_path = obj_path.replace("Debug\\", "Src\\").replace("Debug/", "Src/")
|
if "-I" in line or "C_INCLUDES" in line:
|
||||||
else:
|
matches = re.findall(r"-I\s*([^\s\\]+)", line)
|
||||||
rel_path = obj_path
|
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)
|
||||||
|
|
||||||
abs_path = os.path.normpath(os.path.join(project_root, rel_path))
|
# Добавляем пути с заменой 'Src' на 'Inc', если путь заканчивается на 'Src'
|
||||||
|
additional_includes = set()
|
||||||
root, ext = os.path.splitext(abs_path)
|
for inc in include_dirs:
|
||||||
if ext.lower() == ".obj":
|
if inc.endswith(os.sep + "Src") or inc.endswith("/Src"):
|
||||||
c_path = root + ".c"
|
inc_inc = inc[:-3] + "Inc" # заменяем 'Src' на 'Inc'
|
||||||
else:
|
if os.path.isdir(inc_inc):
|
||||||
c_path = abs_path
|
additional_includes.add(inc_inc)
|
||||||
|
|
||||||
# Проверяем существование файла, если нет — пропускаем
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
include_dirs.update(additional_includes)
|
||||||
|
|
||||||
h_files = find_all_includes_recursive(c_files, include_dirs)
|
h_files = find_all_includes_recursive(c_files, include_dirs)
|
||||||
|
|
||||||
|
return sorted(c_files), sorted(h_files), sorted(include_dirs), sorted(defines)
|
||||||
|
|
||||||
return sorted(c_files), sorted(h_files), sorted(include_dirs)
|
|
||||||
|
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)
|
||||||
@@ -7,7 +7,7 @@ import contextlib
|
|||||||
import io
|
import io
|
||||||
import json
|
import json
|
||||||
from scan_vars import run_scan
|
from scan_vars import run_scan
|
||||||
from var_table import var_tableWidget, 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
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ from clang import cindex
|
|||||||
from clang.cindex import Config
|
from clang.cindex import Config
|
||||||
import lxml.etree as ET
|
import lxml.etree as ET
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
from makefile_parser 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)
|
||||||
@@ -170,7 +171,12 @@ def analyze_variables_across_files(c_files, h_files, include_dirs):
|
|||||||
return # игнорируем только явно известные служебные переменные
|
return # игнорируем только явно известные служебные переменные
|
||||||
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}"
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -244,7 +244,6 @@ class VariableSelectWidget(QWidget):
|
|||||||
|
|
||||||
def filter_tree(self):
|
def filter_tree(self):
|
||||||
text = self.search_input.text().strip().lower()
|
text = self.search_input.text().strip().lower()
|
||||||
print(f"[{self.objectName()}] Filtering tree with text: '{text}'")
|
|
||||||
path_parts = split_path(text) if text else []
|
path_parts = split_path(text) if text else []
|
||||||
|
|
||||||
if '.' not in text and '->' not in text and '[' not in text and text != '':
|
if '.' not in text and '->' not in text and '[' not in text and text != '':
|
||||||
@@ -358,8 +357,6 @@ class VariableSelectWidget(QWidget):
|
|||||||
|
|
||||||
self.completer.setModel(QStringListModel(completions))
|
self.completer.setModel(QStringListModel(completions))
|
||||||
self.completer.complete()
|
self.completer.complete()
|
||||||
print(f"[{self.objectName()}] Updating completions for text: '{text}' -> {len(completions)} completions found.")
|
|
||||||
print(f" Completions: {completions[:5]}") # Вывести первые 5 для проверки
|
|
||||||
return completions
|
return completions
|
||||||
|
|
||||||
|
|
||||||
@@ -469,7 +466,6 @@ class VariableSelectWidget(QWidget):
|
|||||||
def on_search_text_changed(self, text):
|
def on_search_text_changed(self, text):
|
||||||
sender_widget = self.sender()
|
sender_widget = self.sender()
|
||||||
sender_name = sender_widget.objectName() if sender_widget else "Unknown Sender"
|
sender_name = sender_widget.objectName() if sender_widget else "Unknown Sender"
|
||||||
print(f"[{self.objectName()}] (Sender: {sender_name}) Search text changed: '{text}'")
|
|
||||||
|
|
||||||
self.completer.setWidget(self.search_input)
|
self.completer.setWidget(self.search_input)
|
||||||
self.filter_tree()
|
self.filter_tree()
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import var_selector_table
|
|||||||
|
|
||||||
array_re = re.compile(r'^(\w+)\[(\d+)\]$')
|
array_re = re.compile(r'^(\w+)\[(\d+)\]$')
|
||||||
|
|
||||||
class var_selector_windowDialog(QDialog):
|
class VariableSelectorDialog(QDialog):
|
||||||
def __init__(self, table, all_vars, structs, typedefs, xml_path=None, parent=None):
|
def __init__(self, table, all_vars, structs, typedefs, xml_path=None, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setWindowTitle("Выбор переменных")
|
self.setWindowTitle("Выбор переменных")
|
||||||
@@ -62,11 +62,29 @@ class var_selector_windowDialog(QDialog):
|
|||||||
self.selected_vars_widget.tree.itemDoubleClicked.connect(self.on_rigth_tree_double_click)
|
self.selected_vars_widget.tree.itemDoubleClicked.connect(self.on_rigth_tree_double_click)
|
||||||
self.selected_vars_widget.setObjectName("RightTable")
|
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 окна
|
main_layout = QVBoxLayout(self) # главный вертикальный layout окна
|
||||||
|
|
||||||
tables_layout = QHBoxLayout() # горизонтальный 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)
|
self.vars_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
@@ -101,7 +119,7 @@ class var_selector_windowDialog(QDialog):
|
|||||||
self.btn_accept.clicked.connect(self.on_apply_clicked)
|
self.btn_accept.clicked.connect(self.on_apply_clicked)
|
||||||
|
|
||||||
# Соединяем чекбокс с методом виджета
|
# Соединяем чекбокс с методом виджета
|
||||||
self.autocomplete_checkbox.stateChanged.connect(self.vars_widget.set_autocomplete)
|
self.autocomplete_checkbox.stateChanged.connect(self.set_autocomplete_tables)
|
||||||
# Устанавливаем начальное состояние автодополнения в виджете
|
# Устанавливаем начальное состояние автодополнения в виджете
|
||||||
self.vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked())
|
self.vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked())
|
||||||
self.selected_vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked())
|
self.selected_vars_widget.set_autocomplete(self.autocomplete_checkbox.isChecked())
|
||||||
@@ -224,13 +242,6 @@ class var_selector_windowDialog(QDialog):
|
|||||||
self.accept()
|
self.accept()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def save_checkbox_state(self):
|
|
||||||
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Обнови on_left_tree_double_click:
|
# Обнови on_left_tree_double_click:
|
||||||
def on_left_tree_double_click(self, item, column):
|
def on_left_tree_double_click(self, item, column):
|
||||||
selected_names = [item.text(0)]
|
selected_names = [item.text(0)]
|
||||||
@@ -373,3 +384,9 @@ class var_selector_windowDialog(QDialog):
|
|||||||
|
|
||||||
def save_checkbox_state(self):
|
def save_checkbox_state(self):
|
||||||
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())
|
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,10 +1,10 @@
|
|||||||
from PySide2.QtWidgets import (
|
from PySide2.QtWidgets import (
|
||||||
QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter,
|
QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter,
|
||||||
QAbstractItemView, QHeaderView, QLabel,
|
QAbstractItemView, QHeaderView, QLabel, QSpacerItem, QSizePolicy, QSpinBox,
|
||||||
QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QScrollArea, QWidget
|
QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QScrollArea, QWidget
|
||||||
)
|
)
|
||||||
from PySide2.QtGui import QColor, QBrush, QPalette
|
from PySide2.QtGui import QColor, QBrush, QPalette
|
||||||
from PySide2.QtCore import Qt
|
from PySide2.QtCore import Qt, QSettings
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from generate_debug_vars import type_map
|
from generate_debug_vars import type_map
|
||||||
import time
|
import time
|
||||||
@@ -60,8 +60,65 @@ class FilterDialog(QDialog):
|
|||||||
return [cb.text() for cb in self.checkboxes if cb.isChecked()]
|
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="Укажите размер короткого имени"):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setWindowTitle(title)
|
||||||
|
self.setFixedSize(320, 120) # Задаем фиксированный размер для аккуратного вида
|
||||||
|
|
||||||
class var_tableWidget(QTableWidget):
|
# Основной вертикальный макет
|
||||||
|
main_layout = QVBoxLayout(self)
|
||||||
|
|
||||||
|
# Макет для ввода значения
|
||||||
|
input_layout = QHBoxLayout()
|
||||||
|
label = QLabel("Количество символов:", 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):
|
def __init__(self, parent=None):
|
||||||
super().__init__(0, 8, parent)
|
super().__init__(0, 8, parent)
|
||||||
# Таблица переменных
|
# Таблица переменных
|
||||||
@@ -77,16 +134,22 @@ class var_tableWidget(QTableWidget):
|
|||||||
])
|
])
|
||||||
self.setEditTriggers(QAbstractItemView.AllEditTriggers)
|
self.setEditTriggers(QAbstractItemView.AllEditTriggers)
|
||||||
self.var_list = []
|
self.var_list = []
|
||||||
|
# Инициализируем QSettings с именем организации и приложения
|
||||||
|
self.settings = QSettings("SET", "DebugVarEdit_VarTable")
|
||||||
|
# Восстанавливаем сохранённое состояние, если есть
|
||||||
|
shortsize = self.settings.value("shortname_size", True, type=int)
|
||||||
|
self._shortname_size = shortsize
|
||||||
|
|
||||||
self.type_options = list(dict.fromkeys(type_map.values()))
|
self.type_options = list(dict.fromkeys(type_map.values()))
|
||||||
self.pt_types_all = [t.replace('pt_', '') for t in self.type_options]
|
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_all = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
|
||||||
# Задаём базовые iq-типы (без префикса 'iq_')
|
# Задаём базовые iq-типы (без префикса 'iq_')
|
||||||
self.iq_types = ['iq_none', 'iq24', 'iq19', 'iq15', 'iq10']
|
self.iq_types = ['iq_none', 'iq', 'iq10', 'iq15', 'iq19', 'iq24']
|
||||||
# Фильтруем типы из type_map.values() исключая те, что содержат 'arr' или 'ptr'
|
# Фильтруем типы из type_map.values() исключая те, что содержат 'arr' или 'ptr'
|
||||||
self.type_options = [t for t in set(type_map.values()) if 'arr' not in t and 'ptr' not in t]
|
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]
|
||||||
# Формируем display_type_options без префикса 'pt_'
|
# Формируем display_type_options без префикса 'pt_'
|
||||||
self.pt_types = [t.replace('pt_', '') for t in self.type_options]
|
self.pt_types = [t.replace('pt_', '') for t in type_options]
|
||||||
|
|
||||||
self._iq_type_filter = list(self.iq_types) # Текущий фильтр iq типов (по умолчанию все)
|
self._iq_type_filter = list(self.iq_types) # Текущий фильтр iq типов (по умолчанию все)
|
||||||
self._pt_type_filter = list(self.pt_types)
|
self._pt_type_filter = list(self.pt_types)
|
||||||
@@ -117,9 +180,6 @@ class var_tableWidget(QTableWidget):
|
|||||||
|
|
||||||
def populate(self, vars_list, structs, on_change_callback):
|
def populate(self, vars_list, structs, on_change_callback):
|
||||||
self.var_list = vars_list
|
self.var_list = vars_list
|
||||||
self.type_options = list(dict.fromkeys(type_map.values()))
|
|
||||||
self.pt_types = [t.replace('pt_', '') for t in self.type_options]
|
|
||||||
iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
|
|
||||||
|
|
||||||
# --- ДО: удаляем отображение структур и union-переменных
|
# --- ДО: удаляем отображение структур и union-переменных
|
||||||
for var in vars_list:
|
for var in vars_list:
|
||||||
@@ -168,7 +228,7 @@ class var_tableWidget(QTableWidget):
|
|||||||
self.setItem(row, rows.type, origin_item)
|
self.setItem(row, rows.type, origin_item)
|
||||||
|
|
||||||
# pt_type
|
# pt_type
|
||||||
pt_combo = QComboBox()
|
pt_combo = CtrlScrollComboBox()
|
||||||
pt_combo.addItems(self.pt_types)
|
pt_combo.addItems(self.pt_types)
|
||||||
value = var['pt_type'].replace('pt_', '')
|
value = var['pt_type'].replace('pt_', '')
|
||||||
if value not in self.pt_types:
|
if value not in self.pt_types:
|
||||||
@@ -176,11 +236,10 @@ class var_tableWidget(QTableWidget):
|
|||||||
pt_combo.setCurrentText(value)
|
pt_combo.setCurrentText(value)
|
||||||
pt_combo.currentTextChanged.connect(on_change_callback)
|
pt_combo.currentTextChanged.connect(on_change_callback)
|
||||||
pt_combo.setStyleSheet(style_with_padding)
|
pt_combo.setStyleSheet(style_with_padding)
|
||||||
pt_combo.wheelEvent = lambda e: e.ignore()
|
|
||||||
self.setCellWidget(row, rows.pt_type, pt_combo)
|
self.setCellWidget(row, rows.pt_type, pt_combo)
|
||||||
|
|
||||||
# iq_type
|
# iq_type
|
||||||
iq_combo = QComboBox()
|
iq_combo = CtrlScrollComboBox()
|
||||||
iq_combo.addItems(self.iq_types)
|
iq_combo.addItems(self.iq_types)
|
||||||
value = var['iq_type'].replace('t_', '')
|
value = var['iq_type'].replace('t_', '')
|
||||||
if value not in self.iq_types:
|
if value not in self.iq_types:
|
||||||
@@ -188,17 +247,15 @@ class var_tableWidget(QTableWidget):
|
|||||||
iq_combo.setCurrentText(value)
|
iq_combo.setCurrentText(value)
|
||||||
iq_combo.currentTextChanged.connect(on_change_callback)
|
iq_combo.currentTextChanged.connect(on_change_callback)
|
||||||
iq_combo.setStyleSheet(style_with_padding)
|
iq_combo.setStyleSheet(style_with_padding)
|
||||||
iq_combo.wheelEvent = lambda e: e.ignore()
|
|
||||||
self.setCellWidget(row, rows.iq_type, iq_combo)
|
self.setCellWidget(row, rows.iq_type, iq_combo)
|
||||||
|
|
||||||
# return_type
|
# return_type
|
||||||
ret_combo = QComboBox()
|
ret_combo = CtrlScrollComboBox()
|
||||||
ret_combo.addItems(self.iq_types)
|
ret_combo.addItems(self.iq_types)
|
||||||
value = var['return_type'].replace('t_', '')
|
value = var['return_type'].replace('t_', '')
|
||||||
ret_combo.setCurrentText(value)
|
ret_combo.setCurrentText(value)
|
||||||
ret_combo.currentTextChanged.connect(on_change_callback)
|
ret_combo.currentTextChanged.connect(on_change_callback)
|
||||||
ret_combo.setStyleSheet(style_with_padding)
|
ret_combo.setStyleSheet(style_with_padding)
|
||||||
ret_combo.wheelEvent = lambda e: e.ignore()
|
|
||||||
self.setCellWidget(row, rows.ret_type, ret_combo)
|
self.setCellWidget(row, rows.ret_type, ret_combo)
|
||||||
|
|
||||||
# short_name
|
# short_name
|
||||||
@@ -230,7 +287,7 @@ class var_tableWidget(QTableWidget):
|
|||||||
t3 = time.time()
|
t3 = time.time()
|
||||||
shortname = short_name_edit.text() if short_name_edit else ""
|
shortname = short_name_edit.text() if short_name_edit else ""
|
||||||
|
|
||||||
long_shortname = len(shortname) > 10
|
long_shortname = len(shortname) > self._shortname_size
|
||||||
found = name in var_names_set
|
found = name in var_names_set
|
||||||
|
|
||||||
color = None
|
color = None
|
||||||
@@ -276,7 +333,7 @@ class var_tableWidget(QTableWidget):
|
|||||||
|
|
||||||
def on_header_clicked(self, logicalIndex):
|
def on_header_clicked(self, logicalIndex):
|
||||||
if logicalIndex == rows.pt_type:
|
if logicalIndex == rows.pt_type:
|
||||||
dlg = FilterDialog(self, self.pt_types_all, self._pt_type_filter, "Выберите Pointer Types")
|
dlg = FilterDialog(self, self.pt_types_all, self._pt_type_filter, "Выберите базовые типы")
|
||||||
if dlg.exec_():
|
if dlg.exec_():
|
||||||
self._pt_type_filter = dlg.get_selected()
|
self._pt_type_filter = dlg.get_selected()
|
||||||
self.update_comboboxes({rows.pt_type: self._pt_type_filter})
|
self.update_comboboxes({rows.pt_type: self._pt_type_filter})
|
||||||
@@ -292,6 +349,13 @@ class var_tableWidget(QTableWidget):
|
|||||||
if dlg.exec_():
|
if dlg.exec_():
|
||||||
self._ret_type_filter = dlg.get_selected()
|
self._ret_type_filter = dlg.get_selected()
|
||||||
self.update_comboboxes({rows.ret_type: self._ret_type_filter})
|
self.update_comboboxes({rows.ret_type: self._ret_type_filter})
|
||||||
|
|
||||||
|
elif logicalIndex == rows.short_name:
|
||||||
|
dlg = SetSizeDialog(self)
|
||||||
|
if dlg.exec_():
|
||||||
|
self._shortname_size = dlg.get_selected_size()
|
||||||
|
self.settings.setValue("shortname_size", self._shortname_size)
|
||||||
|
self.check()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -309,6 +373,7 @@ class var_tableWidget(QTableWidget):
|
|||||||
current = combo.currentText()
|
current = combo.currentText()
|
||||||
combo.blockSignals(True)
|
combo.blockSignals(True)
|
||||||
combo.clear()
|
combo.clear()
|
||||||
|
|
||||||
combo.addItems(allowed_items)
|
combo.addItems(allowed_items)
|
||||||
if current in allowed_items:
|
if current in allowed_items:
|
||||||
combo.setCurrentText(current)
|
combo.setCurrentText(current)
|
||||||
|
|||||||
411
debug_tools.c
411
debug_tools.c
@@ -1,46 +1,68 @@
|
|||||||
#include "debug_tools.h"
|
#include "debug_tools.h"
|
||||||
#include "IQmathLib.h"
|
|
||||||
|
|
||||||
DebugLowLevel_t debug_ll = DEBUG_LOWLEVEL_INIT;
|
#if !defined(GLOBAL_Q)
|
||||||
|
#define GLOBAL_Q 16
|
||||||
|
#endif
|
||||||
|
|
||||||
static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var);
|
|
||||||
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var);
|
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);
|
||||||
|
|
||||||
///////////////////////////----EXAPLE-----//////////////////////////////
|
///////////////////////////----EXAPLE-----//////////////////////////////
|
||||||
long var_numb = 1;
|
int var_numb = 1; ///< Ïðèìåð ïåðåìåííîé äëÿ îòëàäêè
|
||||||
DebugVarName_t var_name;
|
DebugVarName_t var_name; ///< Èìÿ ïåðåìåííîé
|
||||||
long return_var;
|
int32_t return_var; ///< Ïåðåìåííàÿ äëÿ âîçâðàòà ðåçóëüòàòà
|
||||||
long return_ll_var;
|
int32_t return_ll_var; ///< Âîçâðàùàåìîå çíà÷åíèå ñ íèæíåãî óðîâíÿ
|
||||||
int result;
|
int result; ///< Ïåðåìåííàÿ ðåçóëüòàòà
|
||||||
char ext_date[] = {7, 233, 11, 07, 16, 50};
|
DateTime_t ext_date = {2025, 11, 07, 16, 50}; ///< Ïðèìåð âíåøíåé äàòû ñáîðêè
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ïðèìåð èñïîëüçîâàíèÿ ôóíêöèé îòëàäêè.
|
||||||
|
* @details Äåìîíñòðàöèîííàÿ ôóíêöèÿ äëÿ ðàáîòû ñ ïåðåìåííûìè îòëàäêè.
|
||||||
|
*/
|
||||||
void Debug_Test_Example(void)
|
void Debug_Test_Example(void)
|
||||||
{
|
{
|
||||||
result = Debug_ReadVar(var_numb, &return_var);
|
result = Debug_ReadVar(var_numb, &return_var);
|
||||||
result = Debug_ReadVarName(var_numb, var_name);
|
result = Debug_ReadVarName(var_numb, var_name);
|
||||||
|
|
||||||
|
|
||||||
if(Debug_LowLevel_Initialize(ext_date) == 0)
|
if(Debug_LowLevel_Initialize(&ext_date) == 0)
|
||||||
result = Debug_LowLevel_ReadVar(&return_ll_var);
|
result = Debug_LowLevel_ReadVar(&return_ll_var);
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////----PUBLIC-----//////////////////////////////
|
///////////////////////////----PUBLIC-----//////////////////////////////
|
||||||
int Debug_ReadVar(int var_ind, long *return_long)
|
|
||||||
|
/**
|
||||||
|
* @brief ×èòàåò ïåðåìåííóþ ïî èíäåêñó.
|
||||||
|
* @param var_ind – èíäåêñ ïåðåìåííîé.
|
||||||
|
* @param return_32b – óêàçàòåëü äëÿ âîçâðàòà ðåçóëüòàòà.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà.
|
||||||
|
* @details Èñïîëüçóåòñÿ äëÿ ÷òåíèÿ çíà÷åíèé ïåðåìåííûõ ïî èõ èíäåêñó.
|
||||||
|
*/
|
||||||
|
int Debug_ReadVar(int var_ind, int32_t *return_32b)
|
||||||
{
|
{
|
||||||
if(return_long == NULL)
|
if(return_32b == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
long tmp_var;
|
int32_t tmp_var;
|
||||||
|
|
||||||
if (var_ind >= DebugVar_Qnt)
|
if (var_ind >= DebugVar_Qnt)
|
||||||
return 1;
|
return 1;
|
||||||
if((dbg_vars[var_numb].ptr_type == pt_struct) || (dbg_vars[var_numb].ptr_type == pt_union) ||
|
if((dbg_vars[var_ind].ptr_type == pt_struct) || (dbg_vars[var_ind].ptr_type == pt_union) ||
|
||||||
(dbg_vars[var_numb].ptr_type == pt_unknown))
|
(dbg_vars[var_ind].ptr_type == pt_unknown))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
return convertDebugVarToIQx(&dbg_vars[var_ind], return_32b);
|
||||||
|
|
||||||
return convertDebugVarToIQx(&dbg_vars[var_numb], return_long);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr)
|
||||||
{
|
{
|
||||||
if(name_ptr == NULL)
|
if(name_ptr == NULL)
|
||||||
@@ -51,29 +73,34 @@ int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr)
|
|||||||
|
|
||||||
int i;
|
int i;
|
||||||
// Êîïèðîâàíèå ñ çàùèòîé îò ïåðåïîëíåíèÿ è ÿâíîé îñòàíîâêîé ïî '\0'
|
// Êîïèðîâàíèå ñ çàùèòîé îò ïåðåïîëíåíèÿ è ÿâíîé îñòàíîâêîé ïî '\0'
|
||||||
for (i = 0; i < sizeof(dbg_vars[var_numb].name); i++)
|
for (i = 0; i < sizeof(dbg_vars[var_ind].name); i++)
|
||||||
{
|
{
|
||||||
name_ptr[i] = dbg_vars[var_numb].name[i];
|
name_ptr[i] = dbg_vars[var_ind].name[i];
|
||||||
if (dbg_vars[var_numb].name[i] == '\0')
|
if (dbg_vars[var_ind].name[i] == '\0')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Ãàðàíòèðîâàííîå çàâåðøåíèå ñòðîêè (íà ñëó÷àé, åñëè â var->name íå áûëî '\0')
|
// Ãàðàíòèðîâàííîå çàâåðøåíèå ñòðîêè (íà ñëó÷àé, åñëè â var->name íå áûëî '\0')
|
||||||
name_ptr[sizeof(dbg_vars[var_numb].name) - 1] = '\0';
|
name_ptr[sizeof(dbg_vars[var_ind].name) - 1] = '\0';
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
int Debug_LowLevel_ReadVar(long *return_long)
|
* @brief ×èòàåò çíà÷åíèå ïåðåìåííîé îòëàäêè ñ íèæíåãî óðîâíÿ.
|
||||||
|
* @param return_32b – óêàçàòåëü íà ïåðåìåííóþ, êóäà çàïèñûâàåòñÿ ðåçóëüòàò.
|
||||||
|
* @return int – 0: óñïåõ, 1: îøèáêà, 2: íåäîïóñòèìûé àäðåñ.
|
||||||
|
* @details Èñïîëüçóåò àäðåññ, ïåðåäàâàåìûé ñ òåðìèíàëêè äëÿ ïîëó÷åíèÿ çíà÷åíèÿ.
|
||||||
|
*/
|
||||||
|
int Debug_LowLevel_ReadVar(int32_t *return_32b)
|
||||||
{
|
{
|
||||||
if (return_long == NULL)
|
if (return_32b == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
if (debug_ll.isVerified == 0)
|
if (debug_ll.isVerified == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
char *addr = debug_ll.dbg_var.Ptr;
|
uint8_t *addr = debug_ll.dbg_var.Ptr;
|
||||||
unsigned long addr_val = (unsigned long)addr;
|
uint32_t addr_val = (uint32_t)addr;
|
||||||
|
|
||||||
// Ðàçðåø¸ííûå äèàïàçîíû ïàìÿòè (èç .cmd ôàéëà)
|
// Ðàçðåø¸ííûå äèàïàçîíû ïàìÿòè (èç .cmd ôàéëà)
|
||||||
if (!(
|
if (!(
|
||||||
@@ -89,32 +116,28 @@ int Debug_LowLevel_ReadVar(long *return_long)
|
|||||||
return 2; // Çàïðåù¸ííûé àäðåñ — íåëüçÿ ÷èòàòü
|
return 2; // Çàïðåù¸ííûé àäðåñ — íåëüçÿ ÷èòàòü
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertDebugVarToIQx(&debug_ll.dbg_var, return_long);
|
return convertDebugVarToIQx(&debug_ll.dbg_var, return_32b);
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
int Debug_LowLevel_Initialize(const char* external_date)
|
* @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 -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ïðåîáðàçóåì external_date â ñòðóêòóðó
|
|
||||||
DateTime_t ext;
|
|
||||||
ext.year = (external_date[0] << 8) | external_date[1];
|
|
||||||
ext.day = external_date[2];
|
|
||||||
ext.month = external_date[3];
|
|
||||||
ext.hour = external_date[4];
|
|
||||||
ext.minute = external_date[5];
|
|
||||||
|
|
||||||
|
|
||||||
// Ñðàâíåíèå âñåõ ïîëåé
|
// Ñðàâíåíèå âñåõ ïîëåé
|
||||||
if (ext.year == debug_ll.build_date.year &&
|
if (external_date->year == debug_ll.build_date.year &&
|
||||||
ext.month == debug_ll.build_date.month &&
|
external_date->month == debug_ll.build_date.month &&
|
||||||
ext.day == debug_ll.build_date.day &&
|
external_date->day == debug_ll.build_date.day &&
|
||||||
ext.hour == debug_ll.build_date.hour &&
|
external_date->hour == debug_ll.build_date.hour &&
|
||||||
ext.minute == debug_ll.build_date.minute)
|
external_date->minute == debug_ll.build_date.minute)
|
||||||
{
|
{
|
||||||
debug_ll.isVerified = 1;
|
debug_ll.isVerified = 1;
|
||||||
return 0; // Ñîâïàëî
|
return 0; // Ñîâïàëî
|
||||||
@@ -129,6 +152,12 @@ int Debug_LowLevel_Initialize(const char* external_date)
|
|||||||
|
|
||||||
|
|
||||||
/////////////////////----INTERNAL FUNCTIONS-----////////////////////////
|
/////////////////////----INTERNAL FUNCTIONS-----////////////////////////
|
||||||
|
/**
|
||||||
|
* @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)
|
static int iqTypeToQ(DebugVarIQType_t t)
|
||||||
{
|
{
|
||||||
if (t == t_iq_none)
|
if (t == t_iq_none)
|
||||||
@@ -141,9 +170,16 @@ static int iqTypeToQ(DebugVarIQType_t t)
|
|||||||
return -1; // îøèáêà
|
return -1; // îøèáêà
|
||||||
}
|
}
|
||||||
|
|
||||||
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var)
|
/**
|
||||||
|
* @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)
|
||||||
{
|
{
|
||||||
long iq_numb, iq_united, iq_final;
|
int32_t iq_numb, iq_united, iq_final;
|
||||||
float float_numb;
|
float float_numb;
|
||||||
|
|
||||||
if(getDebugVar(var, &iq_numb, &float_numb) != 0)
|
if(getDebugVar(var, &iq_numb, &float_numb) != 0)
|
||||||
@@ -155,30 +191,30 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var)
|
|||||||
if (src_q < 0 || dst_q < 0)
|
if (src_q < 0 || dst_q < 0)
|
||||||
return 2; // íåïðàâèëüíûé ôîðìàò
|
return 2; // íåïðàâèëüíûé ôîðìàò
|
||||||
|
|
||||||
long long iq_united64 = 0;
|
int64_t iq_united64 = 0;
|
||||||
long long iq_final64 = 0;
|
int64_t iq_final64 = 0;
|
||||||
|
|
||||||
// Êîíâåðòàöèÿ ê GLOBAL_Q (64-áèò)
|
// Êîíâåðòàöèÿ ê GLOBAL_Q (64-áèò)
|
||||||
if (var->iq_type == t_iq_none) {
|
if (var->iq_type == t_iq_none) {
|
||||||
if (var->ptr_type == pt_float) {
|
if (var->ptr_type == pt_float) {
|
||||||
// float_numb óìíîæàåì íà 2^GLOBAL_Q (2^24=16777216)
|
// float_numb óìíîæàåì íà 2^GLOBAL_Q
|
||||||
// Ðåçóëüòàò ïðèâîäèì ê long long
|
// Ðåçóëüòàò ïðèâîäèì ê 64 áèòà
|
||||||
iq_united64 = (long long)(float_numb * 16777216.0f);
|
iq_united64 = (int64_t)(float_numb * (1 << GLOBAL_Q));
|
||||||
} else {
|
} else {
|
||||||
iq_united64 = ((long long)iq_numb) << GLOBAL_Q;
|
iq_united64 = ((int64_t)iq_numb) << GLOBAL_Q;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int shift = GLOBAL_Q - src_q;
|
int shift = GLOBAL_Q - src_q;
|
||||||
if (shift >= 0)
|
if (shift >= 0)
|
||||||
iq_united64 = ((long long)iq_numb) << shift;
|
iq_united64 = ((int64_t)iq_numb) << shift;
|
||||||
else
|
else
|
||||||
iq_united64 = ((long long)iq_numb) >> (-shift);
|
iq_united64 = ((int64_t)iq_numb) >> (-shift);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Êîíâåðòàöèÿ èç GLOBAL_Q â öåëåâîé IQ (64-áèò)
|
// Êîíâåðòàöèÿ èç GLOBAL_Q â öåëåâîé IQ (64-áèò)
|
||||||
if (var->return_type == t_iq_none) {
|
if (var->return_type == t_iq_none) {
|
||||||
// Âîçâðàùàåì öåëîå, îòáðîñèâ äðîáíóþ ÷àñòü
|
// Âîçâðàùàåì öåëîå, îòáðîñèâ äðîáíóþ ÷àñòü
|
||||||
*ret_var = (long)(iq_united64 >> GLOBAL_Q);
|
*ret_var = (uint32_t)(iq_united64 >> GLOBAL_Q);
|
||||||
} else {
|
} else {
|
||||||
int shift = dst_q - GLOBAL_Q;
|
int shift = dst_q - GLOBAL_Q;
|
||||||
if (shift >= 0)
|
if (shift >= 0)
|
||||||
@@ -187,54 +223,65 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var)
|
|||||||
iq_final64 = iq_united64 >> (-shift);
|
iq_final64 = iq_united64 >> (-shift);
|
||||||
|
|
||||||
// Ïðîâåðÿåì ïåðåïîëíåíèå int32_t
|
// Ïðîâåðÿåì ïåðåïîëíåíèå int32_t
|
||||||
if (iq_final64 > LONG_MAX || iq_final64 < LONG_MIN)
|
if (iq_final64 > 2147483647 || iq_final64 < -2147483648)
|
||||||
return 3; // ïåðåïîëíåíèå
|
return 3; // ïåðåïîëíåíèå
|
||||||
|
|
||||||
*ret_var = (long)iq_final64;
|
*ret_var = (uint32_t)iq_final64;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if (!var || !int_var || !float_var || !var->Ptr)
|
||||||
return 1; // îøèáêà: null óêàçàòåëü
|
return 1; // îøèáêà: null óêàçàòåëü
|
||||||
|
|
||||||
char *addr = var->Ptr;
|
uint8_t *addr = var->Ptr;
|
||||||
unsigned long addr_val = (unsigned long)addr;
|
uint32_t addr_val = (uint32_t)addr;
|
||||||
|
|
||||||
switch (var->ptr_type)
|
switch (var->ptr_type)
|
||||||
{
|
{
|
||||||
case pt_int8: // 8 áèò
|
case pt_int8: // 8 áèò
|
||||||
|
if ((addr_val & ALIGN_8BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
|
return 1; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile int8_t *)addr);
|
||||||
case pt_uint8:
|
case pt_uint8:
|
||||||
// âûðàâíèâàíèå íå íóæíî äëÿ 8 áèò
|
if ((addr_val & ALIGN_8BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
*int_var = *((volatile char *)addr);
|
return 1; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*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 2; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile int16_t *)addr);
|
||||||
case pt_uint16:
|
case pt_uint16:
|
||||||
*int_var = *((volatile int *)addr);
|
if ((addr_val & ALIGN_16BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
|
return 2; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile uint16_t *)addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case pt_int32: // 32 áèò (long)
|
case pt_int32: // 32 áèò
|
||||||
case pt_uint32:
|
if ((addr_val & ALIGN_32BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
if (addr_val & 0x1) // ïðîâåðÿåì âûðàâíèâàíèå ïî 2 ñëîâàì (4 áàéòà)
|
|
||||||
return 3; // îøèáêà âûðàâíèâàíèÿ
|
return 3; // îøèáêà âûðàâíèâàíèÿ
|
||||||
*int_var = *((volatile long *)addr);
|
*int_var = *((volatile int32_t *)addr);
|
||||||
|
case pt_uint32:
|
||||||
|
if ((addr_val & ALIGN_32BIT) != 0) // ïðîâåðÿåì âûðàâíèâàíèå
|
||||||
|
return 3; // îøèáêà âûðàâíèâàíèÿ
|
||||||
|
*int_var = *((volatile uint32_t *)addr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case pt_int64: // 64 áèò (long long)
|
|
||||||
// case pt_uint64:
|
|
||||||
// if (addr_val & 0x3) // ïðîâåðêà âûðàâíèâàíèÿ ïî 4 ñëîâàì (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 & 0x1) // ïðîâåðêà âûðàâíèâàíèÿ ïî 2 ñëîâàì
|
if ((addr_val & ALIGN_FLOAT) != 0) // ïðîâåðêà âûðàâíèâàíèÿ
|
||||||
return 4; // îøèáêà âûðàâíèâàíèÿ
|
return 4; // îøèáêà âûðàâíèâàíèÿ
|
||||||
*float_var = *((volatile float *)addr);
|
*float_var = *((volatile float *)addr);
|
||||||
break;
|
break;
|
||||||
@@ -259,211 +306,3 @@ static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var)
|
|||||||
return 0; // óñïåõ
|
return 0; // óñïåõ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////// OUTDATE ////////////////
|
|
||||||
|
|
||||||
//
|
|
||||||
// // ïðèâåäåíèå ê îäíîìó IQ
|
|
||||||
// switch(var->iq_type)
|
|
||||||
// {
|
|
||||||
// case t_iq_none:
|
|
||||||
// if(var->ptr_type == pt_float)
|
|
||||||
// {
|
|
||||||
// iq_united = _IQ(float_numb);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// iq_united = _IQ(iq_numb);
|
|
||||||
// }
|
|
||||||
// break;
|
|
||||||
// case t_iq1:
|
|
||||||
// iq_united = _IQ1toIQ(iq_numb);
|
|
||||||
// break;
|
|
||||||
// case t_iq2:
|
|
||||||
// iq_united = _IQ2toIQ(iq_numb);
|
|
||||||
// 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 ê çàïðàøèâàåìîìó
|
|
||||||
// switch(var->return_type)
|
|
||||||
// {
|
|
||||||
// case t_iq_none:
|
|
||||||
// iq_final = (long)_IQtoF(iq_united);
|
|
||||||
// break;
|
|
||||||
// case t_iq1:
|
|
||||||
// iq_final = _IQtoIQ1(iq_united);
|
|
||||||
// break;
|
|
||||||
// case t_iq2:
|
|
||||||
// iq_final = _IQtoIQ2(iq_united);
|
|
||||||
// break;
|
|
||||||
// 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;
|
|
||||||
|
|||||||
105
debug_tools.h
105
debug_tools.h
@@ -1,8 +1,40 @@
|
|||||||
#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>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Òèï äàííûõ, íà êîòîðûé óêàçûâàåò óêàçàòåëü ïåðåìåííîé îòëàäêè.
|
||||||
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
pt_unknown, // unknown
|
pt_unknown, // unknown
|
||||||
@@ -14,7 +46,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 +63,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,45 +102,67 @@ typedef enum
|
|||||||
t_iq30
|
t_iq30
|
||||||
}DebugVarIQType_t;
|
}DebugVarIQType_t;
|
||||||
|
|
||||||
typedef char DebugVarName_t[11];
|
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 âîçâðàùàåìîãî çíà÷åíèÿ
|
||||||
DebugVarName_t name;
|
DebugVarName_t name; ///< Èìÿ ïåðåìåííîé
|
||||||
}DebugVar_t;
|
} DebugVar_t;
|
||||||
|
|
||||||
|
typedef long DebugValue_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ñòðóêòóðà äàòû è âðåìåíè.
|
||||||
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int year;
|
uint16_t year; ///< Ãîä (íàïðèìåð, 2025)
|
||||||
char month;
|
uint8_t month; ///< Ìåñÿö (1-12)
|
||||||
char day;
|
uint8_t day; ///< Äåíü (1-31)
|
||||||
char hour;
|
uint8_t hour; ///< ×àñû (0-23)
|
||||||
char minute;
|
uint8_t minute; ///< Ìèíóòû (0-59)
|
||||||
} DateTime_t;
|
} DateTime_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Ñòðóêòóðà íèæíåãî óðîâíÿ îòëàäêè.
|
||||||
|
*/
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
DateTime_t build_date;
|
DateTime_t build_date; ///< Äàòà ñáîðêè
|
||||||
unsigned int isVerified;
|
unsigned int isVerified; ///< Ôëàã èíèöèàëèçàöèè íèçêîóðîâíåíîé îòëàäêè (0 — íåò, 1 — óñïåøíî)
|
||||||
DebugVar_t dbg_var;
|
DebugVar_t dbg_var; ///< Ïåðåìåííàÿ äëÿ îòëàäêè
|
||||||
}DebugLowLevel_t;
|
}DebugLowLevel_t;
|
||||||
extern DebugLowLevel_t debug_ll;
|
extern DebugLowLevel_t debug_ll; ///< Ãëîáàëüíûé ýêçåìïëÿð îòëàäêè íèæíåãî óðîâíÿ
|
||||||
|
|
||||||
|
|
||||||
|
/** @brief Ìàêðîñ èíèöèàëèçàöèè äàòû */
|
||||||
#define DATE_INIT {BUILD_YEAR, BUILD_MONTH, BUILD_DATA, BUILD_HOURS, BUILD_MINUTES}
|
#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"}
|
#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}
|
#define DEBUG_LOWLEVEL_INIT {DATE_INIT, 0, DEBUG_VAR_INIT}
|
||||||
|
|
||||||
|
|
||||||
extern int DebugVar_Qnt;
|
extern int DebugVar_Qnt; ///< Êîëè÷åñòâî ïåðåìåííûõ îòëàäêè
|
||||||
extern DebugVar_t dbg_vars[];
|
extern DebugVar_t dbg_vars[]; ///< Ìàññèâ ïåðåìåííûõ îòëàäêè
|
||||||
|
|
||||||
|
|
||||||
|
/* Ïðèìåð èñïîëüçîâàíèÿ îòëàäêè */
|
||||||
void Debug_Test_Example(void);
|
void Debug_Test_Example(void);
|
||||||
|
|
||||||
int Debug_ReadVar(int var_ind, long *return_long);
|
/* ×èòàåò çíà÷åíèå ïåðåìåííîé ïî èíäåêñó */
|
||||||
|
int Debug_ReadVar(int var_ind, int32_t *return_long);
|
||||||
|
/* ×èòàåò èìÿ ïåðåìåííîé ïî èíäåêñó */
|
||||||
int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr);
|
int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr);
|
||||||
int Debug_LowLevel_ReadVar(long *return_long);
|
/* ×èòàåò çíà÷åíèå ïåðåìåííîé ñ íèæíåãî óðîâíÿ */
|
||||||
int Debug_LowLevel_Initialize(const char* external_date);
|
int Debug_LowLevel_ReadVar(int32_t *return_long);
|
||||||
|
/* Èíèöèàëèçèðóåò îòëàäêó íèæíåãî óðîâíÿ */
|
||||||
|
int Debug_LowLevel_Initialize(DateTime_t *external_date);
|
||||||
|
|
||||||
#endif //DEBUG_TOOLS
|
#endif //DEBUG_TOOLS
|
||||||
|
|||||||
341
debug_vars.c
341
debug_vars.c
@@ -1,341 +0,0 @@
|
|||||||
// Ýòîò ôàéë ñãåíåðèðîâàí àâòîìàòè÷åñêè
|
|
||||||
#include "debug_tools.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Èíêëþäû äëÿ äîñòóïà ê ïåðåìåííûì
|
|
||||||
#include "vector.h"
|
|
||||||
#include "errors.h"
|
|
||||||
#include "RS_Functions_modbus.h"
|
|
||||||
#include "xp_project.h"
|
|
||||||
#include "adc_tools.h"
|
|
||||||
#include "pwm_vector_regul.h"
|
|
||||||
#include "log_can.h"
|
|
||||||
#include "f281xpwm.h"
|
|
||||||
#include "v_pwm24.h"
|
|
||||||
#include "xp_write_xpwm_time.h"
|
|
||||||
#include "dq_to_alphabeta_cos.h"
|
|
||||||
#include "teta_calc.h"
|
|
||||||
#include "rotation_speed.h"
|
|
||||||
#include "detect_phase_break2.h"
|
|
||||||
#include "RS_Functions.h"
|
|
||||||
#include "Spartan2E_Functions.h"
|
|
||||||
#include "xp_controller.h"
|
|
||||||
#include "xp_rotation_sensor.h"
|
|
||||||
#include "x_serial_bus.h"
|
|
||||||
#include "x_parallel_bus.h"
|
|
||||||
#include "xPeriphSP6_loader.h"
|
|
||||||
#include "log_params.h"
|
|
||||||
#include "CAN_Setup.h"
|
|
||||||
#include "CRC_Functions.h"
|
|
||||||
#include "log_to_memory.h"
|
|
||||||
#include "global_time.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 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 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 = 23;
|
|
||||||
#pragma DATA_SECTION(dbg_vars,".dbgvar_info")
|
|
||||||
DebugVar_t dbg_vars[] = {\
|
|
||||||
{(char *)&ADC0finishAddr, pt_int16, t_iq_none, t_iq_none, "ADC0finish" }, \
|
|
||||||
{(char *)&IQ_OUT_NOM, pt_float, t_iq_none, t_iq10, "IQ_OUT_NOM" }, \
|
|
||||||
{(char *)&KmodTerm, pt_float, t_iq_none, t_iq10, "KmodTerm" }, \
|
|
||||||
{(char *)&freqTerm, pt_float, t_iq_none, t_iq10, "freqTerm" }, \
|
|
||||||
{(char *)&ADC_sf[0][0], pt_int16, t_iq_none, t_iq_none, "ADC_sf00" }, \
|
|
||||||
{(char *)&ADC_sf[0][1], pt_int16, t_iq_none, t_iq_none, "ADC_sf01" }, \
|
|
||||||
{(char *)&ADC_sf[0][2], pt_int16, t_iq_none, t_iq_none, "ADC_sf02" }, \
|
|
||||||
{(char *)&ADC_sf[0][3], pt_int16, t_iq_none, t_iq_none, "ADC_sf03" }, \
|
|
||||||
{(char *)&ADC_sf[0][4], pt_int16, t_iq_none, t_iq_none, "ADC_sf04" }, \
|
|
||||||
{(char *)&ADC_sf[0][5], pt_int16, t_iq_none, t_iq_none, "ADC_sf05" }, \
|
|
||||||
{(char *)&ADC_sf[0][6], pt_int16, t_iq_none, t_iq_none, "ADC_sf06" }, \
|
|
||||||
{(char *)&ADC_sf[0][7], pt_int16, t_iq_none, t_iq_none, "ADC_sf07" }, \
|
|
||||||
{(char *)&ADC_sf[0][8], pt_int16, t_iq_none, t_iq_none, "ADC_sf08" }, \
|
|
||||||
{(char *)&ADC_sf[0][9], pt_int16, t_iq_none, t_iq_none, "ADC_sf09" }, \
|
|
||||||
{(char *)&ADC_sf[0][10], pt_int16, t_iq_none, t_iq_none, "ADC_sf010" }, \
|
|
||||||
{(char *)&ADC_sf[0][11], pt_int16, t_iq_none, t_iq_none, "ADC_sf011" }, \
|
|
||||||
{(char *)&ADC_sf[0][12], pt_int16, t_iq_none, t_iq_none, "ADC_sf012" }, \
|
|
||||||
{(char *)&ADC_sf[0][13], pt_int16, t_iq_none, t_iq_none, "ADC_sf013" }, \
|
|
||||||
{(char *)&ADC_sf[0][14], pt_int16, t_iq_none, t_iq_none, "ADC_sf014" }, \
|
|
||||||
{(char *)&ADC_sf[0][15], pt_int16, t_iq_none, t_iq_none, "ADC_sf015" }, \
|
|
||||||
{(char *)&Bender[0].KOhms, pt_uint16, t_iq_none, t_iq_none, "Bend0.KOhm" }, \
|
|
||||||
{(char *)&Bender[0].Times, pt_uint16, t_iq_none, t_iq_none, "Bend0.Time" }, \
|
|
||||||
{(char *)&Bender[0].Error.all, pt_uint16, t_iq_none, t_iq_none, "Bend0.Err" }, \
|
|
||||||
};
|
|
||||||
23
debug_vars_example.c
Normal file
23
debug_vars_example.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#include "debug_tools.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Инклюды для доступа к переменным
|
||||||
|
#include "bender.h"
|
||||||
|
|
||||||
|
// Экстерны для доступа к переменным
|
||||||
|
extern int ADC0finishAddr;
|
||||||
|
|
||||||
|
|
||||||
|
// Определение массива с указателями на переменные для отладки
|
||||||
|
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" }, \
|
||||||
|
};
|
||||||
20181
structs.xml
20181
structs.xml
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user