From ae2c90160ea588edeea32afa8dd2ae058f7cd3bb Mon Sep 17 00:00:00 2001 From: Razvalyaev Date: Thu, 17 Jul 2025 09:18:03 +0300 Subject: [PATCH] =?UTF-8?q?+=D0=B1=D0=B8=D0=B1=D0=BB=D0=B8=D0=BE=D1=82?= =?UTF-8?q?=D0=B5=D0=BA=D0=B0=20.c/.h=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BF?= =?UTF-8?q?=D0=B8=D1=81=D0=B0=D0=BD=D0=B0=20=D0=BF=D0=BE=D0=B4=20=D1=83?= =?UTF-8?q?=D0=BD=D0=B8=D0=B2=D0=B5=D1=80=D1=81=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20=D0=B4=D0=B5=D1=84=D0=B0=D0=B9=D0=BD=D1=8B=20int?= =?UTF-8?q?X=5Ft=20uintX=5Ft?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit +сделано задание размера короткого имени + добавлена бета поддержка stm:+ - парс переменных из файла преокта Keil или makefile CubeIDE - запись в utf-8 для STM, вместо cp1251 для TMS - другой размер int (32 бита, вместо 16 бит) для STM --- README.md | 34 ++-- Src/DebugVarEdit_GUI.py | 29 ++- Src/generate_debug_vars.py | 55 ++++-- Src/scan_vars.py | 11 +- Src/var_table.py | 69 ++++++- debug_tools.c | 360 ++++++++----------------------------- debug_tools.h | 67 +++++-- 7 files changed, 284 insertions(+), 341 deletions(-) diff --git a/README.md b/README.md index 773565a..c9ec221 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# DebugTools - Просмотр переменных через терминалку +# DebugTools - Просмотр переменных по указателям Модуль состоит из трех файлов: - **debug_tools.c** - реализация считывания переменных - **debug_tools.h** - объявление всякого для считывания переменных @@ -7,8 +7,9 @@ Этот модуль предоставляет функциональность для чтения значений переменных во встроенной системе, включая работу с IQ-форматами, защиту доступа и проверку диапазонов памяти. Для чтения переменных можно использовать функции: + ```c -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); ``` @@ -19,19 +20,19 @@ int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr); // Определение массива с указателями на переменные для отладки int DebugVar_Qnt = 5; #pragma DATA_SECTION(dbg_vars,".dbgvar_info") -// pointer_type iq_type return_iq_type short_name +// pointer_type iq_type return_iq_type short_name DebugVar_t dbg_vars[] = {\ -{(char *)&freqTerm, pt_float, t_iq_none, t_iq10, "freqT" }, \ -{(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 *)&Bender[0].KOhms, pt_uint16, t_iq, t_iq10, "Bend0.KOhm" }, \ -{(char *)&Bender[0].Times, pt_uint16, t_iq_none, t_iq_none, "Bend0.Time" }, \ +{(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" }, \ +{(char *)&Bender[0].Times, pt_uint16, t_iq_none, t_iq_none, "Bend0.Time" }, \ }; ``` -# DebugVarEdit - Настройка переменных для терминалки +# DebugVarEdit - Настройка переменных **DebugVarEdit** — графическое приложение для Windows, предназначенное для настройки и генерации отладочных переменных (`debug_vars.c`) на основе исходного C-проекта. Работает с `makefile` проекта, сохраняет изменения в XML и позволяет удобно редактировать переменные и их типы через интерфейс. Программа — один исполняемый файл `DebugVarEdit.exe`, не требующий установки и дополнительных зависимостей. @@ -44,11 +45,12 @@ DebugVar_t dbg_vars[] = {\ 1. Запустите **DebugVarEdit.exe.** -2. Укажите пути: +2. Укажите пути и контроллер: - **Путь к XML** — новый или существующий файл настроек переменных; - **Путь к проекту** — путь к корню проека (папка, которая является корнем для проекта в Code Composer); - **Путь к makefile** — путь к `makefile` относительно корня проекта; - **Путь для debug_vars.c** — папка, куда будет сгенерирован файл `debug_vars.c` с переменными. + - **МК** — TMS или STM. Они отличаются размером int, и также принятыми кодировками файлов (utf-8/cp1251) 3. Нажмите **Сканировать переменные**: - Программа проанализирует исходники, указанные в makefile, и найдёт все переменные. @@ -92,7 +94,7 @@ DebugVar_t dbg_vars[] = {\ ## Пример XML-файла ```xml - + true @@ -139,14 +141,14 @@ Src Для запуска приложения: - **Python 3.7+** -- **clang** — используется для парсинга C-кода (требуется `libclang.dll`) +- **clang** — используется для парсинга C-кода (требуется `libclang.dll`, лежит в папке Src) - **PySide2** — GUI-фреймворк - **lxml** — работа с XML > Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7 Для сборки `.exe`: - **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей -- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен) +- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен для запуска `.exe`) ### Сборка: @@ -166,5 +168,5 @@ Src ### Установка зависимостей ```bash -pip install PySide2 lxml nuitka pyinstaller +pip install clang PySide2 lxml nuitka pyinstaller ``` \ No newline at end of file diff --git a/Src/DebugVarEdit_GUI.py b/Src/DebugVarEdit_GUI.py index 534a4e2..8aaff12 100644 --- a/Src/DebugVarEdit_GUI.py +++ b/Src/DebugVarEdit_GUI.py @@ -127,19 +127,28 @@ class VarEditor(QWidget): # Добавляем чекбокс для выбора типовой карты # --- Создаем верхнее меню --- menubar = QMenuBar(self) - target_menu = QMenu("Target", menubar) + 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.setChecked(True) # по умолчанию TMS - self.action_tms.triggered.connect(lambda: self.on_target_selected("tms")) - self.action_stm.triggered.connect(lambda: self.on_target_selected("stm")) + 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') - target_menu.addAction(self.action_tms) - target_menu.addAction(self.action_stm) + self.target_menu.addAction(self.action_tms) + self.target_menu.addAction(self.action_stm) - menubar.addMenu(target_menu) + menubar.addMenu(self.target_menu) # Кнопка сохранения btn_save = QPushButton(build_title) @@ -171,8 +180,10 @@ class VarEditor(QWidget): def on_target_selected(self, target): + self.target_menu.setTitle(f'МК: {target}') + self.settings.setValue("mcu_choosen", target) self.target = target.lower() - if target == "stm": + if self.target == "stm": choose_type_map(True) self.action_stm.setChecked(True) self.action_tms.setChecked(False) @@ -272,7 +283,7 @@ class VarEditor(QWidget): return 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 успешно сгенерирован.") self.update() except Exception as e: diff --git a/Src/generate_debug_vars.py b/Src/generate_debug_vars.py index e56db3e..47388d2 100644 --- a/Src/generate_debug_vars.py +++ b/Src/generate_debug_vars.py @@ -12,6 +12,7 @@ from xml.dom import minidom import myXML import argparse +shortnameSize = 10 # === Словарь соответствия типов XML → DebugVarType_t === type_map_tms = dict([ @@ -186,13 +187,16 @@ type_map_stm32 = dict([ )], ]) 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): typename_orig = typename.strip() @@ -286,9 +290,9 @@ def add_new_vars_to_xml(proj_path, xml_rel_path, output_path): if os.path.isfile(output_path): with open(output_path, 'r', encoding='utf-8', errors='ignore') as 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 , "ShortName"}, m = re.match( - 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*"([^"]+)"', + r'{\s*\(uint8_t\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: full_varname = m.group(1) # e.g., some.deep.var.name @@ -426,12 +430,27 @@ def read_vars_from_xml(proj_path, xml_rel_path): 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): output_dir = os.path.join(proj_path, output_dir) os.makedirs(output_dir, exist_ok=True) 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 @@ -479,7 +498,7 @@ def generate_vars_file(proj_path, xml_path, output_dir): # Дополнительные поля, например комментарий comment = info.get("comment", "") 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'): f_name = f'{vname},' @@ -489,7 +508,7 @@ def generate_vars_file(proj_path, xml_path, output_dir): f_short_name = f'"{short_trimmed}"' # оборачиваем в кавычки # Добавим комментарий после записи, если он есть 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 else: @@ -535,14 +554,19 @@ def generate_vars_file(proj_path, xml_path, output_dir): out_lines.append(f'\n\n// Определение массива с указателями на переменные для отладки') 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.extend(all_debug_lines) out_lines.append('};') out_lines.append('') # Выберем кодировку для записи файла # Если встречается несколько, возьмем первую из set - enc_to_write = 'cp1251' + if stm_flag_global == 0: + enc_to_write = 'cp1251' + else: + enc_to_write = 'utf-8' #print("== GLOBAL VARS FOUND ==") #for vname, (vtype, path) in vars_in_c.items(): @@ -552,6 +576,16 @@ def generate_vars_file(proj_path, xml_path, output_dir): with open(output_path, 'w', encoding=enc_to_write) as f: 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)}') @@ -613,16 +647,17 @@ Usage example: print(f"Error: Project path '{proj_path}' не является директорией или не существует.") 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__": main() -def run_generate(proj_path, xml_path, output_dir): +def run_generate(proj_path, xml_path, output_dir, shortname_size): import os - + global shortnameSize + shortnameSize = shortname_size # Normalize absolute paths proj_path = os.path.abspath(proj_path) xml_path_abs = os.path.abspath(xml_path) diff --git a/Src/scan_vars.py b/Src/scan_vars.py index 685c8a6..52fa146 100644 --- a/Src/scan_vars.py +++ b/Src/scan_vars.py @@ -154,6 +154,7 @@ def analyze_variables_across_files(c_files, h_files, include_dirs, global_defs): # Проверяем, начинается ли имя с "_" и содержит заглавные буквы или служебные символы return bool(re.match(r"^_[_A-Z]", var_name)) + if node.kind == clang.cindex.CursorKind.VAR_DECL: if node.semantic_parent.kind == clang.cindex.CursorKind.TRANSLATION_UNIT: is_extern = (node.storage_class == clang.cindex.StorageClass.EXTERN) @@ -170,7 +171,12 @@ def analyze_variables_across_files(c_files, h_files, include_dirs, global_defs): return # игнорируем только явно известные служебные переменные if node.spelling == 'HUGE': # еще одна служеюная, которую хз как выделять return + + if 'Drivers' in node.location.file.name: + return + if 'uint' in node.spelling: + a = 1 # Проверяем, является ли тип указателем на функцию # Признак: в типе есть '(' и ')' и '*', например: "void (*)(int)" if "(" in var_type and "*" in var_type and ")" in var_type: @@ -464,8 +470,6 @@ def analyze_typedefs_and_structs_across_files(c_files, include_dirs, global_defs def visit(node): if node.kind == clang.cindex.CursorKind.TYPEDEF_DECL: name = node.spelling - if 'ADC_HandleTypeDef' in name: - a =1 underlying = node.underlying_typedef_type.spelling typedefs[name] = underlying @@ -473,10 +477,7 @@ def analyze_typedefs_and_structs_across_files(c_files, include_dirs, global_defs prefix = "struct " if node.kind == clang.cindex.CursorKind.STRUCT_DECL else "union " raw_name = node.spelling - if 'struct (unnamed struct at F:\\Work\\Projects\\NIIET\\MZKT\\MZKT\\Drivers\\STM32F4xx_HAL_Driver\\Inc\\stm32f4xx_hal_adc.h:195:9)' in raw_name: - a =1 normalized_name = normalize_type_name(raw_name) - # struct_name всегда с префиксом if node.spelling and "unnamed" not in normalized_name: struct_name = f"{prefix}{normalized_name}" diff --git a/Src/var_table.py b/Src/var_table.py index 81be6bb..3c2337a 100644 --- a/Src/var_table.py +++ b/Src/var_table.py @@ -1,10 +1,10 @@ from PySide2.QtWidgets import ( QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter, - QAbstractItemView, QHeaderView, QLabel, + QAbstractItemView, QHeaderView, QLabel, QSpacerItem, QSizePolicy, QSpinBox, QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QScrollArea, QWidget ) from PySide2.QtGui import QColor, QBrush, QPalette -from PySide2.QtCore import Qt +from PySide2.QtCore import Qt, QSettings from enum import IntEnum from generate_debug_vars import type_map import time @@ -60,6 +60,57 @@ class FilterDialog(QDialog): 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) # Задаем фиксированный размер для аккуратного вида + + # Основной вертикальный макет + 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: @@ -83,6 +134,11 @@ class VariableTableWidget(QTableWidget): ]) self.setEditTriggers(QAbstractItemView.AllEditTriggers) self.var_list = [] + # Инициализируем QSettings с именем организации и приложения + self.settings = QSettings("SET", "DebugVarEdit_VarTable") + # Восстанавливаем сохранённое состояние, если есть + shortsize = self.settings.value("shortname_size", True, type=int) + self._shortname_size = shortsize self.type_options = list(dict.fromkeys(type_map.values())) self.pt_types_all = [t.replace('pt_', '') for t in self.type_options] @@ -231,7 +287,7 @@ class VariableTableWidget(QTableWidget): t3 = time.time() 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 color = None @@ -293,6 +349,13 @@ class VariableTableWidget(QTableWidget): if dlg.exec_(): self._ret_type_filter = dlg.get_selected() self.update_comboboxes({rows.ret_type: self._ret_type_filter}) + + elif logicalIndex == rows.short_name: + dlg = SetSizeDialog(self) + if dlg.exec_(): + self._shortname_size = dlg.get_selected_size() + self.settings.setValue("shortname_size", self._shortname_size) + self.check() diff --git a/debug_tools.c b/debug_tools.c index 032ee97..ec7e97c 100644 --- a/debug_tools.c +++ b/debug_tools.c @@ -1,18 +1,22 @@ #include "debug_tools.h" -#include "IQmathLib.h" + +#if !defined(GLOBAL_Q) +#define GLOBAL_Q 16 +#endif + DebugLowLevel_t debug_ll = DEBUG_LOWLEVEL_INIT; ///< () -static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var); -static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var); +static int getDebugVar(DebugVar_t *var, int32_t *int_var, float *float_var); +static int convertDebugVarToIQx(DebugVar_t *var, int32_t *ret_var); ///////////////////////////----EXAPLE-----////////////////////////////// -long var_numb = 1; ///< +int var_numb = 1; ///< DebugVarName_t var_name; ///< -long return_var; ///< -long return_ll_var; ///< +int32_t return_var; ///< +int32_t return_ll_var; ///< int result; ///< -char ext_date[] = {7, 233, 11, 07, 16, 50}; ///< +DateTime_t ext_date = {2025, 11, 07, 16, 50}; ///< /** * @brief . @@ -24,7 +28,7 @@ void Debug_Test_Example(void) 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); } @@ -33,25 +37,23 @@ void Debug_Test_Example(void) /** * @brief . * @param var_ind . - * @param return_long . + * @param return_32b . * @return int 0: , 1: . * @details . */ -int Debug_ReadVar(int var_ind, long *return_long) +int Debug_ReadVar(int var_ind, int32_t *return_32b) { - if(return_long == NULL) + if(return_32b == NULL) return 1; - long tmp_var; + int32_t tmp_var; if (var_ind >= DebugVar_Qnt) return 1; - if((dbg_vars[var_numb].ptr_type == pt_struct) || (dbg_vars[var_numb].ptr_type == pt_union) || - (dbg_vars[var_numb].ptr_type == pt_unknown)) + if((dbg_vars[var_ind].ptr_type == pt_struct) || (dbg_vars[var_ind].ptr_type == pt_union) || + (dbg_vars[var_ind].ptr_type == pt_unknown)) return 1; - - - return convertDebugVarToIQx(&dbg_vars[var_numb], return_long); + return convertDebugVarToIQx(&dbg_vars[var_ind], return_32b); } /** @@ -71,14 +73,14 @@ int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr) int i; // '\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]; - if (dbg_vars[var_numb].name[i] == '\0') + name_ptr[i] = dbg_vars[var_ind].name[i]; + if (dbg_vars[var_ind].name[i] == '\0') break; } // ( , 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; } @@ -86,19 +88,19 @@ int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr) /** * @brief . - * @param return_long , . + * @param return_32b , . * @return int 0: , 1: , 2: . * @details , . */ -int Debug_LowLevel_ReadVar(long *return_long) +int Debug_LowLevel_ReadVar(int32_t *return_32b) { - if (return_long == NULL) + if (return_32b == NULL) return 1; if (debug_ll.isVerified == 0) return 1; - char *addr = debug_ll.dbg_var.Ptr; - unsigned long addr_val = (unsigned long)addr; + uint8_t *addr = debug_ll.dbg_var.Ptr; + uint32_t addr_val = (uint32_t)addr; // ( .cmd ) if (!( @@ -114,37 +116,28 @@ int Debug_LowLevel_ReadVar(long *return_long) return 2; // } - return convertDebugVarToIQx(&debug_ll.dbg_var, return_long); -; + return convertDebugVarToIQx(&debug_ll.dbg_var, return_32b); } /** * @brief . - * @param external_date 6 : {year_hi, year_lo, day, month, hour, minute}. + * @param external_date DateTime_t * @return int 0: , 1: , -1: . * @details . */ -int Debug_LowLevel_Initialize(const char* external_date) +int Debug_LowLevel_Initialize(DateTime_t* external_date) { if (external_date == NULL) { 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 && - ext.month == debug_ll.build_date.month && - ext.day == debug_ll.build_date.day && - ext.hour == debug_ll.build_date.hour && - ext.minute == debug_ll.build_date.minute) + if (external_date->year == debug_ll.build_date.year && + external_date->month == debug_ll.build_date.month && + external_date->day == debug_ll.build_date.day && + external_date->hour == debug_ll.build_date.hour && + external_date->minute == debug_ll.build_date.minute) { debug_ll.isVerified = 1; return 0; // @@ -180,13 +173,13 @@ static int iqTypeToQ(DebugVarIQType_t t) /** * @brief IQ . * @param var . - * @param ret_var long. + * @param ret_var 32 . * @return int 0: , 1: , 2: , 3: . - * @details IQ , long . + * @details IQ , 32b . */ -static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) +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; if(getDebugVar(var, &iq_numb, &float_numb) != 0) @@ -198,30 +191,30 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) if (src_q < 0 || dst_q < 0) return 2; // - long long iq_united64 = 0; - long long iq_final64 = 0; + int64_t iq_united64 = 0; + int64_t iq_final64 = 0; // GLOBAL_Q (64-) if (var->iq_type == t_iq_none) { if (var->ptr_type == pt_float) { // float_numb 2^GLOBAL_Q (2^24=16777216) - // long long - iq_united64 = (long long)(float_numb * 16777216.0f); + // 64 + iq_united64 = (int64_t)(float_numb * 16777216.0f); } else { - iq_united64 = ((long long)iq_numb) << GLOBAL_Q; + iq_united64 = ((int64_t)iq_numb) << GLOBAL_Q; } } else { int shift = GLOBAL_Q - src_q; if (shift >= 0) - iq_united64 = ((long long)iq_numb) << shift; + iq_united64 = ((int64_t)iq_numb) << shift; else - iq_united64 = ((long long)iq_numb) >> (-shift); + iq_united64 = ((int64_t)iq_numb) >> (-shift); } // GLOBAL_Q IQ (64-) if (var->return_type == t_iq_none) { // , - *ret_var = (long)(iq_united64 >> GLOBAL_Q); + *ret_var = (uint32_t)(iq_united64 >> GLOBAL_Q); } else { int shift = dst_q - GLOBAL_Q; if (shift >= 0) @@ -230,10 +223,10 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) iq_final64 = iq_united64 >> (-shift); // int32_t - if (iq_final64 > LONG_MAX || iq_final64 < LONG_MIN) + if (iq_final64 > 2147483647 || iq_final64 < -2147483648) return 3; // - *ret_var = (long)iq_final64; + *ret_var = (uint32_t)iq_final64; } return 0; @@ -242,50 +235,53 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) /** * @brief . * @param var DebugVar. - * @param int_var long . + * @param int_var 32 . * @param float_var float . * @return int 0: , 1: , 3/4: . * @details . */ -static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var) +static int getDebugVar(DebugVar_t *var, int32_t *int_var, float *float_var) { if (!var || !int_var || !float_var || !var->Ptr) return 1; // : null - char *addr = var->Ptr; - unsigned long addr_val = (unsigned long)addr; + uint8_t *addr = var->Ptr; + uint32_t addr_val = (uint32_t)addr; switch (var->ptr_type) { case pt_int8: // 8 + if ((addr_val & ALIGN_8BIT) != 0) // + return 1; // + *int_var = *((volatile int8_t *)addr); case pt_uint8: - // 8 - *int_var = *((volatile char *)addr); + if ((addr_val & ALIGN_8BIT) != 0) // + return 1; // + *int_var = *((volatile uint8_t *)addr); break; case pt_int16: // 16 (int) + if ((addr_val & ALIGN_16BIT) != 0) // + return 2; // + *int_var = *((volatile int16_t *)addr); case pt_uint16: - *int_var = *((volatile int *)addr); + if ((addr_val & ALIGN_16BIT) != 0) // + return 2; // + *int_var = *((volatile uint16_t *)addr); break; - case pt_int32: // 32 (long) - case pt_uint32: - if (addr_val & 0x1) // 2 (4 ) + case pt_int32: // 32 + if ((addr_val & ALIGN_32BIT) != 0) // 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; -// 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 ) - if (addr_val & 0x1) // 2 + if ((addr_val & ALIGN_FLOAT) != 0) // return 4; // *float_var = *((volatile float *)addr); break; @@ -310,211 +306,3 @@ static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var) 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; diff --git a/debug_tools.h b/debug_tools.h index 9c52b39..4b1b2a5 100644 --- a/debug_tools.h +++ b/debug_tools.h @@ -1,7 +1,48 @@ #ifndef DEBUG_TOOLS #define DEBUG_TOOLS -#include "IQmathLib.h" -#include "DSP281x_Device.h" +#include +#include + + +//#if (LONG_MAX != 2147483647L) +//# error "debug_tools: this code assumes 32-bit long. Please update DebugValue_t typedef." +//#endif + + + + +#if defined(uint8_t) && defined(int8_t) // 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 !defined(uint8_t) + typedef unsigned char uint8_t; +#endif +#if !defined(int8_t) + typedef signed char int8_t; +#endif +#if !defined(NULL) + #define NULL 0 +#endif +#if !defined(NULL) +#define NULL 0 +#endif + /** * @brief , . @@ -17,7 +58,7 @@ typedef enum pt_uint16, // unsigned int pt_uint32, // unsigned long pt_uint64, // unsigned long - pt_float, // float + pt_float, // floatf pt_struct, // struct pt_union, // struct // pt_ptr_int8, // signed char* @@ -80,22 +121,24 @@ typedef char DebugVarName_t[11]; ///< */ typedef struct { - char* Ptr; ///< + uint8_t* Ptr; ///< DebugVarPtrType_t ptr_type; ///< DebugVarIQType_t iq_type; ///< IQ ( ) DebugVarIQType_t return_type;///< IQ DebugVarName_t name; ///< } DebugVar_t; +typedef long DebugValue_t; + /** * @brief . */ typedef struct { - int year; ///< (, 2025) - char month; ///< (1-12) - char day; ///< (1-31) - char hour; ///< (0-23) - char minute; ///< (0-59) + uint16_t year; ///< (, 2025) + uint8_t month; ///< (1-12) + uint8_t day; ///< (1-31) + uint8_t hour; ///< (0-23) + uint8_t minute; ///< (0-59) } DateTime_t; /** @@ -126,12 +169,12 @@ extern DebugVar_t dbg_vars[]; ///< 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_LowLevel_ReadVar(long *return_long); +int Debug_LowLevel_ReadVar(int32_t *return_long); /* */ -int Debug_LowLevel_Initialize(const char* external_date); +int Debug_LowLevel_Initialize(DateTime_t *external_date); #endif //DEBUG_TOOLS