diff --git a/DebugVarEdit.exe b/DebugVarEdit.exe index 5aaac85..bcf632b 100644 Binary files a/DebugVarEdit.exe and b/DebugVarEdit.exe differ diff --git a/Src/DebugVarEdit_GUI.py b/Src/DebugVarEdit_GUI.py index 4c1c88a..534a4e2 100644 --- a/Src/DebugVarEdit_GUI.py +++ b/Src/DebugVarEdit_GUI.py @@ -5,7 +5,7 @@ import sys import os import subprocess 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 import threading from generate_debug_vars import run_generate @@ -21,8 +21,9 @@ from PySide2.QtWidgets import ( QApplication, QWidget, QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QVBoxLayout, QHBoxLayout, QPushButton, 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.QtCore import Qt, QProcess, QObject, Signal, QSettings @@ -58,6 +59,7 @@ class VarEditor(QWidget): self.output_path = None self._updating = False # Флаг блокировки рекурсии self._resizing = False # флаг блокировки повторного вызова + self.target = 'TMS' self.initUI() def initUI(self): @@ -122,6 +124,23 @@ class VarEditor(QWidget): self.btn_update_vars = QPushButton(scan_title) self.btn_update_vars.clicked.connect(self.update_vars_data) + # Добавляем чекбокс для выбора типовой карты + # --- Создаем верхнее меню --- + menubar = QMenuBar(self) + target_menu = QMenu("Target", menubar) + # Создаем действия для выбора Target + self.action_tms = QAction("TMS", self, checkable=True) + self.action_stm = QAction("STM", self, checkable=True) + # Группируем действия чтобы выбирался только один + 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")) + + target_menu.addAction(self.action_tms) + target_menu.addAction(self.action_stm) + + menubar.addMenu(target_menu) + # Кнопка сохранения btn_save = QPushButton(build_title) btn_save.clicked.connect(self.save_build) @@ -137,6 +156,7 @@ class VarEditor(QWidget): self.table = VariableTableWidget() # Основной layout layout = QVBoxLayout() + layout.setMenuBar(menubar) # прикрепляем menubar в layout сверху layout.addLayout(xml_layout) layout.addLayout(proj_layout) layout.addLayout(makefile_layout) @@ -150,7 +170,18 @@ class VarEditor(QWidget): self.setLayout(layout) - + def on_target_selected(self, target): + self.target = target.lower() + if 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): xml_path = self.xml_output_edit.text().strip() return xml_path @@ -358,15 +389,25 @@ class VarEditor(QWidget): super().keyPressEvent(event) 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( - self, "Выберите Makefile", filter="Makefile (makefile);;All Files (*)" + self, + dialog_title, + filter=file_filter ) - if file_path and self.proj_path: - path = myXML.make_relative_path(file_path, self.proj_path) - else: - path = file_path - self.makefile_edit.setText(path) - self.makefile_path = path + if file_path: + if self.proj_path: + path = myXML.make_relative_path(file_path, self.proj_path) + else: + path = file_path + self.makefile_edit.setText(path) + self.makefile_path = path def __browse_source_output(self): dir_path = QFileDialog.getExistingDirectory(self, "Выберите папку для debug_vars.c") @@ -438,12 +479,12 @@ class VarEditor(QWidget): self.write_to_xml() - def __open_variable_selector(self): + def __open_variable_selector(self): + self.update() if not self.vars_list: QMessageBox.warning(self, "Нет переменных", f"Сначала загрузите переменные ({scan_title}).") return - self.update() dlg = VariableSelectorDialog(self.table, self.vars_list, self.structs, self.typedef_map, self.xml_path, self) if dlg.exec_(): self.write_to_xml() diff --git a/Src/generate_debug_vars.py b/Src/generate_debug_vars.py index 01bc481..e56db3e 100644 --- a/Src/generate_debug_vars.py +++ b/Src/generate_debug_vars.py @@ -14,7 +14,7 @@ import argparse # === Словарь соответствия типов XML → DebugVarType_t === -type_map = dict([ +type_map_tms = dict([ *[(k, 'pt_int8') for k in ('signed char', 'char')], *[(k, 'pt_int16') for k in ('int', 'int16', 'short')], *[(k, 'pt_int32') for k in ('long', 'int32', '_iqx')], @@ -52,6 +52,147 @@ type_map = dict([ ('struct[]', 'pt_arr_struct'), ('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 + +def choose_type_map(stm_flag): + global type_map # объявляем, что будем менять глобальную переменную + if stm_flag: + type_map = type_map_stm32 + else: + type_map = type_map_tms def map_type_to_pt(typename, varname=None, typedef_map=None): typename_orig = typename.strip() diff --git a/Src/makefile_parser.py b/Src/makefile_parser.py index e2e17e0..e9ba9e7 100644 --- a/Src/makefile_parser.py +++ b/Src/makefile_parser.py @@ -1,5 +1,6 @@ import os import re +from lxml import etree as ET 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 +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) + + # Добавим + 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): - makefile_dir = os.path.dirname(makefile_path) - project_root = proj_path + import os + import re + + project_root = os.path.abspath(proj_path) + c_files = [] + include_dirs = set() + defines = [] # Заглушка: нет define-параметров из Makefile with open(makefile_path, 'r', encoding='utf-8') as f: lines = f.readlines() - objs_lines = [] + raw_entries = [] collecting = False for line in lines: stripped = line.strip() - if stripped.startswith("ORDERED_OBJS") and "+=" in stripped: - parts = stripped.split("\\") - first_part = parts[0] - idx = first_part.find("+=") - tail = first_part[idx+2:].strip() - if tail: - objs_lines.append(tail) + + if (("ORDERED_OBJS" in stripped or "C_SOURCES" in stripped) and ("+=" in stripped or "=" in stripped)): collecting = True - if len(parts) > 1: - for p in parts[1:]: - p = p.strip() - if p: - objs_lines.append(p) - continue if collecting: - if stripped.endswith("\\"): - objs_lines.append(stripped[:-1].strip()) - else: - objs_lines.append(stripped) + line_clean = stripped.rstrip("\\").strip() + if line_clean: + line_clean = re.sub(r"\$\([^)]+\)", "", line_clean) + line_clean = re.sub(r"\$\{[^}]+\}", "", line_clean) + raw_entries.append(line_clean) + + if not stripped.endswith("\\"): collecting = False - 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 = [] - for part in objs_str.split(): - part = part.strip() - if part.startswith('"') and part.endswith('"'): - part = part[1:-1] - if part: - objs.append(part) + if token.endswith(".obj"): + token = re.sub(r"\.obj$", ".c", token) + elif token.endswith(".o"): + token = re.sub(r"\.o$", ".c", token) - c_files = [] - include_dirs = set() + if token.endswith(".c"): + abs_path = os.path.normpath(os.path.join(project_root, token)) + if os.path.isfile(abs_path): + if not any(x in abs_path for x in ["DebugTools", "v120", "v100"]): + c_files.append(abs_path) + include_dirs.add(os.path.dirname(abs_path)) - for obj_path in objs: - if "DebugTools" in obj_path: - continue - if "v120" in obj_path: - continue - if "v100" in obj_path: - continue + if not c_files: + makefile_dir = os.path.dirname(os.path.abspath(makefile_path)) + objects_list_path = os.path.join(makefile_dir, "objects.list") + c_from_objects, inc_from_objects = parse_objects_list(objects_list_path, project_root) + c_files.extend(c_from_objects) + include_dirs.update(inc_from_objects) - if obj_path.startswith("Debug\\") or obj_path.startswith("Debug/"): - rel_path = obj_path.replace("Debug\\", "Src\\").replace("Debug/", "Src/") - else: - rel_path = obj_path + for line in lines: + if "-I" in line or "C_INCLUDES" in line: + matches = re.findall(r"-I\s*([^\s\\]+)", line) + for match in matches: + match = match.strip('"').replace("\\", "/") + abs_include = os.path.normpath(os.path.join(project_root, match)) + if os.path.isdir(abs_include): + include_dirs.add(abs_include) - abs_path = os.path.normpath(os.path.join(project_root, rel_path)) - - root, ext = os.path.splitext(abs_path) - if ext.lower() == ".obj": - c_path = root + ".c" - else: - c_path = abs_path - - # Проверяем существование файла, если нет — пропускаем - if not os.path.isfile(c_path): - continue - - # Сохраняем только .c файлы - if c_path.lower().endswith(".c"): - c_files.append(c_path) - dir_path = os.path.dirname(c_path) - if dir_path and "DebugTools" not in dir_path: - include_dirs.add(dir_path) + # Добавляем пути с заменой 'Src' на 'Inc', если путь заканчивается на 'Src' + additional_includes = set() + for inc in include_dirs: + if inc.endswith(os.sep + "Src") or inc.endswith("/Src"): + inc_inc = inc[:-3] + "Inc" # заменяем 'Src' на 'Inc' + if os.path.isdir(inc_inc): + additional_includes.add(inc_inc) + include_dirs.update(additional_includes) h_files = find_all_includes_recursive(c_files, include_dirs) + return sorted(c_files), sorted(h_files), sorted(include_dirs), sorted(defines) - 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) \ No newline at end of file diff --git a/Src/scan_vars.py b/Src/scan_vars.py index 0ef77a6..685c8a6 100644 --- a/Src/scan_vars.py +++ b/Src/scan_vars.py @@ -11,7 +11,7 @@ from clang import cindex from clang.cindex import Config import lxml.etree as ET from xml.dom import minidom -from makefile_parser import parse_makefile +from makefile_parser import parse_project from collections import deque import argparse import myXML @@ -118,11 +118,11 @@ def get_canonical_typedef_file(var_type, include_dirs): break 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...") 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 = {} # имя переменной → словарь с инфой h_files_needed = set() vars_need_extern = {} # имя переменной → словарь без поля 'extern' @@ -295,6 +295,8 @@ def strip_ptr_and_array(typename): return typename + + def analyze_typedefs_and_struct(typedefs, structs): optional_printf(PRINT_STATUS, "Resolving typedefs and expanding struct field types...") @@ -422,10 +424,28 @@ def contains_anywhere_in_node(node, target: str) -> bool: 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...") 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_structs_raw = {} @@ -444,6 +464,8 @@ def analyze_typedefs_and_structs_across_files(c_files, include_dirs): 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 @@ -451,6 +473,8 @@ def analyze_typedefs_and_structs_across_files(c_files, include_dirs): 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 всегда с префиксом @@ -855,10 +879,10 @@ Usage example: print(f"Error: Makefile path '{makefile_path}' does not exist.") 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) - typedefs, structs = analyze_typedefs_and_structs_across_files(c_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, global_defs) vars = dict(sorted(vars.items())) includes = get_sorted_headers(c_files, includes, include_dirs) @@ -898,10 +922,10 @@ def run_scan(proj_path, makefile_path, output_xml, verbose=2): if not os.path.isfile(makefile_path): 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) - typedefs, structs = analyze_typedefs_and_structs_across_files(c_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, global_defs) vars = dict(sorted(vars.items())) includes = get_sorted_headers(c_files, includes, include_dirs) diff --git a/debug_tools.c b/debug_tools.c index 7e6287e..032ee97 100644 --- a/debug_tools.c +++ b/debug_tools.c @@ -1,18 +1,23 @@ #include "debug_tools.h" #include "IQmathLib.h" -DebugLowLevel_t debug_ll = DEBUG_LOWLEVEL_INIT; +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); ///////////////////////////----EXAPLE-----////////////////////////////// -long var_numb = 1; -DebugVarName_t var_name; -long return_var; -long return_ll_var; -int result; -char ext_date[] = {7, 233, 11, 07, 16, 50}; +long var_numb = 1; ///< +DebugVarName_t var_name; ///< +long return_var; ///< +long return_ll_var; ///< +int result; ///< +char ext_date[] = {7, 233, 11, 07, 16, 50}; ///< + +/** + * @brief . + * @details . + */ void Debug_Test_Example(void) { result = Debug_ReadVar(var_numb, &return_var); @@ -24,6 +29,14 @@ void Debug_Test_Example(void) } ///////////////////////////----PUBLIC-----////////////////////////////// + +/** + * @brief . + * @param var_ind . + * @param return_long . + * @return int 0: , 1: . + * @details . + */ int Debug_ReadVar(int var_ind, long *return_long) { if(return_long == NULL) @@ -41,6 +54,13 @@ int Debug_ReadVar(int var_ind, long *return_long) 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) { if(name_ptr == NULL) @@ -64,7 +84,12 @@ int Debug_ReadVarName(int var_ind, DebugVarName_t name_ptr) } - +/** + * @brief . + * @param return_long , . + * @return int 0: , 1: , 2: . + * @details , . + */ int Debug_LowLevel_ReadVar(long *return_long) { if (return_long == NULL) @@ -93,7 +118,12 @@ int Debug_LowLevel_ReadVar(long *return_long) ; } - +/** + * @brief . + * @param external_date 6 : {year_hi, year_lo, day, month, hour, minute}. + * @return int 0: , 1: , -1: . + * @details . + */ int Debug_LowLevel_Initialize(const char* external_date) { if (external_date == NULL) { @@ -129,6 +159,12 @@ int Debug_LowLevel_Initialize(const char* external_date) /////////////////////----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) { if (t == t_iq_none) @@ -141,6 +177,13 @@ static int iqTypeToQ(DebugVarIQType_t t) return -1; // } +/** + * @brief IQ . + * @param var . + * @param ret_var long. + * @return int 0: , 1: , 2: , 3: . + * @details IQ , long . + */ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) { long iq_numb, iq_united, iq_final; @@ -196,6 +239,14 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var) return 0; } +/** + * @brief . + * @param var DebugVar. + * @param int_var long . + * @param float_var float . + * @return int 0: , 1: , 3/4: . + * @details . + */ static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var) { if (!var || !int_var || !float_var || !var->Ptr) diff --git a/debug_tools.h b/debug_tools.h index 7e050af..9c52b39 100644 --- a/debug_tools.h +++ b/debug_tools.h @@ -3,6 +3,9 @@ #include "IQmathLib.h" #include "DSP281x_Device.h" +/** + * @brief , . + */ typedef enum { pt_unknown, // unknown @@ -31,6 +34,9 @@ typedef enum // pt_arr_uint32, // unsigned long[] }DebugVarPtrType_t; +/** + * @brief IQ- . + */ typedef enum { t_iq_none, @@ -67,45 +73,65 @@ typedef enum t_iq30 }DebugVarIQType_t; -typedef char DebugVarName_t[11]; +typedef char DebugVarName_t[11]; ///< ( 10 + \0) + +/** + * @brief . + */ typedef struct { - char* Ptr; - DebugVarPtrType_t ptr_type; - DebugVarIQType_t iq_type; - DebugVarIQType_t return_type; - DebugVarName_t name; -}DebugVar_t; + char* Ptr; ///< + DebugVarPtrType_t ptr_type; ///< + DebugVarIQType_t iq_type; ///< IQ ( ) + DebugVarIQType_t return_type;///< IQ + DebugVarName_t name; ///< +} DebugVar_t; +/** + * @brief . + */ typedef struct { - int year; - char month; - char day; - char hour; - char minute; + int year; ///< (, 2025) + char month; ///< (1-12) + char day; ///< (1-31) + char hour; ///< (0-23) + char minute; ///< (0-59) } DateTime_t; +/** + * @brief . + */ typedef struct { - DateTime_t build_date; - unsigned int isVerified; - DebugVar_t dbg_var; + DateTime_t build_date; ///< + unsigned int isVerified; ///< (0 , 1 ) + DebugVar_t dbg_var; ///< }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} +/** @brief */ #define DEBUG_VAR_INIT {0, pt_uint16, t_iq_none, t_iq_none, "\0"} +/** @brief */ #define DEBUG_LOWLEVEL_INIT {DATE_INIT, 0, DEBUG_VAR_INIT} -extern int DebugVar_Qnt; -extern DebugVar_t dbg_vars[]; +extern int DebugVar_Qnt; ///< +extern DebugVar_t dbg_vars[]; ///< +/* */ void Debug_Test_Example(void); +/* */ int Debug_ReadVar(int var_ind, long *return_long); +/* */ 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); #endif //DEBUG_TOOLS