Доработана функции для считывания переменных

Добавлены бета-функции для считывания переменны по адресу

+фиксы багов

future:
- в селекторе сделать две таблички для всех переменных и для выборанных
- по кнопке переносить переменные из всех в выбранные
- переменные из выбранных и добавлять в основную табличку
- сделать отдельный класс для таблички - который будет принимать спиоск переменных для отображения
This commit is contained in:
Razvalyaev 2025-07-11 16:46:51 +03:00
parent d3f1e824fa
commit e4fcfd11d7
12 changed files with 2512 additions and 2053 deletions

Binary file not shown.

View File

@ -8,12 +8,11 @@ import xml.etree.ElementTree as ET
from generateVars import type_map
from enum import IntEnum
import threading
from scanVars import run_scan
from generateVars import run_generate
import setupVars
from VariableSelector import VariableSelectorDialog
from VariableTable import VariableTableWidget, rows
from scanVarGUI import ProcessOutputWindowDummy
from scanVarGUI import ProcessOutputWindow
import scanVars
import myXML
import time
@ -202,25 +201,10 @@ class VarEditor(QWidget):
# Создаём окно с кнопкой "Готово"
self.proc_win = ProcessOutputWindowDummy(self.__after_scanvars_finished)
self.emitting_stream = self.proc_win.emitting_stream # ключевая строка!
self.proc_win.show()
self.proc_win = ProcessOutputWindow(self.proj_path, self.makefile_path, self.xml_path,
on_done_callback=self.__after_scanvars_finished)
self.proc_win.start_scan()
def run_scan_wrapper():
try:
old_stdout = sys.stdout
sys.stdout = self.emitting_stream
run_scan(self.proj_path, self.makefile_path, self.xml_path)
except Exception as e:
self.emitting_stream.text_written.emit(f"\n[ОШИБКА] {e}")
finally:
sys.stdout = old_stdout
self.emitting_stream.text_written.emit("\n--- Анализ завершён ---")
self.proc_win.btn_close.setEnabled(True)
threading.Thread(target=run_scan_wrapper, daemon=True).start()
def save_build(self):
@ -435,15 +419,10 @@ class VarEditor(QWidget):
if not selected_rows:
return
# Удаляем из vars_list те, у кого show_var == true и имя совпадает
filtered_vars = [v for v in self.vars_list if v.get('show_var', 'false') == 'true']
for row in selected_rows:
if 0 <= row < len(filtered_vars):
var_to_remove = filtered_vars[row]
for v in self.vars_list:
if v['name'] == var_to_remove['name']:
v['show_var'] = 'false'
break
if 0 <= row < len(self.vars_list):
# Меняем флаг show_var для переменной с этим индексом
self.vars_list[row]['show_var'] = 'false'
self.table.populate(self.vars_list, self.structs, self.write_to_xml)
self.write_to_xml()
@ -454,7 +433,7 @@ class VarEditor(QWidget):
QMessageBox.warning(self, "Нет переменных", f"Сначала загрузите переменные ({scan_title}).")
return
dlg = VariableSelectorDialog(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_():
self.write_to_xml()
self.update()

View File

@ -1,10 +1,12 @@
import re
import xml.etree.ElementTree as ET
from PySide2.QtWidgets import (
QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton,
QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout
)
from PySide2.QtGui import QKeySequence, QKeyEvent
from PySide2.QtCore import Qt, QStringListModel, QSettings
import VariableTable
import setupVars
import myXML
import time
@ -13,14 +15,14 @@ import time
array_re = re.compile(r'^(\w+)\[(\d+)\]$')
class VariableSelectorDialog(QDialog):
def __init__(self, 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)
self.setWindowTitle("Выбор переменных")
self.setAttribute(Qt.WA_DeleteOnClose)
self.resize(600, 500)
self.selected_names = []
self._bckspc_pressed = False # флаг подавления добавления разделителя
self.table = table
self.all_vars = all_vars
self.structs = structs
self.typedefs = typedefs
@ -28,6 +30,7 @@ class VariableSelectorDialog(QDialog):
self.var_map = {v['name']: v for v in all_vars}
self.node_index = {}
self.xml_path = xml_path # сохраняем путь к xml
self.manual_completion_active = False
# --- Добавляем чекбокс для автодополнения ---
self.autocomplete_checkbox = QCheckBox("Включить автодополнение")
@ -289,9 +292,10 @@ class VariableSelectorDialog(QDialog):
if not name_parts:
continue
last_part = name_parts[-1].lower()
if prefix == '' or last_part.startswith(prefix):
if prefix == '' or prefix in last_part: # здесь изменено
completions.append(name)
self.completer.complete()
return completions
@ -328,9 +332,16 @@ class VariableSelectorDialog(QDialog):
def eventFilter(self, obj, event):
if obj == self.search_input and isinstance(event, QKeyEvent):
if event.key() == Qt.Key_Space and event.modifiers() & Qt.ControlModifier:
self.manual_completion_active = True
text = self.search_input.text().strip()
self.run_completions(text)
elif event.key() == Qt.Key_Escape:
# Esc — выключаем ручной режим и скрываем подсказки, если autocomplete выключен
if not self.autocomplete_checkbox.isChecked():
self.manual_completion_active = False
self.completer.popup().hide()
return True
if event.key() == Qt.Key_Backspace:
self._bckspc_pressed = True
else:
@ -341,6 +352,9 @@ class VariableSelectorDialog(QDialog):
def run_completions(self, text):
completions = self.update_completions(text)
if not self.autocomplete_checkbox.isChecked() and self._bckspc_pressed:
text = text[:-1]
if len(completions) == 1 and completions[0].lower() == text.lower():
# Найдем узел с таким именем
def find_exact_item(name):
@ -391,6 +405,12 @@ class VariableSelectorDialog(QDialog):
text = self.search_input.text().strip()
if self.autocomplete_checkbox.isChecked():
self.run_completions(text)
else:
# Если выключено, показываем подсказки только если флаг ручного вызова True
if self.manual_completion_active:
self.run_completions(text)
else:
self.completer.popup().hide()
def on_add_clicked(self):
self.selected_names = []
@ -462,9 +482,7 @@ class VariableSelectorDialog(QDialog):
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.")
return
import xml.etree.ElementTree as ET
tree = ET.parse(self.xml_path)
root = tree.getroot()
root, tree = myXML.safe_parse_xml(self.xml_path)
if root is None:
return
@ -485,7 +503,6 @@ class VariableSelectorDialog(QDialog):
myXML.fwrite(root, self.xml_path)
self.populate_tree()
self.done(QDialog.Accepted)
@ -503,8 +520,50 @@ class VariableSelectorDialog(QDialog):
def delete_selected_vars(self):
selected_names = self._get_selected_var_names()
if not selected_names:
print("nothing selected")
return
# Обновляем var_map и all_vars
for name in selected_names:
if name in self.var_map:
self.var_map[name]['show_var'] = 'false'
self.var_map[name]['enable'] = 'false'
for v in self.all_vars:
if v['name'] == name:
v['show_var'] = 'false'
v['enable'] = 'false'
break
# Проверка пути к XML
if not hasattr(self, 'xml_path') or not self.xml_path:
from PySide2.QtWidgets import QMessageBox
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно обновить переменные.")
return
root, tree = myXML.safe_parse_xml(self.xml_path)
if root is None:
return
vars_section = root.find('variables')
if vars_section is None:
return
for var_elem in vars_section.findall('var'):
name = var_elem.attrib.get('name')
if name in selected_names:
def set_text(tag, value):
el = var_elem.find(tag)
if el is None:
el = ET.SubElement(var_elem, tag)
el.text = value
set_text('show_var', 'false')
set_text('enable', 'false')
myXML.fwrite(root, self.xml_path)
self.table.populate(self.all_vars, self.structs, None)
# Проверка пути к XML
if not hasattr(self, 'xml_path') or not self.xml_path:
from PySide2.QtWidgets import QMessageBox
@ -512,8 +571,7 @@ class VariableSelectorDialog(QDialog):
return
import xml.etree.ElementTree as ET
tree = ET.parse(self.xml_path)
root = tree.getroot()
root, tree = myXML.safe_parse_xml(self.xml_path)
if root is None:
return
@ -532,10 +590,22 @@ class VariableSelectorDialog(QDialog):
# Удаляем из all_vars (глобально)
self.all_vars[:] = [v for v in self.all_vars if v['name'] not in selected_names]
# Удаляем из expanded_vars (тоже глобально)
def filter_out_selected(vars_list):
filtered = []
for v in vars_list:
if v['name'] not in selected_names:
# Рекурсивно фильтруем детей, если есть
if 'children' in v:
v = v.copy()
v['children'] = filter_out_selected(v['children'])
filtered.append(v)
return filtered
self.expanded_vars[:] = filter_out_selected(self.expanded_vars)
if removed_any:
myXML.fwrite(root, self.xml_path)
self.populate_tree()
self.filter_tree()
def _get_selected_var_names(self):

View File

@ -1,6 +1,12 @@
import sys
import re
import multiprocessing
import sys
import contextlib
import io
import json
from scanVars import run_scan
from VariableTable import VariableTableWidget, rows
from PySide2.QtWidgets import (
@ -10,7 +16,7 @@ from PySide2.QtWidgets import (
QDialog, QTreeWidget, QTreeWidgetItem, QSizePolicy, QHeaderView, QProgressBar
)
from PySide2.QtGui import QTextCursor, QKeyEvent
from PySide2.QtCore import Qt, QProcess, QObject, Signal, QSettings
from PySide2.QtCore import Qt, QProcess, QObject, Signal, QTimer
class EmittingStream(QObject):
@ -67,24 +73,28 @@ class EmittingStream(QObject):
self._buffer = ""
class ProcessOutputWindowDummy(QDialog):
def __init__(self, on_done_callback):
class ProcessOutputWindow(QDialog):
def __init__(self, proj_path, makefile_path, xml_path, on_done_callback=None):
super().__init__()
self.setWindowTitle("Поиск переменных...")
self.resize(600, 480)
self.setModal(True)
self.proj_path = proj_path
self.makefile_path = makefile_path
self.xml_path = xml_path
self._on_done_callback = on_done_callback
self.layout = QVBoxLayout(self)
self.output_edit = QTextEdit()
self.output_edit.setReadOnly(True)
self.layout.addWidget(self.output_edit)
# Метка с именем прогрессбара
self.progress_label = QLabel("Progress:")
self.layout.addWidget(self.progress_label)
# Прогрессбар
self.progress_bar = QProgressBar()
self.progress_bar.setMinimum(0)
self.progress_bar.setValue(0)
@ -93,29 +103,55 @@ class ProcessOutputWindowDummy(QDialog):
self.btn_close = QPushButton("Закрыть")
self.btn_close.setEnabled(False)
self.layout.addWidget(self.btn_close)
self.btn_close.clicked.connect(self.__handle_done)
self._on_done_callback = on_done_callback
self.emitting_stream = EmittingStream()
self.emitting_stream.text_written.connect(self.append_text)
self.emitting_stream.progress_updated.connect(self.update_progress)
self.queue = None
self.proc = None
sys.stdout = self.emitting_stream
def __handle_done(self):
sys.stdout = sys.__stdout__ # восстановить stdout
if self._on_done_callback:
self._on_done_callback()
self.accept()
def start_scan(self):
self.queue = multiprocessing.Queue()
self.proc = multiprocessing.Process(
target=run_scan_process,
args=(self.proj_path, self.makefile_path, self.xml_path, self.queue),
daemon=True)
self.proc.start()
self.timer = QTimer(self)
self.timer.timeout.connect(self.poll_queue)
self.timer.start(100)
self.show()
def poll_queue(self):
try:
while True:
msg = self.queue.get_nowait()
if msg is None:
# Конец процесса
self.btn_close.setEnabled(True)
self.append_text("\n--- Анализ завершён ---")
self.timer.stop()
return
# Пытаемся разобрать JSON-сообщение
if isinstance(msg, str) and msg.startswith("PROGRESS_MSG:"):
try:
data = json.loads(msg[len("PROGRESS_MSG:"):])
self.update_progress(data["bar_name"], data["current"], data["total"])
except Exception:
# Если не удалось распарсить, выводим как текст
self.append_text(msg)
else:
self.append_text(msg)
except Exception:
pass # Очередь пустая
def append_text(self, text):
cursor = self.output_edit.textCursor()
cursor.movePosition(QTextCursor.End)
if not text.endswith('\n'):
text += '\n'
for line in text.splitlines(True):
cursor.insertText(line)
cursor.insertText(text)
self.output_edit.setTextCursor(cursor)
self.output_edit.ensureCursorVisible()
@ -123,3 +159,61 @@ class ProcessOutputWindowDummy(QDialog):
self.progress_label.setText(f"{bar_name}")
self.progress_bar.setMaximum(total)
self.progress_bar.setValue(current)
def __handle_done(self):
self.close()
def closeEvent(self, event):
if self.proc and self.proc.is_alive():
self.proc.terminate()
self.proc.join()
self.btn_close.setEnabled(True)
self.append_text("Сканирование прервано.")
def run_scan_process(proj_path, makefile_path, xml_path, queue):
class QueueWriter(io.TextIOBase):
def __init__(self):
self._buffer = ""
self._current_bar_name = None
def write(self, txt):
self._buffer += txt
while '\n' in self._buffer:
line, self._buffer = self._buffer.split('\n', 1)
# Обработка прогресса
if line.startswith('Progress: "') and line.endswith('"'):
# Название прогресс-бара
bar_name = line[len('Progress: "'):-1]
self._current_bar_name = bar_name
elif re.match(r'^Progress:\s*\d+\s*/\s*\d+$', line):
m = re.match(r'^Progress:\s*(\d+)\s*/\s*(\d+)$', line)
if m:
current = int(m.group(1))
total = int(m.group(2))
bar_name = self._current_bar_name or "Progress"
# Отправляем специальное сообщение в очередь в формате JSON
msg = {
"bar_name": bar_name,
"current": current,
"total": total
}
queue.put("PROGRESS_MSG:" + json.dumps(msg))
else:
# Обычный вывод
queue.put(line)
def flush(self):
if self._buffer.strip():
queue.put(self._buffer.strip())
self._buffer = ""
sys.stdout = QueueWriter()
sys.stderr = sys.stdout
try:
run_scan(proj_path, makefile_path, xml_path)
except Exception as e:
queue.put(f"[ОШИБКА] {e}")
finally:
queue.put(None) # сигнал окончания

View File

@ -14,7 +14,6 @@ from xml.dom import minidom
from parseMakefile import parse_makefile
from collections import deque
import argparse
from setupVars import make_relative_path
import myXML
BITFIELD_WIDTHS = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}
@ -582,12 +581,12 @@ def generate_xml_output(proj_path, xml_path, unique_vars, h_files_needed, vars_n
}
if makefile_path:
rel_makefile = make_relative_path(makefile_path, proj_path)
rel_makefile = myXML.make_relative_path(makefile_path, proj_path)
if not os.path.isabs(rel_makefile):
analysis_attrs["makefile_path"] = rel_makefile.replace("\\", "/")
if structs_xml_path:
rel_struct = make_relative_path(structs_xml_path, proj_path)
rel_struct = myXML.make_relative_path(structs_xml_path, proj_path)
if not os.path.isabs(rel_struct):
analysis_attrs["structs_path"] = rel_struct.replace("\\", "/")
@ -919,6 +918,5 @@ def run_scan(proj_path, makefile_path, output_xml, verbose=2):
print("[XML] Creating vars.xml...")
generate_xml_output(proj_path, output_xml, vars, includes, externs, structs_xml, makefile_path)
print("Progress: 2/2")
print('Progress: "Done"')
print('Progress: 1/1')
print("Progress: 2/2")

View File

@ -190,24 +190,44 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
return []
# Вспомогательная функция для обработки массивов
def process_array(prefix, base_type, dims):
array_tree = generate_array_names(prefix, dims)
array_flat = flatten_array_tree(array_tree)
for node in array_flat:
sub_items = expand_struct_recursively(node['name'], base_type, structs, typedefs, var_attrs, depth + 1)
if sub_items:
node['children'] = sub_items
def process_array(prefix, type_str, structs, typedefs, var_attrs, depth=0):
base_type, array_dims = parse_array_dims(type_str)
if not array_dims:
return []
# На текущем уровне берем первый размер массива
current_dim = array_dims[0]
# Оставшиеся размеры — все, кроме первого
remaining_dims = array_dims[1:]
# Для создания типа с оставшимися размерами:
if remaining_dims:
# Формируем строку типа для оставшихся измерений массива, например int[16]
remaining_type_str = f"{base_type}{''.join(f'[{d}]' for d in remaining_dims)}"
else:
node.update({
'type': base_type,
remaining_type_str = base_type
array_tree = []
for i in range(current_dim):
name = f"{prefix}[{i}]"
# Для каждого элемента передаем уже оставшийся тип массива
children = expand_struct_recursively(name, remaining_type_str, structs, typedefs, var_attrs, depth + 1)
node = {
'name': name,
'type': remaining_type_str if remaining_dims else base_type,
'pt_type': '',
'iq_type': '',
'return_type': '',
'file': var_attrs.get('file'),
'extern': var_attrs.get('extern'),
'static': var_attrs.get('static'),
})
return array_flat
}
if children:
node['children'] = children
array_tree.append(node)
return array_tree
# Если type_str — уже распарсенная структура (dict)
if isinstance(type_str, dict):
@ -216,7 +236,7 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
# Проверяем, массив ли это
base_type, array_dims = parse_array_dims(type_str)
if array_dims:
return process_array(prefix, base_type, array_dims)
return process_array(prefix, type_str, structs, typedefs, var_attrs, depth)
# Ищем структуру по имени типа
base_type = scanVars.strip_ptr_and_array(type_str)
@ -289,13 +309,9 @@ def expand_struct_recursively(prefix, type_str, structs, typedefs, var_attrs, de
if "(" in field_type_str and "*" in field_type_str and ")" in field_type_str:
continue
# Проверим, является ли тип структурой (по имени)
clean_type = scanVars.strip_ptr_and_array(field_type_str)
struct_fields = structs.get(clean_type)
if isinstance(struct_fields, dict):
if isinstance(field_value, dict):
# Это одиночная структура — раскрываем рекурсивно
sub_items = expand_struct_recursively(full_name, field_type_str, structs, typedefs, var_attrs, depth + 1)
sub_items = expand_struct_recursively(full_name, field_value, structs, typedefs, var_attrs, depth + 1)
child = {
'name': full_name,
'type': field_type_str,

View File

View File

@ -2,27 +2,132 @@
#include "IQmathLib.h"
static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var);
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var, DebugVarIQType_t iq_type_final);
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var);
DebugVarIQType_t dbg_type = t_iq24;
long Debug_ReadVar(DebugVar_t *var, DebugVarIQType_t iq_type_final)
int Debug_LowLevel_ReadVar(DebugVar_t *var_ll, long *return_long)
{
long tmp_var;
if((var->ptr_type == pt_struct) || (var->ptr_type == pt_union) || (var->ptr_type == pt_unknown))
return;
if (var_ll == NULL)
return 1;
convertDebugVarToIQx(var, &tmp_var, dbg_type);
return tmp_var;
char *addr = var_ll->Ptr;
unsigned long addr_val = (unsigned long)addr;
// Ðàçðåø¸ííûå äèàïàçîíû ïàìÿòè íà TMS320F2812
if (!(
(addr_val <= 0x0007FF) || // RAMM0 + RAMM1
(addr_val >= 0x008000 && addr_val <= 0x009FFF) || // L0 + L1 SARAM
(addr_val >= 0x3F8000 && addr_val <= 0x3F9FFF) || // PRAMH0 + DRAMH0
(addr_val >= 0x3D8000 && addr_val <= 0x3EFFFF) || // Flash A-F
(addr_val >= 0x3FF000 && addr_val <= 0x3FFFFF) // Boot ROM / Reset
)) {
return 2; // àäðåñ âíå äîïóñòèìîãî äèàïàçîíà, èãíîðèðóåì
}
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var, DebugVarIQType_t iq_type_final)
convertDebugVarToIQx(var_ll, return_long);
return 0;
}
int Debug_ReadVar(DebugVar_t *var, long *return_long)
{
long tmp_var;
if (var == NULL)
return 1;
if((var->ptr_type == pt_struct) || (var->ptr_type == pt_union) ||
(var->ptr_type == pt_unknown) || (var->return_type == pt_unknown))
return 1;
convertDebugVarToIQx(var, return_long);
return 0;
}
int Debug_ReadVarName(DebugVar_t *var, char *name_ptr)
{
if((var == NULL)||(name_ptr == NULL))
return 1;
int i;
// Êîïèðîâàíèå ñ çàùèòîé îò ïåðåïîëíåíèÿ è ÿâíîé îñòàíîâêîé ïî '\0'
for (i = 0; i < sizeof(var->name); i++)
{
name_ptr[i] = var->name[i];
if (var->name[i] == '\0')
break;
}
// Ãàðàíòèðîâàííîå çàâåðøåíèå ñòðîêè (íà ñëó÷àé, åñëè â var->name íå áûëî '\0')
name_ptr[sizeof(var->name) - 1] = '\0';
return 0;
}
int Debug_LowLevel_Initialize(const uint8_t* external_date)
{
if (external_date == NULL) {
return -1;
}
// Ïðåîáðàçóåì external_date â ñòðóêòóðó
DateTimeHex ext;
ext.year = (external_date[0] << 8) | external_date[1];
ext.month = external_date[2];
ext.day = external_date[3];
ext.hour = external_date[4];
ext.minute = external_date[5];
// Ïàðñèì BUILD_FULL_DATE "YYYYMMDD_HHMM"
DateTimeHex build;
char buf[5] = {0};
// Ãîä
memcpy(buf, BUILD_FULL_DATE + 0, 4);
build.year = (uint16_t)atoi(buf);
// Ìåñÿö
memcpy(buf, BUILD_FULL_DATE + 4, 2);
build.month = (uint8_t)atoi(buf);
// Äåíü
memcpy(buf, BUILD_FULL_DATE + 6, 2);
build.day = (uint8_t)atoi(buf);
// ×àñ
memcpy(buf, BUILD_FULL_DATE + 9, 2);
build.hour = (uint8_t)atoi(buf);
// Ìèíóòû
memcpy(buf, BUILD_FULL_DATE + 11, 2);
build.minute = (uint8_t)atoi(buf);
// Ñðàâíåíèå âñåõ ïîëåé
if (ext.year == build.year &&
ext.month == build.month &&
ext.day == build.day &&
ext.hour == build.hour &&
ext.minute == build.minute)
{
return 0; // Ñîâïàëî
}
return 1; // Íå ñîâïàëî
}
/////////////////////----INTERNAL FUNCTIONS-----////////////////////////
static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var)
{
long iq_numb, iq_united, iq_final;
float float_numb;
if(getDebugVar(var, &iq_numb, &float_numb) == 1)
if(getDebugVar(var, &iq_numb, &float_numb) != 0)
return 1;
// ïðèâåäåíèå ê îäíîìó IQ
@ -131,7 +236,7 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var, DebugVarIQType_t
}
// ïðèâåäåíèå îáùåãî IQ ê çàïðàøèâàåìîìó
switch(iq_type_final)
switch(var->return_type)
{
case t_iq_none:
iq_final = (int)_IQtoF(iq_united);
@ -233,42 +338,53 @@ static int convertDebugVarToIQx(DebugVar_t *var, long *ret_var, DebugVarIQType_t
}
static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var)
{
if (!var || !int_var || !float_var)
if (!var || !int_var || !float_var || !var->Ptr)
return 1; // îøèáêà: null óêàçàòåëü
char *addr = var->Ptr;
unsigned long addr_val = (unsigned long)addr;
switch (var->ptr_type)
{
case pt_int8: // signed char
*int_var = *((signed char *)var->Ptr);
case pt_int8: // 8 áèò
case pt_uint8:
// âûðàâíèâàíèå íå íóæíî äëÿ 8 áèò
*int_var = *((volatile char *)addr);
break;
case pt_int16: // int
*int_var = *((int *)var->Ptr);
case pt_int16: // 16 áèò (int)
case pt_uint16:
if (addr_val & 0x1) // ïðîâåðêà âûðàâíèâàíèÿ ïî 2 áàéòàì
return 2; // îøèáêà âûðàâíèâàíèÿ
*int_var = *((volatile int *)addr);
break;
case pt_int32: // long
*int_var = *((long *)var->Ptr);
case pt_int32: // 32 áèò (long)
case pt_uint32:
if (addr_val & 0x3) // ïðîâåðêà âûðàâíèâàíèÿ ïî 4 áàéòàì
return 3; // îøèáêà âûðàâíèâàíèÿ
*int_var = *((volatile long *)addr);
break;
case pt_uint8: // unsigned char
*int_var = *((unsigned char *)var->Ptr);
break;
case pt_uint16: // unsigned int
*int_var = *((unsigned int *)var->Ptr);
break;
case pt_uint32: // unsigned long
*int_var = *((unsigned long *)var->Ptr);
break;
case pt_float: // float
*float_var = *((float *)var->Ptr);
// case pt_int64: // 64 áèò (long long)
// case pt_uint64:
// if (addr_val & 0x7) // ïðîâåðêà âûðàâíèâàíèÿ ïî 8 áàéòàì
// return 2; // îøèáêà âûðàâíèâàíèÿ
// // Òóò ïðîñòî ÷èòàåì, íî long long ìîæåò íå ïîìåñòèòüñÿ â *int_var
// // Ìîæíî çàìåíèòü ëîãèêó ïîä 64-áèòíîå ÷òåíèå ïðè íåîáõîäèìîñòè
// *int_var = *((volatile long long *)addr);
// break;
case pt_float: // float (4 áàéòà)
if (addr_val & 0x3) // ïðîâåðêà âûðàâíèâàíèÿ ïî 4 áàéòàì
return 4; // îøèáêà âûðàâíèâàíèÿ
*float_var = *((volatile float *)addr);
break;
default:
return 1; // íåïîääåðæèâàåìûé òèï
// äëÿ óêàçàòåëåé è ìàññèâîâ íå ïîääåðæèâàåòñÿ ÷òåíèå
// case pt_ptr_int8:
// case pt_ptr_int16:
@ -282,8 +398,6 @@ static int getDebugVar(DebugVar_t *var, long *int_var, float *float_var)
// case pt_arr_uint8:
// case pt_arr_uint16:
// case pt_arr_uint32:
default:
return 1;
}
return 0; // óñïåõ

View File

@ -9,9 +9,11 @@ typedef enum
pt_int8, // signed char
pt_int16, // int
pt_int32, // long
pt_int64, // long
pt_uint8, // unsigned char
pt_uint16, // unsigned int
pt_uint32, // unsigned long
pt_uint64, // unsigned long
pt_float, // float
pt_struct, // struct
pt_union, // struct
@ -70,12 +72,25 @@ typedef struct
char* Ptr;
DebugVarPtrType_t ptr_type;
DebugVarIQType_t iq_type;
char name[10];
DebugVarIQType_t return_type;
char name[11]; // 10 ñèìâîëîâ + '\0'
}DebugVar_t;
typedef struct {
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
} DateTimeHex;
extern int DebugVar_Qnt;
extern DebugVar_t dbg_vars[];
long Debug_ReadVar(DebugVar_t *var, DebugVarIQType_t iq_type_final);
int Debug_LowLevel_ReadVar(DebugVar_t *var_ll, long *return_long);
int Debug_ReadVar(DebugVar_t *var, long *return_long);
int Debug_ReadVarName(DebugVar_t *var, char *name_ptr);
#endif //DEBUG_TOOLS

View File

@ -3,33 +3,33 @@
// Èíêëþäû äëÿ äîñòóïà ê ïåðåìåííûì
#include "vector.h"
#include "f281xpwm.h"
#include "log_can.h"
#include "RS_Functions_modbus.h"
#include "errors.h"
#include "pwm_vector_regul.h"
#include "xp_project.h"
#include "xp_write_xpwm_time.h"
#include "teta_calc.h"
#include "vector.h"
#include "v_pwm24.h"
#include "errors.h"
#include "dq_to_alphabeta_cos.h"
#include "log_can.h"
#include "f281xpwm.h"
#include "pwm_vector_regul.h"
#include "adc_tools.h"
#include "rotation_speed.h"
#include "dq_to_alphabeta_cos.h"
#include "teta_calc.h"
#include "CAN_Setup.h"
#include "log_to_memory.h"
#include "log_params.h"
#include "CRC_Functions.h"
#include "global_time.h"
#include "RS_Functions.h"
#include "detect_phase_break2.h"
#include "x_parallel_bus.h"
#include "x_serial_bus.h"
#include "Spartan2E_Functions.h"
#include "xp_controller.h"
#include "xPeriphSP6_loader.h"
#include "xp_rotation_sensor.h"
#include "x_serial_bus.h"
#include "Spartan2E_Functions.h"
#include "x_parallel_bus.h"
#include "svgen_dq.h"
#include "detect_phase_break2.h"
#include "log_to_memory.h"
#include "CRC_Functions.h"
#include "global_time.h"
#include "CAN_Setup.h"
#include "log_params.h"
#include "pid_reg3.h"
#include "IQmathLib.h"
#include "doors_control.h"
@ -314,9 +314,26 @@ extern int zero_ADC[20];
// Îïðåäåëåíèå ìàññèâà ñ óêàçàòåëÿìè íà ïåðåìåííûå äëÿ îòëàäêè
int DebugVar_Qnt = 2;
int DebugVar_Qnt = 19;
#pragma DATA_SECTION(dbg_vars,".dbgvar_info")
DebugVar_t dbg_vars[] = {\
{(char *)&ADC0finishAddr, pt_uint8, t_iq7, pt_uint8, "asdasjjjjj" }, \
{(char *)&project.cds_tk.count_elements_pbus, pt_uint16, t_iq_none, pt_uint16, "project.cd" }, \
{(char *)&ADC1startAddr, pt_int16, t_iq_none, pt_int16, "ADC1StrAdr" }, \
{(char *)&project.cds_tk[0].plane_address, pt_uint16, t_iq_none, pt_uint16, "tk0_Adr" }, \
{(char *)&ADC_sf[0][0], pt_int16, t_iq_none, pt_int16, "ADC_sf00" }, \
{(char *)&ADC_sf[0][1], pt_int16, t_iq_none, pt_int16, "ADC_sf01" }, \
{(char *)&ADC_sf[0][2], pt_int16, t_iq_none, pt_int16, "ADC_sf02" }, \
{(char *)&ADC_sf[0][3], pt_int16, t_iq_none, pt_int16, "ADC_sf03" }, \
{(char *)&ADC_sf[0][4], pt_int16, t_iq_none, pt_int16, "ADC_sf04" }, \
{(char *)&ADC_sf[0][5], pt_int16, t_iq_none, pt_int16, "ADC_sf05" }, \
{(char *)&ADC_sf[0][6], pt_int16, t_iq_none, pt_int16, "ADC_sf06" }, \
{(char *)&ADC_sf[0][7], pt_int16, t_iq_none, pt_int16, "ADC_sf07" }, \
{(char *)&ADC_sf[0][8], pt_int16, t_iq_none, pt_int16, "ADC_sf08" }, \
{(char *)&ADC_sf[0][9], pt_int16, t_iq_none, pt_int16, "ADC_sf09" }, \
{(char *)&ADC_sf[0][10], pt_int16, t_iq_none, pt_int16, "ADC_sf010" }, \
{(char *)&ADC_sf[0][11], pt_int16, t_iq_none, pt_int16, "ADC_sf011" }, \
{(char *)&ADC_sf[0][12], pt_int16, t_iq_none, pt_int16, "ADC_sf012" }, \
{(char *)&ADC_sf[0][13], pt_int16, t_iq_none, pt_int16, "ADC_sf013" }, \
{(char *)&ADC_sf[0][14], pt_int16, t_iq_none, pt_int16, "ADC_sf014" }, \
{(char *)&ADC_sf[0][15], pt_int16, t_iq_none, pt_int16, "ADC_sf015" }, \
{(char *)&project.cds_tk[0].read.sbus.mask_protect_tk.all, pt_uint16, t_iq_none, pt_uint16, "project.cd" }, \
};

File diff suppressed because it is too large Load Diff

1108
vars.xml

File diff suppressed because it is too large Load Diff