Сохранить русские комментарии и настройки проекта в UTF-8
Добавить пояснения к исходникам, заголовкам TI, настройкам CCS и существующим проверкам. Зафиксировать правила кодировки, обзор модулей и аудит комментариев.
This commit is contained in:
262
tests/comments/run_test.py
Normal file
262
tests/comments/run_test.py
Normal file
@@ -0,0 +1,262 @@
|
||||
# Проверка comments на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Проверка UTF-8 и русских пояснений к каждой строке исходного кода."""; порядок аргументов сохраняется.
|
||||
"""Проверка UTF-8 и русских пояснений к каждой строке исходного кода."""
|
||||
# Подключает модуль argparse для этой проверки или подготовки сборки.
|
||||
import argparse
|
||||
# Подключает модуль io для этой проверки или подготовки сборки.
|
||||
import io
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль re для этой проверки или подготовки сборки.
|
||||
import re
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль tokenize для этой проверки или подготовки сборки.
|
||||
import tokenize
|
||||
|
||||
# Задаёт ROOT по выражению справа; значение используется последующими операциями.
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
# Задаёт RUSSIAN по выражению справа; значение используется последующими операциями.
|
||||
RUSSIAN = re.compile("[А-Яа-яЁё]")
|
||||
# Задаёт C_SUFFIXES по выражению справа; значение используется последующими операциями.
|
||||
C_SUFFIXES = {".c", ".h", ".cmd", ".inc"}
|
||||
# Задаёт TEXT_SUFFIXES по выражению справа; значение используется последующими операциями.
|
||||
TEXT_SUFFIXES = C_SUFFIXES | {".asm", ".py", ".md", ".bat", ".old", ".prefs", ".json", ".pjt", ".lkf"}
|
||||
# Задаёт TEXT_NAMES по выражению справа; значение используется последующими операциями.
|
||||
TEXT_NAMES = {".project", ".cproject", ".ccsproject", ".gitignore", ".editorconfig"}
|
||||
|
||||
# Объявляет функцию c_code_lines и её входные параметры.
|
||||
def c_code_lines(text):
|
||||
# Задаёт block по выражению справа; значение используется последующими операциями.
|
||||
block = False
|
||||
# Перебирает line in text.splitlines() в указанном порядке.
|
||||
for line in text.splitlines():
|
||||
# Задаёт out по выражению справа; значение используется последующими операциями.
|
||||
out = []
|
||||
# Задаёт i по выражению справа; значение используется последующими операциями.
|
||||
i = 0
|
||||
# Задаёт quote по выражению справа; значение используется последующими операциями.
|
||||
quote = None
|
||||
# Повторяет блок при выполнении i < len(line).
|
||||
while i < len(line):
|
||||
# Проверяет условие if block перед выполнением следующего блока.
|
||||
if block:
|
||||
# Задаёт end по выражению справа; значение используется последующими операциями.
|
||||
end = line.find("*/", i)
|
||||
# Проверяет условие if end < 0 перед выполнением следующего блока.
|
||||
if end < 0:
|
||||
# Продолжает текущий вызов, список или выражение: break; порядок аргументов сохраняется.
|
||||
break
|
||||
# Задаёт block по выражению справа; значение используется последующими операциями.
|
||||
block = False
|
||||
# Задаёт i по выражению справа; значение используется последующими операциями.
|
||||
i = end + 2
|
||||
# Продолжает текущий вызов, список или выражение: out.append(" "); порядок аргументов сохраняется.
|
||||
out.append(" ")
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Задаёт c по выражению справа; значение используется последующими операциями.
|
||||
c = line[i]
|
||||
# Проверяет условие if quote перед выполнением следующего блока.
|
||||
if quote:
|
||||
# Продолжает текущий вызов, список или выражение: out.append(c); порядок аргументов сохраняется.
|
||||
out.append(c)
|
||||
# Проверяет условие if c == "\\" and i + 1 < len(line) перед выполнением следующего блока.
|
||||
if c == "\\" and i + 1 < len(line):
|
||||
# Задаёт i + по выражению справа; значение используется последующими операциями.
|
||||
i += 1
|
||||
# Продолжает текущий вызов, список или выражение: out.append(line[i]); порядок аргументов сохраняется.
|
||||
out.append(line[i])
|
||||
# Проверяет условие elif c == quote перед выполнением следующего блока.
|
||||
elif c == quote:
|
||||
# Задаёт quote по выражению справа; значение используется последующими операциями.
|
||||
quote = None
|
||||
# Задаёт i + по выражению справа; значение используется последующими операциями.
|
||||
i += 1
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Проверяет условие if line.startswith("//", i) перед выполнением следующего блока.
|
||||
if line.startswith("//", i):
|
||||
# Продолжает текущий вызов, список или выражение: break; порядок аргументов сохраняется.
|
||||
break
|
||||
# Проверяет условие if line.startswith("/*", i) перед выполнением следующего блока.
|
||||
if line.startswith("/*", i):
|
||||
# Задаёт block по выражению справа; значение используется последующими операциями.
|
||||
block = True
|
||||
# Задаёт i + по выражению справа; значение используется последующими операциями.
|
||||
i += 2
|
||||
# Продолжает текущий вызов, список или выражение: out.append(" "); порядок аргументов сохраняется.
|
||||
out.append(" ")
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Проверяет условие if c in "\"'" перед выполнением следующего блока.
|
||||
if c in "\"'":
|
||||
# Задаёт quote по выражению справа; значение используется последующими операциями.
|
||||
quote = c
|
||||
# Продолжает текущий вызов, список или выражение: out.append(c); порядок аргументов сохраняется.
|
||||
out.append(c)
|
||||
# Задаёт i + по выражению справа; значение используется последующими операциями.
|
||||
i += 1
|
||||
# Продолжает текущий вызов, список или выражение: yield "".join(out).strip(); порядок аргументов сохраняется.
|
||||
yield "".join(out).strip()
|
||||
|
||||
# Объявляет функцию python_code_lines и её входные параметры.
|
||||
def python_code_lines(text):
|
||||
# Задаёт active по выражению справа; значение используется последующими операциями.
|
||||
active = set()
|
||||
# Задаёт strings по выражению справа; значение используется последующими операциями.
|
||||
strings = set()
|
||||
# Перебирает token in tokenize.generate_tokens(io.StringIO(text).readline) в указанном порядке.
|
||||
for token in tokenize.generate_tokens(io.StringIO(text).readline):
|
||||
# Проверяет условие if token.type == tokenize.STRING and token.end[0] > token.start[0] перед выполнением следующего блока.
|
||||
if token.type == tokenize.STRING and token.end[0] > token.start[0]:
|
||||
# Продолжает текущий вызов, список или выражение: strings.update(range(token.start[0] + 1, token.end[0] + 1)); порядок аргументов сохраняется.
|
||||
strings.update(range(token.start[0] + 1, token.end[0] + 1))
|
||||
# Проверяет условие if token.type not in {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT, tokenize.ENDMARKER} перед выполнением следующего блока.
|
||||
if token.type not in {tokenize.COMMENT, tokenize.NL, tokenize.NEWLINE, tokenize.INDENT, tokenize.DEDENT, tokenize.ENDMARKER}:
|
||||
# Продолжает текущий вызов, список или выражение: active.add(token.start[0]); порядок аргументов сохраняется.
|
||||
active.add(token.start[0])
|
||||
# Задаёт lines по выражению справа; значение используется последующими операциями.
|
||||
lines = text.splitlines()
|
||||
# Возвращает [line.strip() if n in active and n not in strings else "" for n, line in enumerate(lines, 1)] вызывающему коду и завершает функцию.
|
||||
return [line.strip() if n in active and n not in strings else "" for n, line in enumerate(lines, 1)]
|
||||
|
||||
# Объявляет функцию audit и её входные параметры.
|
||||
def audit(path, text):
|
||||
# Задаёт lines по выражению справа; значение используется последующими операциями.
|
||||
lines = text.splitlines()
|
||||
# Проверяет условие if path.suffix in C_SUFFIXES перед выполнением следующего блока.
|
||||
if path.suffix in C_SUFFIXES:
|
||||
# Задаёт code по выражению справа; значение используется последующими операциями.
|
||||
code = list(c_code_lines(text))
|
||||
# Проверяет условие elif path.suffix == ".asm" перед выполнением следующего блока.
|
||||
elif path.suffix == ".asm":
|
||||
# Задаёт code по выражению справа; значение используется последующими операциями.
|
||||
code = [line.split(";")[0].strip() for line in lines]
|
||||
# Проверяет условие elif path.suffix == ".py" перед выполнением следующего блока.
|
||||
elif path.suffix == ".py":
|
||||
# Задаёт code по выражению справа; значение используется последующими операциями.
|
||||
code = python_code_lines(text)
|
||||
# Обрабатывает альтернативу предыдущего условия.
|
||||
else:
|
||||
# Возвращает 0, [] вызывающему коду и завершает функцию.
|
||||
return 0, []
|
||||
# Задаёт missing по выражению справа; значение используется последующими операциями.
|
||||
missing = []
|
||||
# Задаёт count по выражению справа; значение используется последующими операциями.
|
||||
count = 0
|
||||
# Перебирает i, value in enumerate(code) в указанном порядке.
|
||||
for i, value in enumerate(code):
|
||||
# Проверяет условие if not value перед выполнением следующего блока.
|
||||
if not value:
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Задаёт count + по выражению справа; значение используется последующими операциями.
|
||||
count += 1
|
||||
# Проверяет условие if RUSSIAN.search(lines[i]) or (i and RUSSIAN.search(lines[i-1])) перед выполнением следующего блока.
|
||||
if RUSSIAN.search(lines[i]) or (i and RUSSIAN.search(lines[i-1])):
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Явное продолжение Python-выражения относится к пояснённой начальной строке.
|
||||
# Проверяет условие if path.suffix == ".py" and i and lines[i-1].rstrip().endswith("\\") перед выполнением следующего блока.
|
||||
if path.suffix == ".py" and i and lines[i-1].rstrip().endswith("\\"):
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Продолжает текущий вызов, список или выражение: missing.append(i+1); порядок аргументов сохраняется.
|
||||
missing.append(i+1)
|
||||
# Возвращает count, missing вызывающему коду и завершает функцию.
|
||||
return count, missing
|
||||
|
||||
# Объявляет функцию main и её входные параметры.
|
||||
def main():
|
||||
# Задаёт parser по выражению справа; значение используется последующими операциями.
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
# Задаёт parser.add_argument("--report", type по выражению справа; значение используется последующими операциями.
|
||||
parser.add_argument("--report", type=Path, help="Сохранить таблицу покрытия в Markdown")
|
||||
# Задаёт args по выражению справа; значение используется последующими операциями.
|
||||
args = parser.parse_args()
|
||||
# Задаёт names по выражению справа; значение используется последующими операциями.
|
||||
names = subprocess.check_output(["git", "ls-files", "-z"], cwd=ROOT).decode("utf-8").split("\0")
|
||||
# Задаёт names по выражению справа; значение используется последующими операциями.
|
||||
names = sorted(set(filter(None, names)) | {"tests/comments/run_test.py", ".editorconfig"})
|
||||
# Задаёт rows по выражению справа; значение используется последующими операциями.
|
||||
rows = []
|
||||
# Задаёт errors по выражению справа; значение используется последующими операциями.
|
||||
errors = []
|
||||
# Задаёт checked по выражению справа; значение используется последующими операциями.
|
||||
checked = 0
|
||||
# Перебирает name in names в указанном порядке.
|
||||
for name in names:
|
||||
# Задаёт path по выражению справа; значение используется последующими операциями.
|
||||
path = ROOT / name
|
||||
# Проверяет условие if path.suffix.lower() not in TEXT_SUFFIXES and path.name not in TEXT_NAMES перед выполнением следующего блока.
|
||||
if path.suffix.lower() not in TEXT_SUFFIXES and path.name not in TEXT_NAMES:
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Начинает блок обработки возможной ошибки.
|
||||
try:
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
text = path.read_text(encoding="utf-8")
|
||||
# Перехватывает указанный тип ошибки и выполняет обработку.
|
||||
except UnicodeError as error:
|
||||
# Продолжает текущий вызов, список или выражение: errors.append(f"{name}: неверная кодировка UTF-8: {error}"); порядок аргументов сохраняется.
|
||||
errors.append(f"{name}: неверная кодировка UTF-8: {error}")
|
||||
# Продолжает текущий вызов, список или выражение: continue; порядок аргументов сохраняется.
|
||||
continue
|
||||
# Задаёт checked + по выражению справа; значение используется последующими операциями.
|
||||
checked += 1
|
||||
# Задаёт count, missing по выражению справа; значение используется последующими операциями.
|
||||
count, missing = audit(path, text)
|
||||
# Проверяет условие if missing перед выполнением следующего блока.
|
||||
if missing:
|
||||
# Продолжает текущий вызов, список или выражение: errors.append(f"{name}: нет русского пояснения, строки {missing[:20]}"); порядок аргументов сохраняется.
|
||||
errors.append(f"{name}: нет русского пояснения, строки {missing[:20]}")
|
||||
# Проверяет условие if path.suffix in C_SUFFIXES or path.suffix in {".asm", ".py"} перед выполнением следующего блока.
|
||||
if path.suffix in C_SUFFIXES or path.suffix in {".asm", ".py"}:
|
||||
# Продолжает текущий вызов, список или выражение: rows.append((name, count, count-len(missing))); порядок аргументов сохраняется.
|
||||
rows.append((name, count, count-len(missing)))
|
||||
# Проверяет условие if args.report перед выполнением следующего блока.
|
||||
if args.report:
|
||||
# Задаёт report по выражению справа; значение используется последующими операциями.
|
||||
report = [
|
||||
# Продолжает текущий вызов, список или выражение: "# Проверка комментариев и кодировки",; порядок аргументов сохраняется.
|
||||
"# Проверка комментариев и кодировки",
|
||||
# Продолжает текущий вызов, список или выражение: "",; порядок аргументов сохраняется.
|
||||
"",
|
||||
# Продолжает текущий вызов, список или выражение: "Проверка относится к редактируемым исходникам C/H, ASM, CMD, тестовым INC и Python.",; порядок аргументов сохраняется.
|
||||
"Проверка относится к редактируемым исходникам C/H, ASM, CMD, тестовым INC и Python.",
|
||||
# Продолжает текущий вызов, список или выражение: "Каждая непустая строка кода имеет русское пояснение перед ней или на ней. Пустые строки,",; порядок аргументов сохраняется.
|
||||
"Каждая непустая строка кода имеет русское пояснение перед ней или на ней. Пустые строки,",
|
||||
# Продолжает текущий вызов, список или выражение: "текст существующих комментариев и содержимое многострочных строк данных не считаются кодом.",; порядок аргументов сохраняется.
|
||||
"текст существующих комментариев и содержимое многострочных строк данных не считаются кодом.",
|
||||
# Продолжает текущий вызов, список или выражение: "Исходные уведомления TI сохранены. JSON-паспорта, индексы IDE, таблицы XLS и двоичные",; порядок аргументов сохраняется.
|
||||
"Исходные уведомления TI сохранены. JSON-паспорта, индексы IDE, таблицы XLS и двоичные",
|
||||
# Продолжает текущий вызов, список или выражение: "результаты сборки не допускают исходных комментариев; их назначение описано в документации.",; порядок аргументов сохраняется.
|
||||
"результаты сборки не допускают исходных комментариев; их назначение описано в документации.",
|
||||
# Продолжает текущий вызов, список или выражение: "",; порядок аргументов сохраняется.
|
||||
"",
|
||||
# Продолжает текущий вызов, список или выражение: f"UTF-8 проверен в {checked} текстовых файлах. Строк кода: {sum(r[1] for r in rows)}.",; порядок аргументов сохраняется.
|
||||
f"UTF-8 проверен в {checked} текстовых файлах. Строк кода: {sum(r[1] for r in rows)}.",
|
||||
# Продолжает текущий вызов, список или выражение: "",; порядок аргументов сохраняется.
|
||||
"",
|
||||
# Продолжает текущий вызов, список или выражение: "| Файл | Строк кода | С русским пояснением |",; порядок аргументов сохраняется.
|
||||
"| Файл | Строк кода | С русским пояснением |",
|
||||
# Продолжает текущий вызов, список или выражение: "| --- | ---: | ---: |",; порядок аргументов сохраняется.
|
||||
"| --- | ---: | ---: |",
|
||||
# Продолжает текущий вызов, список или выражение: ]; порядок аргументов сохраняется.
|
||||
]
|
||||
# Задаёт report + по выражению справа; значение используется последующими операциями.
|
||||
report += [f"| {name} | {count} | {covered} |" for name,count,covered in rows]
|
||||
# Сохраняет подготовленный файл в указанном формате для следующего шага.
|
||||
args.report.write_text("\n".join(report)+"\n", encoding="utf-8")
|
||||
# Проверяет условие if errors перед выполнением следующего блока.
|
||||
if errors:
|
||||
# Останавливает текущую операцию с исключением SystemExit("\n".join(errors)).
|
||||
raise SystemExit("\n".join(errors))
|
||||
# Продолжает текущий вызов, список или выражение: print(f"PASS UTF-8: {checked} files; Russian comments: {len(rows)} source files, {sum(r[1] for r in rows)} code lines"); порядок аргументов сохраняется.
|
||||
print(f"PASS UTF-8: {checked} files; Russian comments: {len(rows)} source files, {sum(r[1] for r in rows)} code lines")
|
||||
|
||||
# Проверяет условие if __name__ == "__main__" перед выполнением следующего блока.
|
||||
if __name__ == "__main__":
|
||||
# Продолжает текущий вызов, список или выражение: main(); порядок аргументов сохраняется.
|
||||
main()
|
||||
@@ -1,21 +1,42 @@
|
||||
# Проверка eeprom_profiles на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Check SPI wire address widths for both production EEPROM configurations."""; порядок аргументов сохраняется.
|
||||
"""Check SPI wire address widths for both production EEPROM configurations."""
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль os для этой проверки или подготовки сборки.
|
||||
import os
|
||||
# Подключает модуль shutil для этой проверки или подготовки сборки.
|
||||
import shutil
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
|
||||
# Задаёт root по выражению справа; значение используется последующими операциями.
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
# Задаёт protocol по выражению справа; значение используется последующими операциями.
|
||||
protocol = root.parent / 'newProject/SETGUI/third_party/templates/c/set-protocol'
|
||||
# Задаёт compiler по выражению справа; значение используется последующими операциями.
|
||||
compiler = os.environ.get('CC') or shutil.which('gcc') or 'C:/msys64/mingw64/bin/gcc.exe'
|
||||
# Задаёт os.environ['PATH'] по выражению справа; значение используется последующими операциями.
|
||||
os.environ['PATH'] = str(Path(compiler).resolve().parent) + os.pathsep + os.environ['PATH']
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory() as folder с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
# Перебирает profile in (0, 1) в указанном порядке.
|
||||
for profile in (0, 1):
|
||||
# Задаёт exe по выражению справа; значение используется последующими операциями.
|
||||
exe = Path(folder) / f'spi{profile}.exe'
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([compiler, '-std=c99',
|
||||
# Задаёт f'-DEEPROM_M95M02 по выражению справа; значение используется последующими операциями.
|
||||
f'-DEEPROM_M95M02={profile}', '-Itests/eeprom_profiles/stubs',
|
||||
# Продолжает текущий вызов, список или выражение: '-ISource/Internal/Include', '-I' + str(protocol),; порядок аргументов сохраняется.
|
||||
'-ISource/Internal/Include', '-I' + str(protocol),
|
||||
# Продолжает текущий вызов, список или выражение: 'tests/eeprom_profiles/spi_test.c', '-o', str(exe)],; порядок аргументов сохраняется.
|
||||
'tests/eeprom_profiles/spi_test.c', '-o', str(exe)],
|
||||
# Задаёт cwd по выражению справа; значение используется последующими операциями.
|
||||
cwd=root, check=True)
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([str(exe)], check=True, timeout=10)
|
||||
# Продолжает текущий вызов, список или выражение: print(f'PASS SPI profile {profile}'); порядок аргументов сохраняется.
|
||||
print(f'PASS SPI profile {profile}')
|
||||
|
||||
@@ -1,47 +1,93 @@
|
||||
/* Проверка eeprom_profiles на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Exercise the production Timer2 SPI state machine; no hardware writes. */
|
||||
/* Подключает <assert.h>: настройки и интерфейс assert. */
|
||||
#include <assert.h>
|
||||
/* Подключает "../../Source/Internal/spise2p.c": драйвер SPI EEPROM, адресация, страницы и автомат завершения операций. */
|
||||
#include "../../Source/Internal/spise2p.c"
|
||||
/* Продолжает список аргументов, полей или выражение static unsigned trace[300], widths[300], used;; порядок элементов сохраняется. */
|
||||
static unsigned trace[300], widths[300], used;
|
||||
/* Начинает функцию transfer; назначение модуля — проверка eeprom_profiles на модели ПК. */
|
||||
static void transfer(unsigned long address, int write)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает buf[2] значением {0x1234,0x5678}, i; данные buf. */
|
||||
unsigned buf[2]={0x1234,0x5678}, i;
|
||||
/* Записывает message значением {buf,2,address}; данные message. */
|
||||
SE2P_DATA message={buf,2,address};
|
||||
/* Записывает used значением 0; данные used. */
|
||||
used=0;
|
||||
/* Проверяет if(write) spiSe2pWrite(&se2p,&message); else spiSe2pRead(&se2p,&message); последующий оператор выполняется только при истинном условии. */
|
||||
if(write) spiSe2pWrite(&se2p,&message); else spiSe2pRead(&se2p,&message);
|
||||
/* Цикл for(i=0;i<100 && !spiSe2pFree(&se2p);i++) ; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(i=0;i<100 && !spiSe2pFree(&se2p);i++) {
|
||||
/* Записывает SpiaRegs.SPITXBUF значением 0xdead; данные SPITXBUF. */
|
||||
SpiaRegs.SPITXBUF=0xdead;
|
||||
SpiaRegs.SPIRXBUF=0; /* WIP clear for write, deterministic read data. */
|
||||
SpiaRegs.SPIRXBUF=0; /* WIP clear for write, deterministic read data. */ /* Записывает SpiaRegs.SPIRXBUF значением 0; данные SPIRXBUF. */
|
||||
/* Записывает SpiaRegs.SPISTS.bit.INT_FLAG значением 1; INT флаг. */
|
||||
SpiaRegs.SPISTS.bit.INT_FLAG=1;
|
||||
/* Вызывает SPISE2P_DRV_tick. Продвигает неблокирующий автомат SPI EEPROM: команда, адрес, данные и ожидание завершения записи. */
|
||||
SPISE2P_DRV_tick(&se2p);
|
||||
/* Проверяет if(SpiaRegs.SPITXBUF!=0xdead); последующий оператор выполняется только при истинном условии. */
|
||||
if(SpiaRegs.SPITXBUF!=0xdead) {
|
||||
/* Вызывает assert с аргументами (GpioDataRegs.GPADAT.bit.GPIO19==0) в текущей последовательности операций. */
|
||||
assert(GpioDataRegs.GPADAT.bit.GPIO19==0);
|
||||
/* Записывает trace[used] значением SpiaRegs.SPITXBUF; данные trace. */
|
||||
trace[used]=SpiaRegs.SPITXBUF;
|
||||
/* Записывает widths[used++] значением (SpiaRegs.SPICCR.all&15)+1; данные widths. */
|
||||
widths[used++]=(SpiaRegs.SPICCR.all&15)+1;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Вызывает assert с аргументами (spiSe2pFree(&se2p) && GpioDataRegs.GPADAT.bit.GPIO19==1) в текущей последовательности операций. */
|
||||
assert(spiSe2pFree(&se2p) && GpioDataRegs.GPADAT.bit.GPIO19==1);
|
||||
/* Записывает i значением 0; данные i. */
|
||||
i=0;
|
||||
/* Проверяет if(write); последующий оператор выполняется только при истинном условии. */
|
||||
if(write) { assert(trace[i]==0x0600 && widths[i++]==8); }
|
||||
/* Вызывает assert с аргументами (trace[i]==(write ? 0x0200 : 0x0300) && widths[i++]==8) в текущей последовательности операций. */
|
||||
assert(trace[i]==(write ? 0x0200 : 0x0300) && widths[i++]==8);
|
||||
/* Условие компиляции EEPROM_M95M02: выбранный блок включается в текущий вариант прошивки. */
|
||||
#if EEPROM_M95M02
|
||||
/* Вызывает assert с аргументами (trace[i]==((address>>16)<<8) && widths[i++]==8) в текущей последовательности операций. */
|
||||
assert(trace[i]==((address>>16)<<8) && widths[i++]==8);
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
/* Вызывает assert с аргументами (trace[i]==(address&65535) && widths[i++]==16) в текущей последовательности операций. */
|
||||
assert(trace[i]==(address&65535) && widths[i++]==16);
|
||||
/* Вызывает assert с аргументами (trace[i]==(write ? 0x1234 : 0) && widths[i++]==16) в текущей последовательности операций. */
|
||||
assert(trace[i]==(write ? 0x1234 : 0) && widths[i++]==16);
|
||||
/* Вызывает assert с аргументами (trace[i]==(write ? 0x5678 : 0) && widths[i++]==16) в текущей последовательности операций. */
|
||||
assert(trace[i]==(write ? 0x5678 : 0) && widths[i++]==16);
|
||||
/* Проверяет if(write); последующий оператор выполняется только при истинном условии. */
|
||||
if(write) { assert(trace[i]==0x0500 && widths[i++]==8); assert(trace[i++]==0); }
|
||||
/* Вызывает assert с аргументами (i==used) в текущей последовательности операций. */
|
||||
assert(i==used);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||||
int main(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Вызывает SPISE2P_DRV_init с аргументами (&se2p) в текущей последовательности операций. */
|
||||
SPISE2P_DRV_init(&se2p);
|
||||
/* Вызывает transfer с аргументами (0x7ffc,0); transfer(0x7ffc,1) в текущей последовательности операций. */
|
||||
transfer(0x7ffc,0); transfer(0x7ffc,1);
|
||||
/* Условие компиляции EEPROM_M95M02: выбранный блок включается в текущий вариант прошивки. */
|
||||
#if EEPROM_M95M02
|
||||
/* Вызывает assert с аргументами (BALSAM167_EEPROM_FIRMWARE_BYTES==261884UL) в текущей последовательности операций. */
|
||||
assert(BALSAM167_EEPROM_FIRMWARE_BYTES==261884UL);
|
||||
/* Вызывает transfer с аргументами (0xfffe,0); transfer(0x10000,0) в текущей последовательности операций. */
|
||||
transfer(0xfffe,0); transfer(0x10000,0);
|
||||
/* Вызывает transfer с аргументами (0x20000,1); transfer(0x3fffc,0); transfer(0x3fffc,1) в текущей последовательности операций. */
|
||||
transfer(0x20000,1); transfer(0x3fffc,0); transfer(0x3fffc,1);
|
||||
/* Выбирает альтернативный блок текущего условия компиляции. */
|
||||
#else
|
||||
/* Вызывает assert с аргументами (BALSAM167_EEPROM_FIRMWARE_BYTES==32508) в текущей последовательности операций. */
|
||||
assert(BALSAM167_EEPROM_FIRMWARE_BYTES==32508);
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
/* Завершает main и возвращает 0. */
|
||||
return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,22 +1,45 @@
|
||||
/* Проверка eeprom_profiles/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Начинает условие: EEPROM_TEST_DEVICE_H ещё не определён; защищает повторное включение или задаёт значение сборки. */
|
||||
#ifndef EEPROM_TEST_DEVICE_H
|
||||
/* Определяет защитный символ или переключатель EEPROM_TEST_DEVICE_H для последующей компиляции. */
|
||||
#define EEPROM_TEST_DEVICE_H
|
||||
/* Подключает <stdint.h>: настройки и интерфейс stdint. */
|
||||
#include <stdint.h>
|
||||
/* Определяет защитный символ или переключатель interrupt для последующей компиляции. */
|
||||
#define interrupt
|
||||
/* Определяет защитный символ или переключатель EALLOW для последующей компиляции. */
|
||||
#define EALLOW
|
||||
/* Определяет защитный символ или переключатель EDIS для последующей компиляции. */
|
||||
#define EDIS
|
||||
/* Задаёт CLKMULT = 2; данные CLKMULT. */
|
||||
#define CLKMULT 2
|
||||
/* Задаёт SYSCLKOUT = 60000000UL; данные SYSCLKOUT. */
|
||||
#define SYSCLKOUT 60000000UL
|
||||
/* Задаёт M_INT14 = 0x2000; данные M_INT14. */
|
||||
#define M_INT14 0x2000
|
||||
/* Продолжает список аргументов, полей или выражение static unsigned IER;; порядок элементов сохраняется. */
|
||||
static unsigned IER;
|
||||
/* Описывает структуру bits; порядок полей определяет расположение данных. */
|
||||
struct bits { unsigned GPIO16,GPIO17,GPIO18,GPIO19,SPISWRESET,BUFFULL_FLAG,INT_FLAG; };
|
||||
/* Описывает структуру reg; порядок полей определяет расположение данных. */
|
||||
struct reg { unsigned all; struct bits bit; };
|
||||
/* Продолжает список аргументов, полей или выражение static struct { struct reg GPAMUX2,GPADIR; } GpioCtrlRegs;; порядок элементов сохраняется. */
|
||||
static struct { struct reg GPAMUX2,GPADIR; } GpioCtrlRegs;
|
||||
/* Продолжает список аргументов, полей или выражение static struct { struct reg GPADAT; } GpioDataRegs;; порядок элементов сохраняется. */
|
||||
static struct { struct reg GPADAT; } GpioDataRegs;
|
||||
/* Продолжает список аргументов, полей или выражение static struct { void (*TINT2)(void); } PieVectTable;; порядок элементов сохраняется. */
|
||||
static struct { void (*TINT2)(void); } PieVectTable;
|
||||
/* Продолжает список аргументов, полей или выражение static struct { unsigned InterruptCount; } CpuTimer2;; порядок элементов сохраняется. */
|
||||
static struct { unsigned InterruptCount; } CpuTimer2;
|
||||
/* Продолжает список аргументов, полей или выражение static struct { struct reg TCR; } CpuTimer2Regs;; порядок элементов сохраняется. */
|
||||
static struct { struct reg TCR; } CpuTimer2Regs;
|
||||
/* Продолжает список аргументов, полей или выражение static struct { struct reg SPICCR,SPICTL,SPISTS,SPIFFTX,SPIFFRX,SPIFFCT,SPIPRI;; порядок элементов сохраняется. */
|
||||
static struct { struct reg SPICCR,SPICTL,SPISTS,SPIFFTX,SPIFFRX,SPIFFCT,SPIPRI;
|
||||
/* Продолжает список аргументов, полей или выражение unsigned SPIBRR; uint16_t SPITXBUF,SPIRXBUF; } SpiaRegs;; порядок элементов сохраняется. */
|
||||
unsigned SPIBRR; uint16_t SPITXBUF,SPIRXBUF; } SpiaRegs;
|
||||
/* Начинает функцию InitCpuTimers; назначение модуля — проверка eeprom_profiles/stubs на модели ПК. */
|
||||
static void InitCpuTimers(void) {}
|
||||
/* Начинает функцию ConfigCpuTimer; назначение модуля — проверка eeprom_profiles/stubs на модели ПК. */
|
||||
static void ConfigCpuTimer(void *p, unsigned long f, unsigned t) {(void)p;(void)f;(void)t;}
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
# Проверка firmware_identity на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Independent test oracle: does this built SCI8 file contain its manifest identity?; порядок аргументов сохраняется.
|
||||
"""Independent test oracle: does this built SCI8 file contain its manifest identity?
|
||||
|
||||
This is a build test, not a second production protocol codec. The 12-word vector
|
||||
@@ -5,38 +7,72 @@ is deliberately constructed independently of the C implementation to detect a
|
||||
stale compilation unit, incorrect byte order or a mismatched pre-build JSON.
|
||||
Usage: python tests/firmware_identity/check_build.py path/to/firmware.bin
|
||||
"""
|
||||
# Импортирует необходимые имена: from datetime import datetime.
|
||||
from datetime import datetime
|
||||
# Подключает модуль hashlib для этой проверки или подготовки сборки.
|
||||
import hashlib
|
||||
# Подключает модуль json для этой проверки или подготовки сборки.
|
||||
import json
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль struct для этой проверки или подготовки сборки.
|
||||
import struct
|
||||
# Подключает модуль sys для этой проверки или подготовки сборки.
|
||||
import sys
|
||||
|
||||
# Задаёт image по выражению справа; значение используется последующими операциями.
|
||||
image = Path(sys.argv[1])
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
data = image.read_bytes()
|
||||
meta = json.loads(image.with_suffix(image.suffix + '.manifest.json').read_text())
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
meta = json.loads(image.with_suffix(image.suffix + '.manifest.json').read_text(encoding="utf-8"))
|
||||
# Проверяет обязательное условие hashlib.sha256(data).hexdigest() == meta['sha256'], 'Wrong file hash'; нарушение делает тест неуспешным.
|
||||
assert hashlib.sha256(data).hexdigest() == meta['sha256'], 'Wrong file hash'
|
||||
# Проверяет обязательное условие len(data) == meta['size_bytes'], 'Wrong image size'; нарушение делает тест неуспешным.
|
||||
assert len(data) == meta['size_bytes'], 'Wrong image size'
|
||||
# Задаёт stamp по выражению справа; значение используется последующими операциями.
|
||||
stamp = datetime.fromisoformat(meta['built_at_utc'])
|
||||
# Задаёт build_id по выражению справа; значение используется последующими операциями.
|
||||
build_id = meta['build_id']
|
||||
# Задаёт words по выражению справа; значение используется последующими операциями.
|
||||
words = [1, *meta['version'], stamp.year, stamp.month * 256 + stamp.day,
|
||||
# Продолжает текущий вызов, список или выражение: stamp.hour * 256 + stamp.minute, stamp.second]; порядок аргументов сохраняется.
|
||||
stamp.hour * 256 + stamp.minute, stamp.second]
|
||||
# Задаёт words + по выражению справа; значение используется последующими операциями.
|
||||
words += [ord(build_id[i]) * 256 + ord(build_id[i+1]) for i in range(0, 8, 2)]
|
||||
# Задаёт expected по выражению справа; значение используется последующими операциями.
|
||||
expected = struct.pack('<12H', *words)
|
||||
# Проверяет обязательное условие data[:2] == b'\xaa\x08', 'Not SCI8'; нарушение делает тест неуспешным.
|
||||
assert data[:2] == b'\xaa\x08', 'Not SCI8'
|
||||
# Задаёт offset по выражению справа; значение используется последующими операциями.
|
||||
offset = 22
|
||||
# Задаёт found по выражению справа; значение используется последующими операциями.
|
||||
found = 0
|
||||
# Повторяет блок при выполнении True.
|
||||
while True:
|
||||
# Задаёт count, по выражению справа; значение используется последующими операциями.
|
||||
count, = struct.unpack_from('<H', data, offset)
|
||||
# Задаёт offset + по выражению справа; значение используется последующими операциями.
|
||||
offset += 2
|
||||
# Проверяет условие if not count перед выполнением следующего блока.
|
||||
if not count:
|
||||
# Продолжает текущий вызов, список или выражение: break; порядок аргументов сохраняется.
|
||||
break
|
||||
# Задаёт offset + по выражению справа; значение используется последующими операциями.
|
||||
offset += 4 # destination address, not part of the loaded section payload
|
||||
# Задаёт end по выражению справа; значение используется последующими операциями.
|
||||
end = offset + count * 2
|
||||
# Проверяет обязательное условие end <= len(data), 'Truncated boot block'; нарушение делает тест неуспешным.
|
||||
assert end <= len(data), 'Truncated boot block'
|
||||
# Задаёт block по выражению справа; значение используется последующими операциями.
|
||||
block = data[offset:end]
|
||||
# Задаёт found + по выражению справа; значение используется последующими операциями.
|
||||
found += sum(block[i:i+24] == expected for i in range(0, len(block)-23, 2))
|
||||
# Задаёт offset по выражению справа; значение используется последующими операциями.
|
||||
offset = end
|
||||
# Проверяет обязательное условие offset == len(data), 'Trailing data'; нарушение делает тест неуспешным.
|
||||
assert offset == len(data), 'Trailing data'
|
||||
# Проверяет обязательное условие found == 1, f'Expected one embedded identity, found {found}'; нарушение делает тест неуспешным.
|
||||
assert found == 1, f'Expected one embedded identity, found {found}'
|
||||
# Продолжает текущий вызов, список или выражение: print(f'PASS: SCI8 contains manifest identity {meta["version"]}, {build_id}, {stamp.isoformat()}'); порядок аргументов сохраняется.
|
||||
print(f'PASS: SCI8 contains manifest identity {meta["version"]}, {build_id}, {stamp.isoformat()}')
|
||||
|
||||
@@ -1,33 +1,63 @@
|
||||
/* Проверка firmware_identity на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Test the actual 167 binding, not just a fake protocol backend. Build against
|
||||
* the generated header from the firmware build under test. No MCU registers. */
|
||||
/* Подключает "firmware_identity.h": настройки и интерфейс firmware_identity. */
|
||||
#include "firmware_identity.h"
|
||||
/* Подключает "firmware_info_static.h": настройки и интерфейс firmware_info_static. */
|
||||
#include "firmware_info_static.h"
|
||||
/* Подключает "ump_tms28335.h": настройки и интерфейс ump_tms28335. */
|
||||
#include "ump_tms28335.h"
|
||||
/* Подключает <assert.h>: настройки и интерфейс assert. */
|
||||
#include <assert.h>
|
||||
/* Продолжает список аргументов, полей или выражение static unsigned logger_reads, logger_writes;; порядок элементов сохраняется. */
|
||||
static unsigned logger_reads, logger_writes;
|
||||
/* Проверяет область чтения регистратора и возвращает слова состояния либо архивной записи. */
|
||||
unsigned int ump_log_read(unsigned int address)
|
||||
/* Изменяет счётчик в выражении { (void)address; ++logger_reads; return 0x554dU; } на один для следующего шага. */
|
||||
{ (void)address; ++logger_reads; return 0x554dU; }
|
||||
/* Применяет допустимые команды управления регистратором, сохраняя ограничения адресов. */
|
||||
int ump_log_write(unsigned int address, unsigned int value)
|
||||
/* Изменяет счётчик в выражении { (void)address; (void)value; ++logger_writes; return 1; } на один для следующего шага. */
|
||||
{ (void)address; (void)value; ++logger_writes; return 1; }
|
||||
|
||||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||||
int main(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет words — слова. */
|
||||
uint16_t words[UMP_MAX_WORDS];
|
||||
/* Продолжает список аргументов, полей или выражение ump_octet wire[UMP_RTU_CAPACITY];; порядок элементов сохраняется. */
|
||||
ump_octet wire[UMP_RTU_CAPACITY];
|
||||
/* Продолжает список аргументов, полей или выражение unsigned error, i;; порядок элементов сохраняется. */
|
||||
unsigned error, i;
|
||||
/* Вызывает assert с аргументами (ump_tms28335_prepare(3, UMP_FIRMWARE_INFO, 12, words, &error) == 12 && !error) в текущей последовательности операций. */
|
||||
assert(ump_tms28335_prepare(3, UMP_FIRMWARE_INFO, 12, words, &error) == 12 && !error);
|
||||
/* Вызывает assert с аргументами (words[0] == 1 && words[1] == FIRMWARE_VERSION_MAJOR) в текущей последовательности операций. */
|
||||
assert(words[0] == 1 && words[1] == FIRMWARE_VERSION_MAJOR);
|
||||
/* Вызывает assert с аргументами (words[2] == FIRMWARE_VERSION_MINOR && words[3] == FIRMWARE_VERSION_PATCH) в текущей последовательности операций. */
|
||||
assert(words[2] == FIRMWARE_VERSION_MINOR && words[3] == FIRMWARE_VERSION_PATCH);
|
||||
/* Вызывает assert с аргументами (words[4] == FI_YEAR && words[5] == FI_PAIR(FI_MONTH, FI_DAY)) в текущей последовательности операций. */
|
||||
assert(words[4] == FI_YEAR && words[5] == FI_PAIR(FI_MONTH, FI_DAY));
|
||||
/* Вызывает assert с аргументами (words[8] == FI_PAIR(FI_ID_0, FI_ID_1)) в текущей последовательности операций. */
|
||||
assert(words[8] == FI_PAIR(FI_ID_0, FI_ID_1));
|
||||
/* Вызывает assert с аргументами (logger_reads == 0) в текущей последовательности операций. */
|
||||
assert(logger_reads == 0);
|
||||
/* Вызывает assert с аргументами (ump_tms28335_rtu(1,3,UMP_FIRMWARE_INFO,12,wire,UMP_RTU_CAPACITY) == 29) в текущей последовательности операций. */
|
||||
assert(ump_tms28335_rtu(1,3,UMP_FIRMWARE_INFO,12,wire,UMP_RTU_CAPACITY) == 29);
|
||||
/* Цикл for (i=0; i<12; ++i) assert(((wire[3+i*2]<<8) | wire[4+i*2]) == words[i]);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<12; ++i) assert(((wire[3+i*2]<<8) | wire[4+i*2]) == words[i]);
|
||||
/* Вызывает assert с аргументами (ump_crc(wire,29) == 0) в текущей последовательности операций. */
|
||||
assert(ump_crc(wire,29) == 0);
|
||||
/* Вызывает ump_tms28335_prepare с аргументами (6,UMP_FIRMWARE_INFO,123,words,&error) в текущей последовательности операций. */
|
||||
ump_tms28335_prepare(6,UMP_FIRMWARE_INFO,123,words,&error);
|
||||
/* Вызывает assert с аргументами (error == 2 && logger_writes == 0) в текущей последовательности операций. */
|
||||
assert(error == 2 && logger_writes == 0);
|
||||
/* Firmware reads must not steal the existing logger window. */
|
||||
/* Вызывает assert с аргументами (ump_tms28335_prepare(3,UMP_BASE,16,words,&error) == 16 && !error) в текущей последовательности операций. */
|
||||
assert(ump_tms28335_prepare(3,UMP_BASE,16,words,&error) == 16 && !error);
|
||||
/* Вызывает assert с аргументами (logger_reads == 16 && words[0] == 0x554dU) в текущей последовательности операций. */
|
||||
assert(logger_reads == 16 && words[0] == 0x554dU);
|
||||
/* Завершает main и возвращает 0. */
|
||||
return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,48 +1,93 @@
|
||||
# Проверка gas167 на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Validate the PM35 RAM-load SCI8 image against the selected EEPROM profile."""; порядок аргументов сохраняется.
|
||||
"""Validate the PM35 RAM-load SCI8 image against the selected EEPROM profile."""
|
||||
# Подключает модуль argparse для этой проверки или подготовки сборки.
|
||||
import argparse
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль struct для этой проверки или подготовки сборки.
|
||||
import struct
|
||||
|
||||
|
||||
# Объявляет функцию check_image и её входные параметры.
|
||||
def check_image(path, eeprom):
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
data = path.read_bytes()
|
||||
# Задаёт limit по выражению справа; значение используется последующими операциями.
|
||||
limit = {"AT25256B": 32508, "M95M02": 261884}[eeprom]
|
||||
# Проверяет условие if not 24 <= len(data) <= limit перед выполнением следующего блока.
|
||||
if not 24 <= len(data) <= limit:
|
||||
# Останавливает текущую операцию с исключением ValueError(f"Image size {len(data)} outside 24..{limit}").
|
||||
raise ValueError(f"Image size {len(data)} outside 24..{limit}")
|
||||
# Проверяет условие if struct.unpack_from("<H", data)[0] != 0x08AA перед выполнением следующего блока.
|
||||
if struct.unpack_from("<H", data)[0] != 0x08AA:
|
||||
# Останавливает текущую операцию с исключением ValueError("Not a SCI8 boot image").
|
||||
raise ValueError("Not a SCI8 boot image")
|
||||
# Задаёт high, low по выражению справа; значение используется последующими операциями.
|
||||
high, low = struct.unpack_from("<HH", data, 18)
|
||||
# Задаёт entry по выражению справа; значение используется последующими операциями.
|
||||
entry = (high << 16) | low
|
||||
# Задаёт position, blocks по выражению справа; значение используется последующими операциями.
|
||||
position, blocks = 22, []
|
||||
# Повторяет блок при выполнении True.
|
||||
while True:
|
||||
# Проверяет условие if position + 2 > len(data) перед выполнением следующего блока.
|
||||
if position + 2 > len(data):
|
||||
# Останавливает текущую операцию с исключением ValueError("Missing boot terminator").
|
||||
raise ValueError("Missing boot terminator")
|
||||
# Задаёт words по выражению справа; значение используется последующими операциями.
|
||||
words = struct.unpack_from("<H", data, position)[0]
|
||||
# Задаёт position + по выражению справа; значение используется последующими операциями.
|
||||
position += 2
|
||||
# Проверяет условие if not words перед выполнением следующего блока.
|
||||
if not words:
|
||||
# Проверяет условие if position != len(data) перед выполнением следующего блока.
|
||||
if position != len(data):
|
||||
# Останавливает текущую операцию с исключением ValueError("Trailing bytes after boot terminator").
|
||||
raise ValueError("Trailing bytes after boot terminator")
|
||||
# Продолжает текущий вызов, список или выражение: break; порядок аргументов сохраняется.
|
||||
break
|
||||
# Проверяет условие if position + 4 + words * 2 > len(data) перед выполнением следующего блока.
|
||||
if position + 4 + words * 2 > len(data):
|
||||
# Останавливает текущую операцию с исключением ValueError("Truncated boot block").
|
||||
raise ValueError("Truncated boot block")
|
||||
# Задаёт high, low по выражению справа; значение используется последующими операциями.
|
||||
high, low = struct.unpack_from("<HH", data, position)
|
||||
# Задаёт address по выражению справа; значение используется последующими операциями.
|
||||
address = (high << 16) | low
|
||||
# Задаёт end по выражению справа; значение используется последующими операциями.
|
||||
end = address + words
|
||||
# Проверяет условие if not 0x8000 <= address < end <= 0xD000 перед выполнением следующего блока.
|
||||
if not 0x8000 <= address < end <= 0xD000:
|
||||
# Останавливает текущую операцию с исключением ValueError(f"Boot destination {address:#x}..{end:#x} outside code RAM").
|
||||
raise ValueError(f"Boot destination {address:#x}..{end:#x} outside code RAM")
|
||||
# Проверяет условие if any(address < old_end and old_start < end for old_start, old_end in blocks) перед выполнением следующего блока.
|
||||
if any(address < old_end and old_start < end for old_start, old_end in blocks):
|
||||
# Останавливает текущую операцию с исключением ValueError("Overlapping boot blocks").
|
||||
raise ValueError("Overlapping boot blocks")
|
||||
# Продолжает текущий вызов, список или выражение: blocks.append((address, end)); порядок аргументов сохраняется.
|
||||
blocks.append((address, end))
|
||||
# Задаёт position + по выражению справа; значение используется последующими операциями.
|
||||
position += 4 + words * 2
|
||||
# Проверяет условие if not any(start <= entry < end for start, end in blocks) перед выполнением следующего блока.
|
||||
if not any(start <= entry < end for start, end in blocks):
|
||||
# Останавливает текущую операцию с исключением ValueError("Entry point not loaded by the boot table").
|
||||
raise ValueError("Entry point not loaded by the boot table")
|
||||
# Возвращает len(data), len(blocks), limit - len(data) вызывающему коду и завершает функцию.
|
||||
return len(data), len(blocks), limit - len(data)
|
||||
|
||||
|
||||
# Проверяет условие if __name__ == "__main__" перед выполнением следующего блока.
|
||||
if __name__ == "__main__":
|
||||
# Задаёт parser по выражению справа; значение используется последующими операциями.
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
# Задаёт parser.add_argument("image", type по выражению справа; значение используется последующими операциями.
|
||||
parser.add_argument("image", type=Path)
|
||||
# Задаёт parser.add_argument("--eeprom", choices по выражению справа; значение используется последующими операциями.
|
||||
parser.add_argument("--eeprom", choices=("AT25256B", "M95M02"), required=True)
|
||||
# Задаёт args по выражению справа; значение используется последующими операциями.
|
||||
args = parser.parse_args()
|
||||
# Задаёт size, blocks, free по выражению справа; значение используется последующими операциями.
|
||||
size, blocks, free = check_image(args.image, args.eeprom)
|
||||
# Продолжает текущий вызов, список или выражение: print(f"PASS SCI8 {args.eeprom}: {size} bytes, {blocks} RAM blocks, {free} bytes free"); порядок аргументов сохраняется.
|
||||
print(f"PASS SCI8 {args.eeprom}: {size} bytes, {blocks} RAM blocks, {free} bytes free")
|
||||
|
||||
@@ -1,196 +1,386 @@
|
||||
/* Проверка gas167 на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подключает <assert.h>: настройки и интерфейс assert. */
|
||||
#include <assert.h>
|
||||
/* Подключает <stdbool.h>: настройки и интерфейс stdbool. */
|
||||
#include <stdbool.h>
|
||||
/* Подключает <stdint.h>: настройки и интерфейс stdint. */
|
||||
#include <stdint.h>
|
||||
/* Подключает <stdio.h>: настройки и интерфейс stdio. */
|
||||
#include <stdio.h>
|
||||
/* Подключает <string.h>: настройки и интерфейс string. */
|
||||
#include <string.h>
|
||||
/* Подключает "gas167.h": дополнительная карта GAS 167/v1 только для новой EEPROM M95M02. */
|
||||
#include "gas167.h"
|
||||
/* Подключает "ump_protocol.h": настройки и интерфейс ump_protocol. */
|
||||
#include "ump_protocol.h"
|
||||
/* Подключает "ump_tms28335.h": настройки и интерфейс ump_tms28335. */
|
||||
#include "ump_tms28335.h"
|
||||
/* Подключает "include/balsam167_eeprom_block.h": настройки и интерфейс balsam167_eeprom_block. */
|
||||
#include "include/balsam167_eeprom_block.h"
|
||||
|
||||
/* Задаёт ANSWER_LEN = 128U; данные ANSWER_LEN. */
|
||||
#define ANSWER_LEN 128U
|
||||
/* Задаёт MAX_SEND_LENGTH = 400U; MAX SEND длина. */
|
||||
#define MAX_SEND_LENGTH 400U
|
||||
/* Задаёт CNTRL_ADDR = 16U; данные CNTRL_ADDR. */
|
||||
#define CNTRL_ADDR 16U
|
||||
/* Задаёт CMD_MODBUS_3 = 3U; данные CMD_MODBUS_3. */
|
||||
#define CMD_MODBUS_3 3U
|
||||
/* Задаёт CMD_MODBUS_6 = 6U; данные CMD_MODBUS_6. */
|
||||
#define CMD_MODBUS_6 6U
|
||||
/* Задаёт dsk_LOAD = 6; код платы нагрузки. */
|
||||
#define dsk_LOAD 6
|
||||
/* Задаёт LOBYTE = ((v) & 255U); данные LOBYTE. */
|
||||
#define LOBYTE(v) ((v) & 255U)
|
||||
/* Задаёт HIBYTE = (((v) >> 8) & 255U); данные HIBYTE. */
|
||||
#define HIBYTE(v) (((v) >> 8) & 255U)
|
||||
/* Задаёт UMP_CAN_MAX_WORDS = UMP_MAX_WORDS; UMP CAN MAX слова. */
|
||||
#define UMP_CAN_MAX_WORDS UMP_MAX_WORDS
|
||||
/* Задаёт ump_can_prepare = ump_tms28335_prepare; ump CAN prepare. */
|
||||
#define ump_can_prepare ump_tms28335_prepare
|
||||
/* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */
|
||||
typedef struct { int all; } WORDE;
|
||||
/* Задаёт Modbus = ((WORDE *)modbus); данные Modbus. */
|
||||
#define Modbus ((WORDE *)modbus)
|
||||
/* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */
|
||||
typedef struct {
|
||||
/* Объявляет RS_Header — данные RS_Header; buffer — буфер. */
|
||||
uint16_t RS_Header[8], buffer[MAX_SEND_LENGTH];
|
||||
/* Продолжает список аргументов, полей или выражение unsigned flag_TIMEOUT_to_Send;; порядок элементов сохраняется. */
|
||||
unsigned flag_TIMEOUT_to_Send;
|
||||
/* Продолжает список аргументов, полей или выражение } RS_DATA;; порядок элементов сохраняется. */
|
||||
} RS_DATA;
|
||||
|
||||
/* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит; Desk — аппаратно определённый тип платы; dsk_LOAD — код платы нагрузки. Начальное значение задаётся справа от знака равенства. */
|
||||
int modbus[129], Desk = dsk_LOAD;
|
||||
/* Продолжает список аргументов, полей или выражение static unsigned captures, spi_reads, sent, irq_depth, legacy_reads;; порядок элементов сохраняется. */
|
||||
static unsigned captures, spi_reads, sent, irq_depth, legacy_reads;
|
||||
/* Начинает функцию __disable_interrupts; назначение модуля — проверка gas167 на модели ПК. */
|
||||
static unsigned __disable_interrupts(void) {
|
||||
/* Записывает saved значением irq_depth; данные saved. */
|
||||
unsigned saved = irq_depth;
|
||||
/* Изменяет счётчик в выражении ++irq_depth; на один для следующего шага. */
|
||||
++irq_depth;
|
||||
/* Завершает __disable_interrupts и возвращает saved. */
|
||||
return saved;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию __restore_interrupts; назначение модуля — проверка gas167 на модели ПК. */
|
||||
static void __restore_interrupts(unsigned saved) { irq_depth = saved; }
|
||||
/* Регистрирует изменение слова команд после записи по последовательному интерфейсу. */
|
||||
void ump_log_rs(void) { ++captures; }
|
||||
/* Проверяет область чтения регистратора и возвращает слова состояния либо архивной записи. */
|
||||
unsigned int ump_log_read(unsigned int address) { ++legacy_reads; return address; }
|
||||
/* Применяет допустимые команды управления регистратором, сохраняя ограничения адресов. */
|
||||
int ump_log_write(unsigned int address, unsigned int value) { return 1; }
|
||||
/* Начинает функцию get_crc_16; назначение модуля — проверка gas167 на модели ПК. */
|
||||
static unsigned get_crc_16(unsigned seed, const uint16_t *data, unsigned size) {
|
||||
/* Вызывает assert с аргументами (seed == 0xFFFFU) в текущей последовательности операций. */
|
||||
assert(seed == 0xFFFFU);
|
||||
/* Завершает get_crc_16 и возвращает ump_crc(data, size). */
|
||||
return ump_crc(data, size);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Передаёт массив слов через SCI в выбранном режиме упаковки. */
|
||||
static void RS_Send(RS_DATA *rs, uint16_t *data, unsigned size) {
|
||||
/* Вызывает assert с аргументами (irq_depth == 0) в текущей последовательности операций. */
|
||||
assert(irq_depth == 0);
|
||||
/* Записывает sent значением size; данные sent. */
|
||||
sent = size;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Читает EEPROM порциями; адрес задаётся словами C28x, размер переводится в число передаваемых слов. */
|
||||
static void Seeprom_read(unsigned long word, uint16_t *data, unsigned bytes) {
|
||||
/* Продолжает список аргументов, полей или выражение unsigned i;; порядок элементов сохраняется. */
|
||||
unsigned i;
|
||||
assert(irq_depth == 0); /* The Timer2 SPI driver must retain interrupts. */
|
||||
assert(irq_depth == 0); /* The Timer2 SPI driver must retain interrupts. */ /* Вызывает assert с аргументами (irq_depth == 0) в текущей последовательности операций. */
|
||||
/* Изменяет счётчик в выражении ++spi_reads; на один для следующего шага. */
|
||||
++spi_reads;
|
||||
/* Цикл for (i = 0; i < bytes/2; ++i) data[i] = (uint16_t)(0xBEEFU+i);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < bytes/2; ++i) data[i] = (uint16_t)(0xBEEFU+i);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
static unsigned Load_protection_prepare(unsigned fn, unsigned a, unsigned n,
|
||||
/* Объявляет out — данные out. Хранит указатель на данные. */
|
||||
uint16_t *out, unsigned *error) {
|
||||
/* Записывает out[0] значением (uint16_t)a; out[1] = (uint16_t)n; *error = 0; данные out. */
|
||||
out[0] = (uint16_t)a; out[1] = (uint16_t)n; *error = 0;
|
||||
/* Завершает Load_protection_prepare и возвращает 2. */
|
||||
return 2;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Описывает структуру mock_reg; порядок полей определяет расположение данных. */
|
||||
struct mock_reg { uint32_t all; };
|
||||
/* Продолжает список аргументов, полей или выражение static struct {; порядок элементов сохраняется. */
|
||||
static struct {
|
||||
/* Описывает структуру mock_reg CANTA, CANAA, CANTRR, CANTRS;; порядок полей определяет расположение данных. */
|
||||
struct mock_reg CANTA, CANAA, CANTRR, CANTRS;
|
||||
/* Продолжает список аргументов, полей или выражение } ECanaRegs;; порядок элементов сохраняется. */
|
||||
} ECanaRegs;
|
||||
/* Продолжает список аргументов, полей или выражение static struct {; порядок элементов сохраняется. */
|
||||
static struct {
|
||||
/* Описывает структуру ; порядок полей определяет расположение данных. */
|
||||
struct { struct mock_reg MDH, MDL; } MBOX2;
|
||||
/* Продолжает список аргументов, полей или выражение } ECanaMboxes;; порядок элементов сохраняется. */
|
||||
} ECanaMboxes;
|
||||
/* Продолжает список аргументов, полей или выражение static struct { unsigned long InterruptCount; } CpuTimer1;; порядок элементов сохраняется. */
|
||||
static struct { unsigned long InterruptCount; } CpuTimer1;
|
||||
/* Подключает "production_routes.inc": настройки и интерфейс production_routes. */
|
||||
#include "production_routes.inc"
|
||||
|
||||
/* Начинает функцию request; назначение модуля — проверка gas167 на модели ПК. */
|
||||
static void request(RS_DATA *rs, unsigned fn, unsigned a, unsigned n) {
|
||||
/* Продолжает список аргументов, полей или выражение unsigned crc;; порядок элементов сохраняется. */
|
||||
unsigned crc;
|
||||
/* Вызывает memset с аргументами (rs, 0, sizeof(*rs)) в текущей последовательности операций. */
|
||||
memset(rs, 0, sizeof(*rs));
|
||||
/* Записывает rs->RS_Header[0] значением CNTRL_ADDR; rs->RS_Header[1] = fn; данные rs->RS_Header. */
|
||||
rs->RS_Header[0] = CNTRL_ADDR; rs->RS_Header[1] = fn;
|
||||
/* Записывает rs->RS_Header[2] значением a >> 8; rs->RS_Header[3] = a & 255U; данные rs->RS_Header. */
|
||||
rs->RS_Header[2] = a >> 8; rs->RS_Header[3] = a & 255U;
|
||||
/* Записывает rs->RS_Header[4] значением n >> 8; rs->RS_Header[5] = n & 255U; данные rs->RS_Header. */
|
||||
rs->RS_Header[4] = n >> 8; rs->RS_Header[5] = n & 255U;
|
||||
/* Записывает crc значением ump_crc(rs->RS_Header, 6); данные crc. */
|
||||
crc = ump_crc(rs->RS_Header, 6);
|
||||
/* Записывает rs->RS_Header[6] значением crc & 255U; rs->RS_Header[7] = crc >> 8; данные rs->RS_Header. */
|
||||
rs->RS_Header[6] = crc & 255U; rs->RS_Header[7] = crc >> 8;
|
||||
/* Записывает sent значением 0; данные sent. */
|
||||
sent = 0;
|
||||
/* Проверяет if (fn == 3) ReceiveCommandModbus3(rs); последующий оператор выполняется только при истинном условии. */
|
||||
if (fn == 3) ReceiveCommandModbus3(rs);
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
else ReceiveCommandModbus6(rs);
|
||||
/* Вызывает assert с аргументами (irq_depth == 0 && rs->flag_TIMEOUT_to_Send) в текущей последовательности операций. */
|
||||
assert(irq_depth == 0 && rs->flag_TIMEOUT_to_Send);
|
||||
/* Вызывает assert с аргументами (ump_crc(rs->buffer, rs->buffer[1] & 128U ? 5 : в текущей последовательности операций. */
|
||||
assert(ump_crc(rs->buffer, rs->buffer[1] & 128U ? 5 :
|
||||
/* Продолжает список аргументов, полей или выражение (fn == 6 ? 8 : 5+rs->buffer[2])) == 0);; порядок элементов сохраняется. */
|
||||
(fn == 6 ? 8 : 5+rs->buffer[2])) == 0);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию can_request; назначение модуля — проверка gas167 на модели ПК. */
|
||||
static void can_request(unsigned fn, unsigned a, unsigned n) {
|
||||
/* Вызывает memset с аргументами (&ECanaRegs, 0, sizeof(ECanaRegs)) в текущей последовательности операций. */
|
||||
memset(&ECanaRegs, 0, sizeof(ECanaRegs));
|
||||
/* Вызывает memset с аргументами (&ECanaMboxes, 0, sizeof(ECanaMboxes)) в текущей последовательности операций. */
|
||||
memset(&ECanaMboxes, 0, sizeof(ECanaMboxes));
|
||||
/* Записывает ump_can_waiting значением 0; ump_can_length = 0; ump_can_index = 0; ump CAN waiting. */
|
||||
ump_can_waiting = 0; ump_can_length = 0; ump_can_index = 0;
|
||||
/* Записывает ump_can_pending значением 1; ump_can_tag = 0x0100U | fn; флаг ожидающего запроса служебного CAN между ISR и главным циклом. */
|
||||
ump_can_pending = 1; ump_can_tag = 0x0100U | fn;
|
||||
/* Записывает ump_can_address значением a; ump_can_value = n; ump CAN адрес. */
|
||||
ump_can_address = a; ump_can_value = n;
|
||||
/* Вызывает UMP_CAN_service. В главном цикле готовит замороженный ответ служебного CAN и отправляет его двухсловными фрагментами. */
|
||||
UMP_CAN_service();
|
||||
/* Вызывает assert с аргументами (irq_depth == 0 && !ump_can_pending) в текущей последовательности операций. */
|
||||
assert(irq_depth == 0 && !ump_can_pending);
|
||||
/* Вызывает assert с аргументами (ECanaRegs.CANTRS.all == 4U) в текущей последовательности операций. */
|
||||
assert(ECanaRegs.CANTRS.all == 4U);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||||
int main(void) {
|
||||
/* Объявляет rs — данные rs. */
|
||||
RS_DATA rs;
|
||||
/* Продолжает список аргументов, полей или выражение unsigned i;; порядок элементов сохраняется. */
|
||||
unsigned i;
|
||||
/* Цикл for (i = 0; i < 129; ++i) modbus[i] = (int)i;; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 129; ++i) modbus[i] = (int)i;
|
||||
/* Записывает modbus[128] значением 0xD00D; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[128] = 0xD00D;
|
||||
/* Exercise the real native handlers in both builds. */
|
||||
/* Вызывает request с аргументами (&rs, 6, 1, 0xFEDC) в текущей последовательности операций. */
|
||||
request(&rs, 6, 1, 0xFEDC);
|
||||
/* Вызывает assert с аргументами (modbus[1] == 0xFEDC && sent == 10) в текущей последовательности операций. */
|
||||
assert(modbus[1] == 0xFEDC && sent == 10);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0, 2) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0, 2);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 4 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 4 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x52, 0) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x52, 0);
|
||||
/* Вызывает assert с аргументами (rs.buffer[1] == 0x86 && rs.buffer[2] == 3 && modbus[0x52] == 0x52) в текущей последовательности операций. */
|
||||
assert(rs.buffer[1] == 0x86 && rs.buffer[2] == 3 && modbus[0x52] == 0x52);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x7C, 9) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x7C, 9);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 2 && modbus[0x7C] == 0x7C) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 2 && modbus[0x7C] == 0x7C);
|
||||
/* Existing UMP and protection routing must still work. */
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x1000, 2) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x1000, 2);
|
||||
/* Вызывает assert с аргументами (rs.buffer[1] == 3 && rs.buffer[3] == 0x10 && legacy_reads == 2) в текущей последовательности операций. */
|
||||
assert(rs.buffer[1] == 3 && rs.buffer[3] == 0x10 && legacy_reads == 2);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x1300, 2) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x1300, 2);
|
||||
/* Вызывает assert с аргументами (rs.buffer[1] == 3 && rs.buffer[3] == 0x13) в текущей последовательности операций. */
|
||||
assert(rs.buffer[1] == 3 && rs.buffer[3] == 0x13);
|
||||
/* Условие компиляции EEPROM_M95M02: выбранный блок включается в текущий вариант прошивки. */
|
||||
#if EEPROM_M95M02
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет out — данные out. */
|
||||
uint16_t out[124];
|
||||
/* Продолжает список аргументов, полей или выражение unsigned error, count;; порядок элементов сохраняется. */
|
||||
unsigned error, count;
|
||||
/* Цикл for (i = 0; i < 65536U; ++i); задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 65536U; ++i)
|
||||
/* Вызывает assert с аргументами (gas167_contains((uint16_t)i) == в текущей последовательности операций. */
|
||||
assert(gas167_contains((uint16_t)i) ==
|
||||
/* Продолжает список аргументов, полей или выражение ((i >= 0x5000U && i <= 0x507FU) || (i >= 0x5F00U && i <= 0x5F07U)));; порядок элементов сохраняется. */
|
||||
((i >= 0x5000U && i <= 0x507FU) || (i >= 0x5F00U && i <= 0x5F07U)));
|
||||
/* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 124, 0, out, &error) == 124 && !error) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(3, 0x5000, 124, 0, out, &error) == 124 && !error);
|
||||
/* Вызывает assert с аргументами (out[1] == 0xFEDC && out[123] == 123) в текущей последовательности операций. */
|
||||
assert(out[1] == 0xFEDC && out[123] == 123);
|
||||
/* Записывает count значением gas167_prepare(3, 0x507F, 2, 0, out, &error); число. */
|
||||
count = gas167_prepare(3, 0x507F, 2, 0, out, &error);
|
||||
/* Вызывает assert с аргументами (count == 2 && error == 2 && modbus[128] == 0xD00D) в текущей последовательности операций. */
|
||||
assert(count == 2 && error == 2 && modbus[128] == 0xD00D);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 0, 0, out, &error) == 2 && error == 3) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(3, 0x5000, 0, 0, out, &error) == 2 && error == 3);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 125, 0, out, &error) == 2 && error == 3) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(3, 0x5000, 125, 0, out, &error) == 2 && error == 3);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 1, 1, out, &error) == 2 && error == 3) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(3, 0x5000, 1, 1, out, &error) == 2 && error == 3);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(3, 0xFFFF, 2, 0, out, &error) == 2 && error == 2) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(3, 0xFFFF, 2, 0, out, &error) == 2 && error == 2);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(16, 0x5000, 1, 0, out, &error) == 2 && error == 1) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(16, 0x5000, 1, 0, out, &error) == 2 && error == 1);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(6, 0x5080, 7, 0, out, &error) == 2 && error == 2) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(6, 0x5080, 7, 0, out, &error) == 2 && error == 2);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(6, 0x5052, 60001, 0, out, &error) == 2 && error == 3) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(6, 0x5052, 60001, 0, out, &error) == 2 && error == 3);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(6, 0x5052, 60000, 0, out, &error) == 2 && !error) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(6, 0x5052, 60000, 0, out, &error) == 2 && !error);
|
||||
/* Вызывает assert с аргументами (modbus[0x52] == 60000) в текущей последовательности операций. */
|
||||
assert(modbus[0x52] == 60000);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(3, 0x5000, 1, 0, 0, &error) == 0) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(3, 0x5000, 1, 0, 0, &error) == 0);
|
||||
/* Вызывает assert с аргументами (gas167_prepare(6, 0x5000, 1, 0, out, 0) == 0 && modbus[0] == 0) в текущей последовательности операций. */
|
||||
assert(gas167_prepare(6, 0x5000, 1, 0, out, 0) == 0 && modbus[0] == 0);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5000, 2) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5000, 2);
|
||||
/* Вызывает assert с аргументами (sent == 9 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC) в текущей последовательности операций. */
|
||||
assert(sent == 9 && rs.buffer[5] == 0xFE && rs.buffer[6] == 0xDC);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5000, 124) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5000, 124);
|
||||
/* Вызывает assert с аргументами (sent == 253 && rs.buffer[2] == 248) в текущей последовательности операций. */
|
||||
assert(sent == 253 && rs.buffer[2] == 248);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5F00, 8) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5F00, 8);
|
||||
/* Вызывает assert с аргументами (sent == 21 && rs.buffer[3] == 0x47 && rs.buffer[4] == 0x41) в текущей последовательности операций. */
|
||||
assert(sent == 21 && rs.buffer[3] == 0x47 && rs.buffer[4] == 0x41);
|
||||
/* Вызывает assert с аргументами (rs.buffer[5] == 0x53 && rs.buffer[6] == 0x31) в текущей последовательности операций. */
|
||||
assert(rs.buffer[5] == 0x53 && rs.buffer[6] == 0x31);
|
||||
/* Вызывает assert с аргументами (rs.buffer[10] == 167 && rs.buffer[18] == 1) в текущей последовательности операций. */
|
||||
assert(rs.buffer[10] == 167 && rs.buffer[18] == 1);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x5F00, 0) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x5F00, 0);
|
||||
/* Вызывает assert с аргументами (sent == 5 && rs.buffer[2] == 2) в текущей последовательности операций. */
|
||||
assert(sent == 5 && rs.buffer[2] == 2);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5F07, 2) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5F07, 2);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 2) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 2);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x5052, 0) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x5052, 0);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 3 && modbus[0x52] == 60000) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 3 && modbus[0x52] == 60000);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x507D, 9) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x507D, 9);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 2 && modbus[0x7D] == 0x7D) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 2 && modbus[0x7D] == 0x7D);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x507F, 0x80) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x507F, 0x80);
|
||||
/* Вызывает assert с аргументами (sent == 8 && rs.buffer[2] == 0x50 && rs.buffer[3] == 0x7F) в текущей последовательности операций. */
|
||||
assert(sent == 8 && rs.buffer[2] == 0x50 && rs.buffer[3] == 0x7F);
|
||||
/* Вызывает assert с аргументами (captures == 1 && modbus[127] == 0x80) в текущей последовательности операций. */
|
||||
assert(captures == 1 && modbus[127] == 0x80);
|
||||
/* Вызывает can_request с аргументами (6, 0x5001, 0xFEDC) в текущей последовательности операций. */
|
||||
can_request(6, 0x5001, 0xFEDC);
|
||||
/* Вызывает assert с аргументами (modbus[1] == 0xFEDC && ECanaMboxes.MBOX2.MDL.all == 0x5001FEDCUL) в текущей последовательности операций. */
|
||||
assert(modbus[1] == 0xFEDC && ECanaMboxes.MBOX2.MDL.all == 0x5001FEDCUL);
|
||||
/* Вызывает assert с аргументами (ECanaMboxes.MBOX2.MDH.all == 0x1F000100UL) в текущей последовательности операций. */
|
||||
assert(ECanaMboxes.MBOX2.MDH.all == 0x1F000100UL);
|
||||
/* Вызывает can_request с аргументами (3, 0x5001, 2) в текущей последовательности операций. */
|
||||
can_request(3, 0x5001, 2);
|
||||
/* Вызывает assert с аргументами (ECanaMboxes.MBOX2.MDL.all == 0xFEDC0002UL) в текущей последовательности операций. */
|
||||
assert(ECanaMboxes.MBOX2.MDL.all == 0xFEDC0002UL);
|
||||
/* Вызывает can_request с аргументами (3, 0x5000, 124) в текущей последовательности операций. */
|
||||
can_request(3, 0x5000, 124);
|
||||
/* Вызывает assert с аргументами (ump_can_length == 124 && ump_can_index == 2) в текущей последовательности операций. */
|
||||
assert(ump_can_length == 124 && ump_can_index == 2);
|
||||
modbus[2] = 777; /* All fragments must retain the original snapshot. */
|
||||
modbus[2] = 777; /* All fragments must retain the original snapshot. */ /* Записывает modbus[2] значением 777; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
/* Цикл for (i = 1; i < 62; ++i) ; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 1; i < 62; ++i) {
|
||||
/* Записывает ECanaRegs.CANTA.all значением 4; представление регистра целым словом без разбиения на битовые поля. */
|
||||
ECanaRegs.CANTA.all = 4;
|
||||
/* Вызывает UMP_CAN_service. В главном цикле готовит замороженный ответ служебного CAN и отправляет его двухсловными фрагментами. */
|
||||
UMP_CAN_service();
|
||||
/* Вызывает assert с аргументами (ump_can_index == 2*(i+1)) в текущей последовательности операций. */
|
||||
assert(ump_can_index == 2*(i+1));
|
||||
/* Проверяет if (i == 1) assert(ECanaMboxes.MBOX2.MDL.all == 0x00020003UL); последующий оператор выполняется только при истинном условии. */
|
||||
if (i == 1) assert(ECanaMboxes.MBOX2.MDL.all == 0x00020003UL);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Записывает modbus[2] значением 2; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[2] = 2;
|
||||
/* Вызывает can_request с аргументами (3, 0x5000, 3) в текущей последовательности операций. */
|
||||
can_request(3, 0x5000, 3);
|
||||
/* Вызывает assert с аргументами (ECanaMboxes.MBOX2.MDH.all == 0x1F000103UL) в текущей последовательности операций. */
|
||||
assert(ECanaMboxes.MBOX2.MDH.all == 0x1F000103UL);
|
||||
/* Вызывает can_request с аргументами (6, 0x507C, 9) в текущей последовательности операций. */
|
||||
can_request(6, 0x507C, 9);
|
||||
/* Вызывает assert с аргументами ((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[0x7C] == 0x7C) в текущей последовательности операций. */
|
||||
assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[0x7C] == 0x7C);
|
||||
/* Вызывает can_request с аргументами (6, 0x507F, 0x40) в текущей последовательности операций. */
|
||||
can_request(6, 0x507F, 0x40);
|
||||
/* Вызывает assert с аргументами (captures == 2 && modbus[127] == 0x40) в текущей последовательности операций. */
|
||||
assert(captures == 2 && modbus[127] == 0x40);
|
||||
/* Вызывает can_request с аргументами (6, 0x5F00, 9) в текущей последовательности операций. */
|
||||
can_request(6, 0x5F00, 9);
|
||||
/* Вызывает assert с аргументами ((ECanaMboxes.MBOX2.MDH.all & 255U) == 2) в текущей последовательности операций. */
|
||||
assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 2);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x8000, 0x8001) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x8000, 0x8001);
|
||||
/* Выбирает альтернативный блок текущего условия компиляции. */
|
||||
#else
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5000, 2) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5000, 2);
|
||||
/* Вызывает assert с аргументами (sent == 5 && rs.buffer[2] == 2) в текущей последовательности операций. */
|
||||
assert(sent == 5 && rs.buffer[2] == 2);
|
||||
/* Вызывает request с аргументами (&rs, 6, 0x5001, 9) в текущей последовательности операций. */
|
||||
request(&rs, 6, 0x5001, 9);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 2 && modbus[1] == 0xFEDC) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 2 && modbus[1] == 0xFEDC);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5000, 124) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5000, 124);
|
||||
/* Вызывает assert с аргументами (sent == 5 && rs.buffer[2] == 2) в текущей последовательности операций. */
|
||||
assert(sent == 5 && rs.buffer[2] == 2);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x5F00, 8) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x5F00, 8);
|
||||
/* Вызывает assert с аргументами (rs.buffer[2] == 2) в текущей последовательности операций. */
|
||||
assert(rs.buffer[2] == 2);
|
||||
/* Вызывает can_request с аргументами (6, 0x5001, 9) в текущей последовательности операций. */
|
||||
can_request(6, 0x5001, 9);
|
||||
/* Вызывает assert с аргументами ((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[1] == 0xFEDC) в текущей последовательности операций. */
|
||||
assert((ECanaMboxes.MBOX2.MDH.all & 255U) == 2 && modbus[1] == 0xFEDC);
|
||||
/* Вызывает assert с аргументами (captures == 0) в текущей последовательности операций. */
|
||||
assert(captures == 0);
|
||||
/* Вызывает request с аргументами (&rs, 3, 0x8000, 1) в текущей последовательности операций. */
|
||||
request(&rs, 3, 0x8000, 1);
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
/* Вызывает assert с аргументами (spi_reads == 1 && rs.buffer[3] == 0xBE && rs.buffer[4] == 0xEF) в текущей последовательности операций. */
|
||||
assert(spi_reads == 1 && rs.buffer[3] == 0xBE && rs.buffer[4] == 0xEF);
|
||||
/* Вызывает assert с аргументами (modbus[128] == 0xD00D) в текущей последовательности операций. */
|
||||
assert(modbus[128] == 0xD00D);
|
||||
/* Вызывает printf с аргументами ("PASS GAS167 profile %d: production RTU/CAN routes, guards, CRC and legacy services\n", EEPROM_M95M02) в текущей последовательности операций. */
|
||||
printf("PASS GAS167 profile %d: production RTU/CAN routes, guards, CRC and legacy services\n", EEPROM_M95M02);
|
||||
/* Завершает main и возвращает 0. */
|
||||
return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,51 +1,97 @@
|
||||
# Проверка gas167 на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Exercise the production GAS provider and extracted production RTU/CAN routes."""; порядок аргументов сохраняется.
|
||||
"""Exercise the production GAS provider and extracted production RTU/CAN routes."""
|
||||
# Подключает модуль os для этой проверки или подготовки сборки.
|
||||
import os
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль re для этой проверки или подготовки сборки.
|
||||
import re
|
||||
# Подключает модуль shutil для этой проверки или подготовки сборки.
|
||||
import shutil
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
|
||||
# Задаёт root по выражению справа; значение используется последующими операциями.
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
# Задаёт templates по выражению справа; значение используется последующими операциями.
|
||||
templates = Path(os.environ.get("TEMPLATES_ROOT", root.parent / "newProject/SETGUI/third_party/templates"))
|
||||
# Задаёт protocol по выражению справа; значение используется последующими операциями.
|
||||
protocol = templates / "c/set-protocol"
|
||||
# Задаёт compiler по выражению справа; значение используется последующими операциями.
|
||||
compiler = os.environ.get("CC") or shutil.which("gcc") or "C:/msys64/mingw64/bin/gcc.exe"
|
||||
# Задаёт os.environ["PATH"] по выражению справа; значение используется последующими операциями.
|
||||
os.environ["PATH"] = str(Path(compiler).resolve().parent) + os.pathsep + os.environ["PATH"]
|
||||
|
||||
|
||||
# Объявляет функцию function и её входные параметры.
|
||||
def function(text, name):
|
||||
# Задаёт match по выражению справа; значение используется последующими операциями.
|
||||
match = re.search(r"^(?:static )?(?:void|int) " + name + r"\(", text, re.M)
|
||||
# Проверяет условие if not match перед выполнением следующего блока.
|
||||
if not match:
|
||||
# Останавливает текущую операцию с исключением ValueError(f"Production function {name} missing").
|
||||
raise ValueError(f"Production function {name} missing")
|
||||
# Задаёт end по выражению справа; значение используется последующими операциями.
|
||||
end = re.search(r"^}", text[match.start():], re.M)
|
||||
# Проверяет условие if not end перед выполнением следующего блока.
|
||||
if not end:
|
||||
# Останавливает текущую операцию с исключением ValueError(f"Production function {name} incomplete").
|
||||
raise ValueError(f"Production function {name} incomplete")
|
||||
# Возвращает text[match.start():match.start() + end.end()] + "\n" вызывающему коду и завершает функцию.
|
||||
return text[match.start():match.start() + end.end()] + "\n"
|
||||
|
||||
|
||||
message = (root / "Source/Internal/message.c").read_text(encoding="cp1251")
|
||||
ecan = (root / "Source/Internal/ecan.c").read_text(encoding="cp1251")
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
message = (root / "Source/Internal/message.c").read_text(encoding="utf-8")
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
ecan = (root / "Source/Internal/ecan.c").read_text(encoding="utf-8")
|
||||
# Задаёт can_globals по выражению справа; значение используется последующими операциями.
|
||||
can_globals = ecan[ecan.index("static volatile unsigned int ump_can_pending;"):
|
||||
# Продолжает текущий вызов, список или выражение: ecan.index("static unsigned long ump_can_sent_at;") + len("static unsigned long ump_can_sent_at;")]; порядок аргументов сохраняется.
|
||||
ecan.index("static unsigned long ump_can_sent_at;") + len("static unsigned long ump_can_sent_at;")]
|
||||
# On C28x unsigned int is uint16_t. Preserve that target word layout on GCC.
|
||||
# Задаёт can_globals по выражению справа; значение используется последующими операциями.
|
||||
can_globals = can_globals.replace("static unsigned int ump_can_reply[",
|
||||
# Продолжает текущий вызов, список или выражение: "static uint16_t ump_can_reply["); порядок аргументов сохраняется.
|
||||
"static uint16_t ump_can_reply[")
|
||||
# Задаёт routes по выражению справа; значение используется последующими операциями.
|
||||
routes = can_globals + "\n" + "".join(function(message, name) for name in
|
||||
# Продолжает текущий вызов, список или выражение: ("modbus_exception", "receive_ump", "ReceiveCommandModbus3", "ReceiveCommandModbus6")); порядок аргументов сохраняется.
|
||||
("modbus_exception", "receive_ump", "ReceiveCommandModbus3", "ReceiveCommandModbus6"))
|
||||
# Задаёт routes + по выражению справа; значение используется последующими операциями.
|
||||
routes += function(ecan, "UMP_CAN_service")
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix="gas167-test-") as tmp с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory(prefix="gas167-test-") as tmp:
|
||||
# Задаёт directory по выражению справа; значение используется последующими операциями.
|
||||
directory = Path(tmp)
|
||||
# Сохраняет подготовленный файл в указанном формате для следующего шага.
|
||||
(directory / "production_routes.inc").write_text(routes, encoding="utf-8")
|
||||
# Перебирает profile in (0, 1) в указанном порядке.
|
||||
for profile in (0, 1):
|
||||
# Задаёт exe по выражению справа; значение используется последующими операциями.
|
||||
exe = directory / f"gas167_{profile}.exe"
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([compiler, "-std=c99", "-Wall", "-Wextra",
|
||||
# Продолжает текущий вызов, список или выражение: "-Wno-unused-function", "-Wno-unused-parameter",; порядок аргументов сохраняется.
|
||||
"-Wno-unused-function", "-Wno-unused-parameter",
|
||||
# Задаёт f"-DEEPROM_M95M02 по выражению справа; значение используется последующими операциями.
|
||||
f"-DEEPROM_M95M02={profile}", "-I" + str(directory),
|
||||
# Продолжает текущий вызов, список или выражение: "-ISource/Internal/Include", "-I" + str(protocol),; порядок аргументов сохраняется.
|
||||
"-ISource/Internal/Include", "-I" + str(protocol),
|
||||
# Продолжает текущий вызов, список или выражение: "-I" + str(protocol / "include"),; порядок аргументов сохраняется.
|
||||
"-I" + str(protocol / "include"),
|
||||
# Продолжает текущий вызов, список или выражение: "-I" + str(protocol / "ports/tms320f28335"),; порядок аргументов сохраняется.
|
||||
"-I" + str(protocol / "ports/tms320f28335"),
|
||||
# Продолжает текущий вызов, список или выражение: "tests/gas167/gas167_test.c", "Source/Internal/gas167.c",; порядок аргументов сохраняется.
|
||||
"tests/gas167/gas167_test.c", "Source/Internal/gas167.c",
|
||||
# Продолжает текущий вызов, список или выражение: str(protocol / "src/ump_protocol.c"),; порядок аргументов сохраняется.
|
||||
str(protocol / "src/ump_protocol.c"),
|
||||
# Продолжает текущий вызов, список или выражение: str(protocol / "ports/tms320f28335/ump_tms28335.c"),; порядок аргументов сохраняется.
|
||||
str(protocol / "ports/tms320f28335/ump_tms28335.c"),
|
||||
# Задаёт "-o", str(exe)], cwd по выражению справа; значение используется последующими операциями.
|
||||
"-o", str(exe)], cwd=root, check=True)
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([str(exe)], check=True, timeout=10)
|
||||
|
||||
@@ -1,103 +1,197 @@
|
||||
/* Проверка load_control на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подключает <stdio.h>: настройки и интерфейс stdio. */
|
||||
#include <stdio.h>
|
||||
/* Подключает <string.h>: настройки и интерфейс string. */
|
||||
#include <string.h>
|
||||
/* Подключает "../../Source/Internal/DAC.c": выход ЦАП и автомат защиты нагрузки с проверкой напряжения и свежести CAN. */
|
||||
#include "../../Source/Internal/DAC.c"
|
||||
/* Объявляет READY — данные READY; Desk — аппаратно определённый тип платы; Mode — рабочий адрес или режим платы, выбранный перемычками. Начальное значение задаётся справа от знака равенства. */
|
||||
int READY = 1, Desk = 6, Mode = 5;
|
||||
/* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
int modbus[128];
|
||||
/* Объявляет test_start — данные test_start; test_stop — данные test_stop; test_permission — данные test_permission; test_tick — данные test_tick. */
|
||||
unsigned int test_start, test_stop, test_permission, test_tick;
|
||||
/* Объявляет test_starts — данные test_starts; test_last_stop_tick — данные test_last_stop_tick; test_last_start_tick — данные test_last_start_tick; test_init_dac — test init ЦАП. */
|
||||
unsigned int test_starts, test_last_stop_tick, test_last_start_tick, test_init_dac;
|
||||
/* Объявляет test_bad_order — данные test_bad_order. */
|
||||
int test_bad_order;
|
||||
/* Объявляет ump_dac_ramp — ump ЦАП ramp; ump_dac_duration — ump ЦАП duration; ump_dac_go10 — ump ЦАП go 10; ump_dac_stop10 — ump ЦАП stop 10; ump_dac_position — ump ЦАП position. */
|
||||
unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
/* Задаёт CHECK = do { if (!(x)) { printf("FAIL line %d: %s\n", __LINE__, #x); return 1; } } while (0); данные CHECK. */
|
||||
#define CHECK(x) do { if (!(x)) { printf("FAIL line %d: %s\n", __LINE__, #x); return 1; } } while (0)
|
||||
/* Начинает функцию setup; назначение модуля — проверка load_control на модели ПК. */
|
||||
static void setup(int mode) {
|
||||
/* Записывает Mode значением mode; READY = 1; рабочий адрес или режим платы, выбранный перемычками. */
|
||||
memset(modbus, 0, sizeof(modbus)); Mode = mode; READY = 1;
|
||||
/* Записывает test_start значением test_stop = test_permission = test_tick = test_starts = 0; данные test_start. */
|
||||
test_start = test_stop = test_permission = test_tick = test_starts = 0;
|
||||
/* Записывает test_bad_order значением test_init_dac = 0; данные test_bad_order. */
|
||||
test_bad_order = test_init_dac = 0;
|
||||
/* Записывает WAKEpowse значением 0; данные WAKEpowse. */
|
||||
Load_control_init(); Setup_DAC_time(); WAKEpowse = 0;
|
||||
/* Записывает DAC_go значением 4; DAC_stop = 16; DAC_min() = 100; DAC_max() = 3000; начальный ток нагрузки в мА, технологический регистр 0x50. */
|
||||
DAC_go = 4; DAC_stop = 16; DAC_min() = 100; DAC_max() = 3000;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию tick; назначение модуля — проверка load_control на модели ПК. */
|
||||
static void tick(unsigned int n, int exchange, unsigned int volts) {
|
||||
/* Повторяет или ожидает, пока выполняется while (n--). */
|
||||
while (n--) {
|
||||
/* Проверяет if (exchange) Load_voltage_can(0x8000U | (Mode == 5 ? 305U : 8U), volts, 0, 0); последующий оператор выполняется только при истинном условии. */
|
||||
if (exchange) Load_voltage_can(0x8000U | (Mode == 5 ? 305U : 8U), volts, 0, 0);
|
||||
/* Изменяет счётчик в выражении test_tick++; Load_runner(); на один для следующего шага. */
|
||||
test_tick++; Load_runner();
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||||
int main(void) {
|
||||
/* Объявляет out — данные out; error — ошибка; count — число; ramp — данные ramp; code — данные code. */
|
||||
unsigned int out[8], error, count, ramp, code, stopped_at;
|
||||
/* Вызывает setup с аргументами (5) в текущей последовательности операций. */
|
||||
setup(5);
|
||||
/* Boot ISR before parameters: no divide-by-zero and no GPIO start. */
|
||||
/* Записывает Commands значением 0x80; tick(10, 1, 0); CHECK(!test_starts); слово команд, технологический регистр 127. */
|
||||
Load_control_init(); Commands = 0x80; tick(10, 1, 0); CHECK(!test_starts);
|
||||
/* Записывает WAKEpowse значением 0; данные WAKEpowse. */
|
||||
Setup_DAC_time(); WAKEpowse = 0;
|
||||
/* Вызывает tick с аргументами (10, 0, 0); CHECK(test_starts == 1 && test_permission) в текущей последовательности операций. */
|
||||
tick(10, 0, 0); CHECK(test_starts == 1 && test_permission);
|
||||
/* Вызывает CHECK с аргументами (LOAD_CAN_TIMEOUT == 600) в текущей последовательности операций. */
|
||||
CHECK(LOAD_CAN_TIMEOUT == 600);
|
||||
/* Wrong ZPT and masked slots never confirm freshness. */
|
||||
/* Записывает Commands значением 0x80; слово команд, технологический регистр 127. */
|
||||
setup(5); Commands = 0x80;
|
||||
/* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */
|
||||
Load_voltage_can(0x8000U | 8U, 200, 0, 0);
|
||||
/* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */
|
||||
Load_voltage_can(305U, 200, 0, 0); tick(10, 0, 0);
|
||||
/* Вызывает CHECK с аргументами (!test_starts && (LOAD_STATUS & 2)) в текущей последовательности операций. */
|
||||
CHECK(!test_starts && (LOAD_STATUS & 2));
|
||||
/* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */
|
||||
Load_voltage_can(0x2000U | 303U, 0, 0, 30);
|
||||
/* Вызывает tick с аргументами (1, 0, 0); CHECK(test_starts == 1) в текущей последовательности операций. */
|
||||
tick(1, 0, 0); CHECK(test_starts == 1);
|
||||
/* Freeze current and code at timeout; unrelated exchange cannot unfreeze. */
|
||||
/* Вызывает tick с аргументами (1000, 1, 30); tick(600, 0, 0) в текущей последовательности операций. */
|
||||
tick(1000, 1, 30); tick(600, 0, 0);
|
||||
/* Записывает ramp значением ump_dac_ramp; code = modbus[123]; данные ramp. */
|
||||
ramp = ump_dac_ramp; code = modbus[123];
|
||||
/* Вызывает tick с аргументами (2000, 0, 0); CHECK(ump_dac_ramp == ramp && (unsigned int)modbus[123] == code) в текущей последовательности операций. */
|
||||
tick(2000, 0, 0); CHECK(ump_dac_ramp == ramp && (unsigned int)modbus[123] == code);
|
||||
/* Вызывает CHECK с аргументами (test_permission && !test_stop && (LOAD_STATUS & 2)) в текущей последовательности операций. */
|
||||
CHECK(test_permission && !test_stop && (LOAD_STATUS & 2));
|
||||
/* Вызывает Load_voltage_can. Принимает напряжение выбранной нагрузки из достоверных слов CAN и сбрасывает возраст только нужного измерения. */
|
||||
Load_voltage_can(0x8000U | 8U, 200, 0, 0); tick(10, 0, 0);
|
||||
/* Вызывает CHECK с аргументами (ump_dac_ramp == ramp) в текущей последовательности операций. */
|
||||
CHECK(ump_dac_ramp == ramp);
|
||||
/* Вызывает tick с аргументами (10, 1, 30); CHECK(ump_dac_ramp > ramp) в текущей последовательности операций. */
|
||||
tick(10, 1, 30); CHECK(ump_dac_ramp > ramp);
|
||||
/* Exactly 30 V permits growth; 29 V fails strictly above 6 mA. */
|
||||
/* Записывает Commands значением 0x80; tick(10, 1, 30); слово команд, технологический регистр 127. */
|
||||
setup(6); Commands = 0x80; tick(10, 1, 30);
|
||||
/* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 30); load число ramp. */
|
||||
load_count_ramp = time_dac / 6; tick(5, 1, 30);
|
||||
/* Вызывает CHECK с аргументами (load_state == LOAD_RUN && modbus[0x1C] >= 60) в текущей последовательности операций. */
|
||||
CHECK(load_state == LOAD_RUN && modbus[0x1C] >= 60);
|
||||
/* Вызывает tick с аргументами (5, 1, 29); CHECK(load_state == LOAD_RELOAD && test_stop && !test_permission) в текущей последовательности операций. */
|
||||
tick(5, 1, 29); CHECK(load_state == LOAD_RELOAD && test_stop && !test_permission);
|
||||
/* Вызывает CHECK с аргументами (!test_start && ump_dac_ramp == 0 && modbus[0x1C] == 40) в текущей последовательности операций. */
|
||||
CHECK(!test_start && ump_dac_ramp == 0 && modbus[0x1C] == 40);
|
||||
/* Записывает stopped_at значением test_last_stop_tick; данные stopped_at. */
|
||||
CHECK(modbus[123] == DAC_min()); stopped_at = test_last_stop_tick;
|
||||
/* Вызывает tick с аргументами (999, 1, 0); CHECK(test_starts == 1 && test_stop) в текущей последовательности операций. */
|
||||
tick(999, 1, 0); CHECK(test_starts == 1 && test_stop);
|
||||
/* Вызывает tick с аргументами (1, 1, 0); CHECK(test_starts == 2 && test_last_start_tick-stopped_at == 1000) в текущей последовательности операций. */
|
||||
tick(1, 1, 0); CHECK(test_starts == 2 && test_last_start_tick-stopped_at == 1000);
|
||||
/* Вызывает CHECK с аргументами (!test_stop && test_permission && !test_bad_order) в текущей последовательности операций. */
|
||||
CHECK(!test_stop && test_permission && !test_bad_order);
|
||||
/* Five total attempts, then a persistent fault; no sixth start. */
|
||||
/* Повторяет или ожидает, пока выполняется while (load_state != LOAD_FAULT). */
|
||||
while (load_state != LOAD_FAULT) {
|
||||
/* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 0); load число ramp. */
|
||||
load_count_ramp = time_dac / 6; tick(5, 1, 0);
|
||||
/* Проверяет if (load_state == LOAD_RELOAD) tick(1000, 1, 0); последующий оператор выполняется только при истинном условии. */
|
||||
if (load_state == LOAD_RELOAD) tick(1000, 1, 0);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Вызывает CHECK с аргументами (test_starts == 5 && LOAD_ATTEMPTS == 5 && (LOAD_STATUS & 1)) в текущей последовательности операций. */
|
||||
CHECK(test_starts == 5 && LOAD_ATTEMPTS == 5 && (LOAD_STATUS & 1));
|
||||
/* Вызывает tick с аргументами (3000, 1, 200); CHECK(test_starts == 5 && test_stop && !test_permission) в текущей последовательности операций. */
|
||||
tick(3000, 1, 200); CHECK(test_starts == 5 && test_stop && !test_permission);
|
||||
/* Записывает Commands значением 0xC0; tick(10, 1, 200); CHECK(load_state == LOAD_FAULT); слово команд, технологический регистр 127. */
|
||||
Commands = 0xC0; tick(10, 1, 200); CHECK(load_state == LOAD_FAULT);
|
||||
/* Записывает Commands значением 0; tick(1000, 1, 200); CHECK(!(LOAD_STATUS & 1)); слово команд, технологический регистр 127. */
|
||||
Commands = 0; tick(1000, 1, 200); CHECK(!(LOAD_STATUS & 1));
|
||||
/* Записывает Commands значением 0x80; test_starts = 0; tick(10, 1, 200); CHECK(LOAD_ATTEMPTS == 1); слово команд, технологический регистр 127. */
|
||||
Commands = 0x80; test_starts = 0; tick(10, 1, 200); CHECK(LOAD_ATTEMPTS == 1);
|
||||
/* Manual reset dominates START; releasing it alone cannot start again. */
|
||||
/* Записывает Commands значением 0xC0; tick(1, 1, 200); CHECK(test_stop && !test_permission); слово команд, технологический регистр 127. */
|
||||
Commands = 0xC0; tick(1, 1, 200); CHECK(test_stop && !test_permission);
|
||||
/* Записывает Commands значением 0x80; tick(1500, 1, 200); CHECK(test_starts == 1); слово команд, технологический регистр 127. */
|
||||
Commands = 0x80; tick(1500, 1, 200); CHECK(test_starts == 1);
|
||||
/* Versioned simulation writes are bounded, read-only fields reject writes. */
|
||||
/* Записывает count значением Load_protection_prepare(3, 0x1300, 8, out, &error); число. */
|
||||
count = Load_protection_prepare(3, 0x1300, 8, out, &error);
|
||||
/* Вызывает CHECK с аргументами (count == 8 && !error && out[0] == 0x5550 && out[1] == 1) в текущей последовательности операций. */
|
||||
CHECK(count == 8 && !error && out[0] == 0x5550 && out[1] == 1);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1303, 0, out, &error); CHECK(error == 3);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1304, 0, out, &error); CHECK(error == 2);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1302, 4, out, &error); CHECK(error == 3);
|
||||
/* Записывает Commands значением 0x80; tick(10, 1, 200); слово команд, технологический регистр 127. */
|
||||
setup(5); Commands = 0x80; tick(10, 1, 200);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1303, 20, out, &error); CHECK(!error);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1302, 1, out, &error); CHECK(!error);
|
||||
/* Вызывает tick с аргументами (30, 1, 200); CHECK(LOAD_STATUS & 2) в текущей последовательности операций. */
|
||||
tick(30, 1, 200); CHECK(LOAD_STATUS & 2);
|
||||
/* Записывает ramp значением ump_dac_ramp; tick(100, 1, 200); CHECK(ump_dac_ramp == ramp); данные ramp. */
|
||||
ramp = ump_dac_ramp; tick(100, 1, 200); CHECK(ump_dac_ramp == ramp);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1302, 0, out, &error);
|
||||
/* Вызывает tick с аргументами (10, 1, 200); CHECK(!(LOAD_STATUS & 2) && ump_dac_ramp > ramp) в текущей последовательности операций. */
|
||||
tick(10, 1, 200); CHECK(!(LOAD_STATUS & 2) && ump_dac_ramp > ramp);
|
||||
/* Вызывает Load_protection_prepare. Фиксирует управляющие входы перед выполнением автомата защиты нагрузки. */
|
||||
Load_protection_prepare(6, 0x1302, 2, out, &error);
|
||||
/* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 200); CHECK(load_state == LOAD_RELOAD); load число ramp. */
|
||||
load_count_ramp = time_dac / 6; tick(5, 1, 200); CHECK(load_state == LOAD_RELOAD);
|
||||
/* Calibration must not replace the forced 4 mA output during reload. */
|
||||
/* Устанавливает биты Commands значением 0x200; DAC_cal() = 4095; tick(5, 1, 200); слово команд, технологический регистр 127. */
|
||||
Commands |= 0x200; DAC_cal() = 4095; tick(5, 1, 200);
|
||||
/* Вызывает CHECK с аргументами (modbus[123] == DAC_min() && modbus[0x1C] == 40) в текущей последовательности операций. */
|
||||
CHECK(modbus[123] == DAC_min() && modbus[0x1C] == 40);
|
||||
/* A calibration code preceding START must be replaced by 4 mA first. */
|
||||
/* Записывает Commands значением 0x200; DAC_cal() = 4095; слово команд, технологический регистр 127. */
|
||||
setup(5); Commands = 0x200; DAC_cal() = 4095;
|
||||
/* Вызывает tick с аргументами (10, 1, 200); CHECK(modbus[123] == 4095 && !load_zero_sent) в текущей последовательности операций. */
|
||||
tick(10, 1, 200); CHECK(modbus[123] == 4095 && !load_zero_sent);
|
||||
/* Записывает Commands значением 0x280; tick(1, 1, 200); CHECK(!test_starts); слово команд, технологический регистр 127. */
|
||||
Commands = 0x280; tick(1, 1, 200); CHECK(!test_starts);
|
||||
/* Вызывает tick с аргументами (4, 1, 200); CHECK(!test_starts && modbus[123] == DAC_min()) в текущей последовательности операций. */
|
||||
tick(4, 1, 200); CHECK(!test_starts && modbus[123] == DAC_min());
|
||||
/* Вызывает tick с аргументами (1, 1, 200); CHECK(test_starts == 1) в текущей последовательности операций. */
|
||||
tick(1, 1, 200); CHECK(test_starts == 1);
|
||||
/* Timeout while STOP is held cannot initiate the pending retry. */
|
||||
/* Записывает Commands значением 0x80; tick(10, 1, 0); слово команд, технологический регистр 127. */
|
||||
setup(5); Commands = 0x80; tick(10, 1, 0);
|
||||
/* Записывает load_count_ramp значением time_dac / 6; tick(5, 1, 0); load число ramp. */
|
||||
load_count_ramp = time_dac / 6; tick(5, 1, 0);
|
||||
/* Вызывает CHECK с аргументами (load_state == LOAD_RELOAD) в текущей последовательности операций. */
|
||||
CHECK(load_state == LOAD_RELOAD);
|
||||
/* Вызывает tick с аргументами (1500, 0, 0); CHECK(test_starts == 1 && test_stop) в текущей последовательности операций. */
|
||||
tick(1500, 0, 0); CHECK(test_starts == 1 && test_stop);
|
||||
/* Вызывает tick с аргументами (1, 1, 0); CHECK(test_starts == 2 && !test_stop) в текущей последовательности операций. */
|
||||
tick(1, 1, 0); CHECK(test_starts == 2 && !test_stop);
|
||||
/* Вызывает Load_control_init. Сбрасывает все переменные автомата нагрузки до разрешения прерываний; COFF не обнуляет всю .ebss. */
|
||||
Load_control_init(); CHECK(!load_simulation);
|
||||
/* Вызывает puts с аргументами ("PASS: production DAC control, timeout, CAN slots, STOP ordering, five attempts, simulation") в текущей последовательности операций. */
|
||||
puts("PASS: production DAC control, timeout, CAN slots, STOP ordering, five attempts, simulation");
|
||||
/* Завершает main и возвращает 0. */
|
||||
return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
# Проверка load_control на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Compile the production DAC.c against GPIO/IRQ mocks; no hardware writes."""; порядок аргументов сохраняется.
|
||||
"""Compile the production DAC.c against GPIO/IRQ mocks; no hardware writes."""
|
||||
# Подключает модуль os для этой проверки или подготовки сборки.
|
||||
import os
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль shutil для этой проверки или подготовки сборки.
|
||||
import shutil
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
|
||||
# Задаёт root по выражению справа; значение используется последующими операциями.
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
# Задаёт compiler по выражению справа; значение используется последующими операциями.
|
||||
compiler = os.environ.get('CC') or shutil.which('gcc') or 'C:/msys64/mingw64/bin/gcc.exe'
|
||||
# Задаёт os.environ['PATH'] по выражению справа; значение используется последующими операциями.
|
||||
os.environ['PATH'] = str(Path(compiler).resolve().parent) + os.pathsep + os.environ['PATH']
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix='load-control-') as tmp с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory(prefix='load-control-') as tmp:
|
||||
# Задаёт exe по выражению справа; значение используется последующими операциями.
|
||||
exe = Path(tmp) / 'test.exe'
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([compiler, '-Wall', '-Wextra', '-std=c99',
|
||||
# Продолжает текущий вызов, список или выражение: '-Itests/load_control/stubs', '-ISource/Internal/Include',; порядок аргументов сохраняется.
|
||||
'-Itests/load_control/stubs', '-ISource/Internal/Include',
|
||||
# Задаёт 'tests/load_control/load_control_test.c', '-o', str(exe)], cwd по выражению справа; значение используется последующими операциями.
|
||||
'tests/load_control/load_control_test.c', '-o', str(exe)], cwd=root, check=True)
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([str(exe)], check=True, timeout=10)
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Начинает условие: TEST_DEVICE_H ещё не определён; защищает повторное включение или задаёт значение сборки. */
|
||||
#ifndef TEST_DEVICE_H
|
||||
/* Определяет защитный символ или переключатель TEST_DEVICE_H для последующей компиляции. */
|
||||
#define TEST_DEVICE_H
|
||||
/* Описывает структуру bits; порядок полей определяет расположение данных. */
|
||||
struct bits { unsigned int GPIO59, GPIO60, GPIO63; };
|
||||
/* Описывает структуру reg; порядок полей определяет расположение данных. */
|
||||
struct reg { struct bits bit; };
|
||||
/* Продолжает список аргументов, полей или выражение static struct { struct reg GPBSET, GPBCLEAR; } GpioDataRegs;; порядок элементов сохраняется. */
|
||||
static struct { struct reg GPBSET, GPBCLEAR; } GpioDataRegs;
|
||||
/* Начинает функцию __disable_interrupts; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static unsigned int __disable_interrupts(void) { return 0; }
|
||||
/* Начинает функцию __restore_interrupts; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void __restore_interrupts(unsigned int saved) { (void)saved; }
|
||||
/* Начинает функцию DSP28x_usDelay; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void DSP28x_usDelay(unsigned long n) { (void)n; }
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* No IRQ registers needed in the host test. */
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* No serial dependencies in the host test. */
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* No filter dependencies in the host test. */
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Задаёт READY_FREQ = 1000; частота основного такта Timer1 в герцах. */
|
||||
#define READY_FREQ 1000
|
||||
/* Задаёт DAC_FREQ = 200; частота обновления тока ЦАП в герцах. */
|
||||
#define DAC_FREQ 200
|
||||
/* Задаёт LOAD_TIME = 30; время нарастания тока нагрузки в секундах. */
|
||||
#define LOAD_TIME 30
|
||||
/* Объявляет READY — данные READY. Память определена в другом модуле. */
|
||||
extern int READY;
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит. Память определена в другом модуле. */
|
||||
extern int modbus[128];
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Задаёт dsk_LOAD = 6; код платы нагрузки. */
|
||||
#define dsk_LOAD 6
|
||||
/* Задаёт adr_LOA1 = 5; данные adr_LOA1. */
|
||||
#define adr_LOA1 5
|
||||
/* Задаёт adr_LOA2 = 6; данные adr_LOA2. */
|
||||
#define adr_LOA2 6
|
||||
/* Задаёт Commands = modbus[127]; слово команд, технологический регистр 127. */
|
||||
#define Commands modbus[127]
|
||||
/* Задаёт cUMPstart = (Commands & 0x80); данные cUMPstart. */
|
||||
#define cUMPstart (Commands & 0x80)
|
||||
/* Задаёт cUMPreset = (Commands & 0x40); данные cUMPreset. */
|
||||
#define cUMPreset (Commands & 0x40)
|
||||
/* Объявляет test_init_dac — test init ЦАП. Память определена в другом модуле. */
|
||||
extern unsigned int test_init_dac;
|
||||
/* Задаёт cInitDac = test_init_dac; c Init ЦАП. */
|
||||
#define cInitDac test_init_dac
|
||||
/* Задаёт cCalibrDac = (Commands & 0x200); c Calibr ЦАП. */
|
||||
#define cCalibrDac (Commands & 0x200)
|
||||
/* Задаёт DAC_go = modbus[0x50]; начальный ток нагрузки в мА, технологический регистр 0x50. */
|
||||
#define DAC_go modbus[0x50]
|
||||
/* Задаёт DAC_stop = modbus[0x51]; конечный ток нагрузки в мА, технологический регистр 0x51. */
|
||||
#define DAC_stop modbus[0x51]
|
||||
/* Задаёт LOAD_CAN_TIMEOUT = modbus[0x52]; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */
|
||||
#define LOAD_CAN_TIMEOUT modbus[0x52]
|
||||
/* Задаёт LOAD_STATUS = modbus[0x7C]; слово состояния защиты нагрузки для чтения, регистр 0x7C. */
|
||||
#define LOAD_STATUS modbus[0x7C]
|
||||
/* Задаёт LOAD_ATTEMPTS = modbus[0x7D]; число попыток пуска для чтения, регистр 0x7D. */
|
||||
#define LOAD_ATTEMPTS modbus[0x7D]
|
||||
/* Задаёт DAC_min = modbus[0x79]; ЦАП min. */
|
||||
#define DAC_min() modbus[0x79]
|
||||
/* Задаёт DAC_max = modbus[0x78]; ЦАП max. */
|
||||
#define DAC_max() modbus[0x78]
|
||||
/* Задаёт DAC_cal = modbus[0x7A]; ЦАП cal. */
|
||||
#define DAC_cal() modbus[0x7A]
|
||||
|
||||
@@ -1,14 +1,29 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Объявляет Desk — аппаратно определённый тип платы; Mode — рабочий адрес или режим платы, выбранный перемычками. Память определена в другом модуле. */
|
||||
extern int Desk, Mode;
|
||||
/* Объявляет test_start — данные test_start; test_stop — данные test_stop; test_permission — данные test_permission; test_tick — данные test_tick. Память определена в другом модуле. */
|
||||
extern unsigned int test_start, test_stop, test_permission, test_tick;
|
||||
/* Объявляет test_starts — данные test_starts; test_last_stop_tick — данные test_last_stop_tick; test_last_start_tick — данные test_last_start_tick. Память определена в другом модуле. */
|
||||
extern unsigned int test_starts, test_last_stop_tick, test_last_start_tick;
|
||||
/* Объявляет test_bad_order — данные test_bad_order. Память определена в другом модуле. */
|
||||
extern int test_bad_order;
|
||||
/* Начинает функцию clear_START_DPTB; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void clear_START_DPTB(void) { test_start = 0; }
|
||||
/* Начинает функцию set_START_DPTB; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void set_START_DPTB(void) {
|
||||
/* Проверяет if (test_stop или (test_starts и test_tick-test_last_stop_tick < 1000)) test_bad_order = 1; последующий оператор выполняется только при истинном условии. */
|
||||
if (test_stop || (test_starts && test_tick-test_last_stop_tick < 1000)) test_bad_order = 1;
|
||||
/* Записывает test_start значением 1; test_last_start_tick = test_tick; test_starts++; данные test_start. */
|
||||
test_start = 1; test_last_start_tick = test_tick; test_starts++;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию set_STOP_DPTB; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void set_STOP_DPTB(void) { test_stop = 1; test_last_stop_tick = test_tick; }
|
||||
/* Начинает функцию clear_STOP_DPTB; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void clear_STOP_DPTB(void) { test_stop = 0; }
|
||||
/* Начинает функцию clear_RES_OUT_2; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void clear_RES_OUT_2(void) { test_permission = 0; }
|
||||
/* Начинает функцию set_RES_OUT_2; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void set_RES_OUT_2(void) { if (!test_start || test_stop) test_bad_order = 1; test_permission = 1; }
|
||||
/* Начинает функцию toggle_RES_OUT_1; назначение модуля — проверка load_control/stubs на модели ПК. */
|
||||
static void toggle_RES_OUT_1(void) {}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка load_control/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Delay provided by the device stub. */
|
||||
|
||||
@@ -1,118 +1,229 @@
|
||||
/* Проверка rs232_fifo на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
|
||||
/* Продолжает список аргументов, полей или выражение volatile struct SCI_REGS SciaRegs,ScibRegs;; порядок элементов сохраняется. */
|
||||
volatile struct SCI_REGS SciaRegs,ScibRegs;
|
||||
/* Описывает структуру ; порядок полей определяет расположение данных. */
|
||||
struct { struct { struct { unsigned ACK9; } bit; } PIEACK; } PieCtrlRegs;
|
||||
/* Описывает структуру ; порядок полей определяет расположение данных. */
|
||||
struct { struct { struct { unsigned GPIO34; } bit; } GPBDAT; } GpioDataRegs;
|
||||
/* Объявляет rs_a — данные rs_a; rs_b — данные rs_b. */
|
||||
RS_DATA rs_a,rs_b;
|
||||
/* Объявляет RS_Len — таблица ожидаемых длин команд последовательного протокола; irq — данные irq. */
|
||||
unsigned int RS_Len[70],irq;
|
||||
/* Объявляет load_memory — данные load_memory. */
|
||||
static unsigned int load_memory[4100];
|
||||
/* Начинает функцию __disable_interrupts; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static unsigned int __disable_interrupts(void) { unsigned old=irq;irq=1;return old; }
|
||||
/* Начинает функцию __restore_interrupts; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void __restore_interrupts(unsigned state) { irq=state; }
|
||||
/* Начинает функцию RS_SetLineMode; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
void RS_SetLineMode(RS_DATA *p,int bits,char parity,int stop)
|
||||
/* Продолжает список аргументов, полей или выражение { (void)p;(void)bits;(void)parity;(void)stop; }; порядок элементов сохраняется. */
|
||||
{ (void)p;(void)bits;(void)parity;(void)stop; }
|
||||
/* Объявляет length — длина; wire_count — wire число. */
|
||||
static unsigned int queue[2][16],length[2],wire[2][20000],wire_count[2];
|
||||
/* Объявляет rx_count — rx число; rx_pos — данные rx_pos; shift_pending — данные shift_pending; shift_checks — данные shift_checks. */
|
||||
static unsigned int rx[2][16],rx_count[2],rx_pos[2],shift_pending[2],shift_checks;
|
||||
/* Начинает функцию port; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static unsigned int port(RS_DATA *p) {return p->commnumber-1;}
|
||||
/* Начинает функцию model_interrupts; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void model_interrupts(RS_DATA *p,unsigned tx)
|
||||
/* Записывает p->SciRegs->SCICTL2.bit.TXINTENA значением tx;p->SciRegs->SCICTL2.bit.RXBKINTENA=!tx; }; данные TXINTENA. */
|
||||
{ p->SciRegs->SCICTL2.bit.TXINTENA=tx;p->SciRegs->SCICTL2.bit.RXBKINTENA=!tx; }
|
||||
/* Начинает функцию model_flush; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void model_flush(RS_DATA *p)
|
||||
/* Записывает i значением port(p);rx_count[i]=rx_pos[i]=0;p->SciRegs->SCIFFRX.bit.RXFFST=0;p->SciRegs->SCIFFRX.bit.RXFFOVF=0; }; данные i. */
|
||||
{ unsigned i=port(p);rx_count[i]=rx_pos[i]=0;p->SciRegs->SCIFFRX.bit.RXFFST=0;p->SciRegs->SCIFFRX.bit.RXFFOVF=0; }
|
||||
/* Начинает функцию model_pop; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static unsigned int model_pop(RS_DATA *p)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает i значением port(p),v;assert(rx_pos[i]<rx_count[i]);v=rx[i][rx_pos[i]++]; данные i. */
|
||||
unsigned i=port(p),v;assert(rx_pos[i]<rx_count[i]);v=rx[i][rx_pos[i]++];
|
||||
/* Записывает p->SciRegs->SCIFFRX.bit.RXFFST значением rx_count[i]-rx_pos[i]; данные RXFFST. */
|
||||
p->SciRegs->SCIFFRX.bit.RXFFST=rx_count[i]-rx_pos[i];
|
||||
/* Записывает p->SciRegs->SCIRXST.bit.RXRDY значением rx_pos[i]<rx_count[i];return v; данные RXRDY. */
|
||||
p->SciRegs->SCIRXST.bit.RXRDY=rx_pos[i]<rx_count[i];return v;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию model_push; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void model_push(RS_DATA *p,unsigned v)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает i значением port(p);assert(length[i]<16);queue[i][length[i]++]=v&255; данные i. */
|
||||
unsigned i=port(p);assert(length[i]<16);queue[i][length[i]++]=v&255;
|
||||
/* Проверяет if(i==0)p->SciRegs->SCIFFTX.bit.TXFFST=length[i]; последующий оператор выполняется только при истинном условии. */
|
||||
if(i==0)p->SciRegs->SCIFFTX.bit.TXFFST=length[i];
|
||||
/* Записывает p->SciRegs->SCICTL2.bit.TXEMPTY значением 0; данные TXEMPTY. */
|
||||
p->SciRegs->SCICTL2.bit.TXEMPTY=0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию model_shift; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void model_shift(RS_DATA *p)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает i значением port(p);assert(length[i]==0); данные i. */
|
||||
unsigned i=port(p);assert(length[i]==0);
|
||||
if(i==0)assert(p->fifo_tx_active); /* last symbol cannot finish early */
|
||||
if(i==0)assert(p->fifo_tx_active); /* last symbol cannot finish early */ /* Проверяет if(i==0)assert(p->fifo_tx_active); последующий оператор выполняется только при истинном условии. */
|
||||
/* Записывает shift_pending[i] значением 0;p->SciRegs->SCICTL2.bit.TXEMPTY=1;shift_checks++; данные shift_pending. */
|
||||
shift_pending[i]=0;p->SciRegs->SCICTL2.bit.TXEMPTY=1;shift_checks++;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию model_step; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void model_step(RS_DATA *p)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает i значением port(p),j; данные i. */
|
||||
unsigned i=port(p),j;
|
||||
/* Проверяет if(length[i]); последующий оператор выполняется только при истинном условии. */
|
||||
if(length[i]) {
|
||||
/* Изменяет счётчик в выражении wire[i][wire_count[i]++]=queue[i][0]; на один для следующего шага. */
|
||||
wire[i][wire_count[i]++]=queue[i][0];
|
||||
/* Цикл for(j=1;j<length[i];j++)queue[i][j-1]=queue[i][j];; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(j=1;j<length[i];j++)queue[i][j-1]=queue[i][j];
|
||||
/* Записывает shift_pending[i] значением 1; данные shift_pending. */
|
||||
length[i]--;shift_pending[i]=1;
|
||||
/* Проверяет if(i==0)p->SciRegs->SCIFFTX.bit.TXFFST=length[i]; последующий оператор выполняется только при истинном условии. */
|
||||
if(i==0)p->SciRegs->SCIFFTX.bit.TXFFST=length[i];
|
||||
/* Проверяет else if(shift_pending[i]) model_shift(p); последующий оператор выполняется только при истинном условии. */
|
||||
} else if(shift_pending[i]) model_shift(p);
|
||||
/* Проверяет if(i==0 и p->SciRegs->SCIFFTX.bit.TXFFIENA и; последующий оператор выполняется только при истинном условии. */
|
||||
if(i==0 && p->SciRegs->SCIFFTX.bit.TXFFIENA &&
|
||||
/* Продолжает список аргументов, полей или выражение length[i]<=p->SciRegs->SCIFFTX.bit.TXFFIL) RS_TX_Handler(p);; порядок элементов сохраняется. */
|
||||
length[i]<=p->SciRegs->SCIFFTX.bit.TXFFIL) RS_TX_Handler(p);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию reset; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void reset(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Вызывает memset с аргументами (&rs_a,0,sizeof(rs_a));memset(&rs_b,0,sizeof(rs_b)) в текущей последовательности операций. */
|
||||
memset(&rs_a,0,sizeof(rs_a));memset(&rs_b,0,sizeof(rs_b));
|
||||
/* Вызывает memset с аргументами ((void *)&SciaRegs,0,sizeof(SciaRegs));memset((void *)&ScibRegs,0,sizeof(ScibRegs)) в текущей последовательности операций. */
|
||||
memset((void *)&SciaRegs,0,sizeof(SciaRegs));memset((void *)&ScibRegs,0,sizeof(ScibRegs));
|
||||
/* Вызывает memset с аргументами (length,0,sizeof(length));memset(wire_count,0,sizeof(wire_count)) в текущей последовательности операций. */
|
||||
memset(length,0,sizeof(length));memset(wire_count,0,sizeof(wire_count));
|
||||
/* Вызывает memset с аргументами (rx_count,0,sizeof(rx_count));memset(rx_pos,0,sizeof(rx_pos)) в текущей последовательности операций. */
|
||||
memset(rx_count,0,sizeof(rx_count));memset(rx_pos,0,sizeof(rx_pos));
|
||||
/* Вызывает memset с аргументами (shift_pending,0,sizeof(shift_pending)) в текущей последовательности операций. */
|
||||
memset(shift_pending,0,sizeof(shift_pending));
|
||||
/* Записывает rs_a.commnumber значением 1;rs_b.commnumber=2;rs_a.SciRegs=&SciaRegs;rs_b.SciRegs=&ScibRegs; данные commnumber. */
|
||||
rs_a.commnumber=1;rs_b.commnumber=2;rs_a.SciRegs=&SciaRegs;rs_b.SciRegs=&ScibRegs;
|
||||
/* Записывает SciaRegs.SCICTL2.bit.TXEMPTY значением ScibRegs.SCICTL2.bit.TXEMPTY=1; данные TXEMPTY. */
|
||||
SciaRegs.SCICTL2.bit.TXEMPTY=ScibRegs.SCICTL2.bit.TXEMPTY=1;
|
||||
/* Записывает rs_a.RS_Flag9bit значением rs_b.RS_Flag9bit=1; RS флаг 9 бит. */
|
||||
rs_a.RS_Flag9bit=rs_b.RS_Flag9bit=1;
|
||||
/* Записывает RS_Len[3] значением 8;RS_Len[6]=8;RS_Len[16]=13;RS_Len[51]=12; таблица ожидаемых длин команд последовательного протокола. */
|
||||
RS_Len[3]=8;RS_Len[6]=8;RS_Len[16]=13;RS_Len[51]=12;
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO34 значением 1;irq=0; аппаратная линия ввода/вывода GPIO34. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO34=1;irq=0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Начинает функцию feed; назначение модуля — проверка rs232_fifo на модели ПК. */
|
||||
static void feed(RS_DATA *p,const unsigned *bytes,unsigned n)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает i значением port(p),j;assert(n<=16);rx_pos[i]=0;rx_count[i]=n; данные i. */
|
||||
unsigned i=port(p),j;assert(n<=16);rx_pos[i]=0;rx_count[i]=n;
|
||||
/* Цикл for(j=0;j<n;j++)rx[i][j]=bytes[j];; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(j=0;j<n;j++)rx[i][j]=bytes[j];
|
||||
/* Записывает p->SciRegs->SCIFFRX.bit.RXFFST значением n;p->SciRegs->SCIRXST.bit.RXRDY=n!=0; данные RXFFST. */
|
||||
p->SciRegs->SCIFFRX.bit.RXFFST=n;p->SciRegs->SCIRXST.bit.RXRDY=n!=0;
|
||||
/* Вызывает RS_RX_Handler. Разбирает приём SCI; для COM_1 читает FIFO и проверяет ошибки, для COM_2 сохраняет штатный обмен RS485. */
|
||||
RS_RX_Handler(p);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* HANDLERS */
|
||||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||||
int main(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Продолжает список аргументов, полей или выражение unsigned data[4200],sizes[]={0,1,2,7,8,15,16,17,31,120,253,400,8194};; порядок элементов сохраняется. */
|
||||
unsigned data[4200],sizes[]={0,1,2,7,8,15,16,17,31,120,253,400,8194};
|
||||
/* Продолжает список аргументов, полей или выражение unsigned a,n,i,mode;unsigned request[]={16,3,0x10,0,0,16,0,0};; порядок элементов сохраняется. */
|
||||
unsigned a,n,i,mode;unsigned request[]={16,3,0x10,0,0,16,0,0};
|
||||
/* Цикл for(mode=0;mode<2;mode++)for(a=0;a<sizeof(sizes)/sizeof(sizes[0]);a++) ; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(mode=0;mode<2;mode++)for(a=0;a<sizeof(sizes)/sizeof(sizes[0]);a++) {
|
||||
/* Записывает n значением sizes[a];for(i=0;i<4200;i++)data[i]=(i*131U+17U)&65535; данные n. */
|
||||
reset();n=sizes[a];for(i=0;i<4200;i++)data[i]=(i*131U+17U)&65535;
|
||||
/* Проверяет if(mode==0 и n>4200)continue; последующий оператор выполняется только при истинном условии. */
|
||||
if(mode==0 && n>4200)continue;
|
||||
/* Вызывает assert с аргументами ((mode ? RS_BSend(&rs_a,data,n):RS_Send(&rs_a,data,n))==0) в текущей последовательности операций. */
|
||||
assert((mode ? RS_BSend(&rs_a,data,n):RS_Send(&rs_a,data,n))==0);
|
||||
/* Проверяет if(n и rs_a.fifo_tx_active)assert(rs_a.RS_Flag9bit==0); последующий оператор выполняется только при истинном условии. */
|
||||
if(n && rs_a.fifo_tx_active)assert(rs_a.RS_Flag9bit==0);
|
||||
/* Вызывает RS_FifoWait. Ожидает завершения аппаратной передачи FIFO и сдвигового регистра SCI. */
|
||||
RS_FifoWait(&rs_a);assert(!rs_a.fifo_tx_active && wire_count[0]==n);
|
||||
/* Цикл for(i=0;i<n;i++)assert(wire[0][i]==(mode?((i&1)?LOBYTE(data[i/2]):HIBYTE(data[i/2])):LOBYTE(data[i])));; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(i=0;i<n;i++)assert(wire[0][i]==(mode?((i&1)?LOBYTE(data[i/2]):HIBYTE(data[i/2])):LOBYTE(data[i])));
|
||||
assert(GpioDataRegs.GPBDAT.bit.GPIO34==1); /* RS232 never touches DE */
|
||||
assert(GpioDataRegs.GPBDAT.bit.GPIO34==1); /* RS232 never touches DE */ /* Вызывает assert с аргументами (GpioDataRegs.GPBDAT.bit.GPIO34==1) в текущей последовательности операций. */
|
||||
/* Вызывает assert с аргументами (!irq) в текущей последовательности операций. */
|
||||
assert(!irq);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Вызывает assert с аргументами (shift_checks>0) в текущей последовательности операций. */
|
||||
assert(shift_checks>0);
|
||||
/* Вызывает reset с аргументами ();feed(&rs_a,request,8);assert(rs_a.RS_DataReady && rs_a.RS_HeaderCnt==8) в текущей последовательности операций. */
|
||||
reset();feed(&rs_a,request,8);assert(rs_a.RS_DataReady && rs_a.RS_HeaderCnt==8);
|
||||
/* Вызывает reset с аргументами ();feed(&rs_a,request,3);feed(&rs_a,request+3,5);assert(rs_a.RS_DataReady) в текущей последовательности операций. */
|
||||
reset();feed(&rs_a,request,3);feed(&rs_a,request+3,5);assert(rs_a.RS_DataReady);
|
||||
/* LOAD payload, including a short final chunk: nothing waits for byte 8. */
|
||||
/* Записывает rs_a.RS_PrevCmd значением CMD_INITLOAD;rs_a.RS_Length=8194; данные RS_PrevCmd. */
|
||||
reset();rs_a.RS_PrevCmd=CMD_INITLOAD;rs_a.RS_Length=8194;
|
||||
/* Записывает rs_a.pRS_RecvPtr значением rs_a.pRecvPtr=load_memory; данные pRS_RecvPtr. */
|
||||
rs_a.pRS_RecvPtr=rs_a.pRecvPtr=load_memory;
|
||||
/* Записывает data[0] значением 16;data[1]=CMD_LOAD;feed(&rs_a,data,2); данные. */
|
||||
data[0]=16;data[1]=CMD_LOAD;feed(&rs_a,data,2);
|
||||
/* Цикл for(a=0;a<8194;a+=n) ; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(a=0;a<8194;a+=n) {
|
||||
/* Записывает n значением 8194-a;n=n<16?n:16; данные n. */
|
||||
n=8194-a;n=n<16?n:16;
|
||||
/* Цикл for(i=0;i<n;i++)data[i]=(a+i)&255;; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(i=0;i<n;i++)data[i]=(a+i)&255;
|
||||
/* Вызывает feed с аргументами (&rs_a,data,n) в текущей последовательности операций. */
|
||||
feed(&rs_a,data,n);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Вызывает assert с аргументами (rs_a.RS_DataReady && rs_a.RS_RecvLen==8194) в текущей последовательности операций. */
|
||||
assert(rs_a.RS_DataReady && rs_a.RS_RecvLen==8194);
|
||||
/* Цикл for(i=0;i<4097;i++)assert(load_memory[i]==(((2*i)&255)<<8 | ((2*i+1)&255)));; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(i=0;i<4097;i++)assert(load_memory[i]==(((2*i)&255)<<8 | ((2*i+1)&255)));
|
||||
/* Записывает data[0] значением 1;data[1]=2;RS_Send(&rs_a,data,2); данные. */
|
||||
reset();data[0]=1;data[1]=2;RS_Send(&rs_a,data,2);
|
||||
/* Вызывает feed с аргументами (&rs_b,request,8);assert(rs_b.RS_DataReady && rs_a.fifo_tx_active) в текущей последовательности операций. */
|
||||
feed(&rs_b,request,8);assert(rs_b.RS_DataReady && rs_a.fifo_tx_active);
|
||||
/* Вызывает RS_FifoWait. Ожидает завершения аппаратной передачи FIFO и сдвигового регистра SCI. */
|
||||
RS_FifoWait(&rs_a);
|
||||
/* Записывает request[3] значением 0xC000;feed(&rs_a,request,8); данные request. */
|
||||
reset();request[3]=0xC000;feed(&rs_a,request,8);
|
||||
/* Вызывает assert с аргументами (!rs_a.RS_DataReady && rs_a.fifo_rx_errors==1 && rs_a.fifo_rx_guard) в текущей последовательности операций. */
|
||||
assert(!rs_a.RS_DataReady && rs_a.fifo_rx_errors==1 && rs_a.fifo_rx_guard);
|
||||
/* Записывает request[3] значением 0;feed(&rs_a,request,8);assert(!rs_a.RS_DataReady); данные request. */
|
||||
request[3]=0;feed(&rs_a,request,8);assert(!rs_a.RS_DataReady);
|
||||
/* Цикл for(i=0;i<4;i++)RS_FifoTick1ms();; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(i=0;i<4;i++)RS_FifoTick1ms();
|
||||
/* Вызывает feed с аргументами (&rs_a,request,8);assert(rs_a.RS_DataReady) в текущей последовательности операций. */
|
||||
feed(&rs_a,request,8);assert(rs_a.RS_DataReady);
|
||||
/* Записывает SciaRegs.SCIFFRX.bit.RXFFOVF значением 1;RS_RX_Handler(&rs_a); данные RXFFOVF. */
|
||||
reset();SciaRegs.SCIFFRX.bit.RXFFOVF=1;RS_RX_Handler(&rs_a);
|
||||
/* Вызывает assert с аргументами (rs_a.fifo_overflows==1 && !rs_a.BS_LoadOK) в текущей последовательности операций. */
|
||||
assert(rs_a.fifo_overflows==1 && !rs_a.BS_LoadOK);
|
||||
/* Цикл for(i=0;i<4;i++)RS_FifoTick1ms();feed(&rs_a,request,8);assert(rs_a.RS_DataReady);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for(i=0;i<4;i++)RS_FifoTick1ms();feed(&rs_a,request,8);assert(rs_a.RS_DataReady);
|
||||
/* A spurious old threshold interrupt may not finish an occupied FIFO. */
|
||||
/* Вызывает reset с аргументами ();RS_Send(&rs_a,data,8);RS_TX_Handler(&rs_a);assert(rs_a.fifo_tx_active) в текущей последовательности операций. */
|
||||
reset();RS_Send(&rs_a,data,8);RS_TX_Handler(&rs_a);assert(rs_a.fifo_tx_active);
|
||||
/* Вызывает RS_FifoWait. Ожидает завершения аппаратной передачи FIFO и сдвигового регистра SCI. */
|
||||
RS_FifoWait(&rs_a);assert(wire_count[0]==8);
|
||||
/* SCI-B keeps the original RX parser and IRQ/TX path, never FIFO state. */
|
||||
/* Вызывает reset с аргументами ();feed(&rs_b,request,8);assert(rs_b.RS_DataReady) в текущей последовательности операций. */
|
||||
reset();feed(&rs_b,request,8);assert(rs_b.RS_DataReady);
|
||||
/* Вызывает reset с аргументами ();RS_Send(&rs_b,data,2);assert(!rs_b.fifo_tx_active && length[1]==1) в текущей последовательности операций. */
|
||||
reset();RS_Send(&rs_b,data,2);assert(!rs_b.fifo_tx_active && length[1]==1);
|
||||
model_step(&rs_b);RS_TX_Handler(&rs_b); /* legacy RS_Wait drains final char */
|
||||
model_step(&rs_b);RS_TX_Handler(&rs_b); /* legacy RS_Wait drains final char */ /* Вызывает model_step с аргументами (&rs_b);RS_TX_Handler(&rs_b) в текущей последовательности операций. */
|
||||
/* Вызывает assert с аргументами (GpioDataRegs.GPBDAT.bit.GPIO34==1) в текущей последовательности операций. */
|
||||
assert(GpioDataRegs.GPBDAT.bit.GPIO34==1);
|
||||
/* Вызывает puts с аргументами ("PM35 RS232 FIFO: PASS (TX/RX/errors/recovery/SCI-B isolation)");return 0 в текущей последовательности операций. */
|
||||
puts("PM35 RS232 FIFO: PASS (TX/RX/errors/recovery/SCI-B isolation)");return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,48 +1,93 @@
|
||||
# Проверка rs232_fifo на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Exercise production RS485.c functions with FIFO register side effects."""; порядок аргументов сохраняется.
|
||||
"""Exercise production RS485.c functions with FIFO register side effects."""
|
||||
# Подключает модуль argparse для этой проверки или подготовки сборки.
|
||||
import argparse
|
||||
# Подключает модуль os для этой проверки или подготовки сборки.
|
||||
import os
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль re для этой проверки или подготовки сборки.
|
||||
import re
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
|
||||
# Задаёт root по выражению справа; значение используется последующими операциями.
|
||||
root=Path(__file__).resolve().parents[2]
|
||||
# Объявляет функцию read и её входные параметры.
|
||||
def read(path):
|
||||
return re.sub(r'/\*.*?\*/|//[^\n]*','',path.read_bytes().decode('cp1251').replace('\r\n','\n'),flags=re.S)
|
||||
# Возвращает re.sub(r'/\*.*?\*/|//[^\n]*','',path.read_bytes().decode('utf-8').replace('\r\n','\n'),flags=re.S) вызывающему коду и завершает функцию.
|
||||
return re.sub(r'/\*.*?\*/|//[^\n]*','',path.read_bytes().decode('utf-8').replace('\r\n','\n'),flags=re.S)
|
||||
# Задаёт source по выражению справа; значение используется последующими операциями.
|
||||
source=read(root/'Source/Internal/RS485.c')
|
||||
# Задаёт names по выражению справа; значение используется последующими операциями.
|
||||
names=['RS_RX_Handler','RS_TX_Handler','RS_Send','RS_BSend','RS_SetBitMode',
|
||||
# Продолжает текущий вызов, список или выражение: 'RS_FifoWait','RS_FifoTx','RS_FifoStart','RS_FifoAbort','RS_FifoTick1ms']; порядок аргументов сохраняется.
|
||||
'RS_FifoWait','RS_FifoTx','RS_FifoStart','RS_FifoAbort','RS_FifoTick1ms']
|
||||
# Задаёт prototypes по выражению справа; значение используется последующими операциями.
|
||||
prototypes=[];functions=[]
|
||||
# Перебирает name in names в указанном порядке.
|
||||
for name in names:
|
||||
# Задаёт match по выражению справа; значение используется последующими операциями.
|
||||
match=re.search(r'(?:static\s+)?(?:void|int)\s+'+name+r'\([^;{}]*\)\s*\{',source)
|
||||
# Проверяет обязательное условие match,name; нарушение делает тест неуспешным.
|
||||
assert match,name
|
||||
# Задаёт begin по выражению справа; значение используется последующими операциями.
|
||||
begin=source.index('{',match.start());end=begin+1;depth=1
|
||||
# Повторяет блок при выполнении depth.
|
||||
while depth:
|
||||
# Задаёт depth+ по выражению справа; значение используется последующими операциями.
|
||||
depth+=(source[end]=='{')-(source[end]=='}');end+=1
|
||||
# Продолжает текущий вызов, список или выражение: prototypes.append(source[match.start():begin]+';'); порядок аргументов сохраняется.
|
||||
prototypes.append(source[match.start():begin]+';')
|
||||
# Продолжает текущий вызов, список или выражение: functions.append(source[match.start():end]); порядок аргументов сохраняется.
|
||||
functions.append(source[match.start():end])
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body='\n'.join(functions)
|
||||
# TI C28x char is 16 bits: 0x80..0xFF remain positive before word packing.
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=re.sub(r'\bchar\s+Rc;', 'unsigned int Rc;', body)
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('received=rs_arr->SciRegs->SCIRXBUF.all;', 'received=model_pop(rs_arr);')
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('Rc = rs_arr->SciRegs->SCIRXBUF.bit.RXDT;', 'Rc=model_pop(rs_arr);')
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=0;',
|
||||
# Задаёт 'model_flush(rs_arr);rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET по выражению справа; значение используется последующими операциями.
|
||||
'model_flush(rs_arr);rs_arr->SciRegs->SCIFFRX.bit.RXFIFORESET=0;')
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('rs_arr->SciRegs->SCICTL1.bit.SWRESET=1;',
|
||||
# Задаёт 'rs_arr->SciRegs->SCIRXST.all по выражению справа; значение используется последующими операциями.
|
||||
'rs_arr->SciRegs->SCIRXST.all=0;rs_arr->SciRegs->SCICTL1.bit.SWRESET=1;')
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }',
|
||||
# Продолжает текущий вызов, список или выражение: 'while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { model_step(rs_arr); }',1); порядок аргументов сохраняется.
|
||||
'while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { model_step(rs_arr); }',1)
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }',
|
||||
# Продолжает текущий вызов, список или выражение: 'while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { model_shift(rs_arr); }'); порядок аргументов сохраняется.
|
||||
'while (!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { model_shift(rs_arr); }')
|
||||
# Задаёт body по выражению справа; значение используется последующими операциями.
|
||||
body=body.replace('!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { }',
|
||||
# Продолжает текущий вызов, список или выражение: '!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { model_step(rs_arr); }'); порядок аргументов сохраняется.
|
||||
'!rs_arr->SciRegs->SCICTL2.bit.TXEMPTY) { model_step(rs_arr); }')
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header=read(root/'Source/Internal/Include/RS485.h')
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header=re.sub(r'#define SCI_send\(x,y\)[^\n]*', '#define SCI_send(x,y) model_push(x,y)',header)
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header=re.sub(r'#define enableUARTInt\(x\)[^\n]*', '#define enableUARTInt(x) model_interrupts(x,0)',header)
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header=re.sub(r'#define enableUARTIntW\(x\)[^\n]*', '#define enableUARTIntW(x) model_interrupts(x,1)',header)
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header=re.sub(r'#define Rec_Bloc_Begin[^\n]*', '#define Rec_Bloc_Begin ((uintptr_t)load_memory)',header)
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header=re.sub(r'#define Rec_Bloc_End[^\n]*', '#define Rec_Bloc_End ((uintptr_t)(load_memory+4100))',header)
|
||||
# Задаёт registers по выражению справа; значение используется последующими операциями.
|
||||
registers=read(root/'Source/External/v120/DSP2833x_headers/include/DSP2833x_Sci.h')
|
||||
# Задаёт defines по выражению справа; значение используется последующими операциями.
|
||||
defines='''
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@@ -62,12 +107,21 @@ typedef unsigned short Uint16;
|
||||
enum {CMD_MODBUS_3=3,ANS_MODBUS_4=4,CMD_MODBUS_6=6,CMD_MODBUS_16=16,
|
||||
CMD_LOAD=51,CMD_INITLOAD=58,CMD_STD_ANS=66};
|
||||
'''
|
||||
harness=(Path(__file__).with_name('model.inc')).read_text()
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
harness=(Path(__file__).with_name('model.inc')).read_text(encoding="utf-8")
|
||||
# Задаёт before,after по выражению справа; значение используется последующими операциями.
|
||||
before,after=harness.split('/* HANDLERS */')
|
||||
# Задаёт parser по выражению справа; значение используется последующими операциями.
|
||||
parser=argparse.ArgumentParser();parser.add_argument('--cc',required=True);args=parser.parse_args()
|
||||
# Задаёт env по выражению справа; значение используется последующими операциями.
|
||||
env=dict(os.environ);env['PATH']=str(Path(args.cc).parent)+os.pathsep+env.get('PATH','')
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix='pm35-fifo-') as directory с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory(prefix='pm35-fifo-') as directory:
|
||||
# Задаёт path по выражению справа; значение используется последующими операциями.
|
||||
path=Path(directory);c=path/'model.c';exe=path/'model.exe'
|
||||
c.write_text(defines+registers+header+'\n'.join(prototypes)+before+body+after)
|
||||
# Сохраняет подготовленный файл в указанном формате для следующего шага.
|
||||
c.write_text(defines+registers+header+'\n'.join(prototypes)+before+body+after, encoding="utf-8")
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([args.cc,'-std=c99','-O1','-Werror=implicit-function-declaration',str(c),'-o',str(exe)],check=True,env=env)
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([str(exe)],check=True,env=env,timeout=20)
|
||||
|
||||
@@ -1,56 +1,109 @@
|
||||
/* Проверка ump_logger на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подключает "../../Source/Internal/log_to_mem.c": двухбанковый регистратор событий нагрузки во внешней RAM. */
|
||||
#include "../../Source/Internal/log_to_mem.c"
|
||||
|
||||
/* Описывает структуру mock_gpio GpioDataRegs;; порядок полей определяет расположение данных. */
|
||||
struct mock_gpio GpioDataRegs;
|
||||
/* Объявляет READY — данные READY; Desk — аппаратно определённый тип платы; Mode — рабочий адрес или режим платы, выбранный перемычками. Начальное значение задаётся справа от знака равенства. */
|
||||
int READY = 1, Desk = 6, Mode = 5;
|
||||
/* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит; CanTimeOutErrorTR — CAN Time Out ошибка TR. */
|
||||
int modbus[128], CanTimeOutErrorTR;
|
||||
/* Объявляет IMPowse — данные IMPowse; WAKEpowse — данные WAKEpowse. */
|
||||
unsigned long IMPowse, WAKEpowse;
|
||||
/* Объявляет ADC_table — АЦП table. */
|
||||
unsigned int ADC_table[4];
|
||||
/* Задаёт CHECK = if (!(x)) return __LINE__; данные CHECK. */
|
||||
#define CHECK(x) if (!(x)) return __LINE__
|
||||
|
||||
/* Точка входа: настраивает периферию, загружает параметры и обслуживает команды в главном цикле. */
|
||||
int main(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет i — данные i. */
|
||||
unsigned int i;
|
||||
/* Simulate COFF boot with dirty RAM, including a stale active bank. */
|
||||
/* Записывает ump_state значением ump_count = ump_cursor = ump_next = 0xA5A5; данные ump_state. */
|
||||
ump_state = ump_count = ump_cursor = ump_next = 0xA5A5;
|
||||
/* Записывает ump_period значением ump_divider = 0xA5A5; период записи регистратора в миллисекундных тактах. */
|
||||
ump_period = ump_divider = 0xA5A5;
|
||||
/* Записывает ump_time значением ump_sequence = 0xA5A5A5A5UL; миллисекундное время регистратора. */
|
||||
ump_time = ump_sequence = 0xA5A5A5A5UL;
|
||||
/* Записывает ump_bank значением ump_archive_bank = 0xA5A5; индекс активного банка регистратора. */
|
||||
ump_bank = ump_archive_bank = 0xA5A5;
|
||||
/* Записывает ump_archive_count значением ump_archive_next = ump_generation = 0xA5A5; ump archive число. */
|
||||
ump_archive_count = ump_archive_next = ump_generation = 0xA5A5;
|
||||
/* Записывает ump_source значением ump_post = 0xA5A5; данные ump_source. */
|
||||
ump_source = ump_post = 0xA5A5;
|
||||
/* Записывает ump_can_header значением ump_can_count = 0xA5A5; ump CAN header. */
|
||||
ump_can_header = ump_can_count = 0xA5A5;
|
||||
/* Цикл for (i = 0; i < 3; i++) ump_can_data[i] = 0xA5A5;; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 3; i++) ump_can_data[i] = 0xA5A5;
|
||||
/* Цикл for (i = 0; i < 2; i++) ump_pm67_voltage[i] = 0xA5A5;; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 2; i++) ump_pm67_voltage[i] = 0xA5A5;
|
||||
/* Записывает ump_prev_commands значением ump_prev_inputs = ump_prev_outputs = 0xA5A5; данные ump_prev_commands. */
|
||||
ump_prev_commands = ump_prev_inputs = ump_prev_outputs = 0xA5A5;
|
||||
/* Записывает ump_dac_ramp значением ump_dac_duration = ump_dac_go10 = 0xA5A5; ump ЦАП ramp. */
|
||||
ump_dac_ramp = ump_dac_duration = ump_dac_go10 = 0xA5A5;
|
||||
/* Записывает ump_dac_stop10 значением ump_dac_position = 0xA5A5; ump ЦАП stop 10. */
|
||||
ump_dac_stop10 = ump_dac_position = 0xA5A5;
|
||||
|
||||
/* Вызывает ump_log_init. Явно инициализирует оба банка регистратора до включения IRQ; повторный старт записи архив не стирает. */
|
||||
ump_log_init();
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_BASE) == 0x554D) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_BASE) == 0x554D);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_BASE+1) == 3) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_BASE+1) == 3);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_BASE+2) == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_BASE+2) == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_BASE+3) == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_BASE+3) == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_BASE+6) == 20) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_BASE+6) == 20);
|
||||
/* Цикл for (i = 7; i <= 8; i++) CHECK(ump_log_read(UMP_LOG_BASE+i) == 0);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 7; i <= 8; i++) CHECK(ump_log_read(UMP_LOG_BASE+i) == 0);
|
||||
/* Цикл for (i = 12; i <= 15; i++) CHECK(ump_log_read(UMP_LOG_BASE+i) == 0);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 12; i <= 15; i++) CHECK(ump_log_read(UMP_LOG_BASE+i) == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_bank == 0 && ump_archive_bank == 1) в текущей последовательности операций. */
|
||||
CHECK(ump_bank == 0 && ump_archive_bank == 1);
|
||||
/* Вызывает CHECK с аргументами (ump_cursor == 0 && ump_next == 0 && ump_archive_next == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_cursor == 0 && ump_next == 0 && ump_archive_next == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_divider == 0 && ump_sequence == 0 && ump_post == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_divider == 0 && ump_sequence == 0 && ump_post == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_can_header == 0 && ump_can_count == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_can_header == 0 && ump_can_count == 0);
|
||||
/* Цикл for (i = 0; i < 3; i++) CHECK(ump_can_data[i] == 0);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 3; i++) CHECK(ump_can_data[i] == 0);
|
||||
/* Цикл for (i = 0; i < 2; i++) CHECK(ump_pm67_voltage[i] == 0);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 2; i++) CHECK(ump_pm67_voltage[i] == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_prev_commands == 0 && ump_prev_inputs == 0 && ump_prev_outputs == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_prev_commands == 0 && ump_prev_inputs == 0 && ump_prev_outputs == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_dac_ramp == 0 && ump_dac_duration == 0 && ump_dac_go10 == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_dac_ramp == 0 && ump_dac_duration == 0 && ump_dac_go10 == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_dac_stop10 == 0 && ump_dac_position == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_dac_stop10 == 0 && ump_dac_position == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE+1, 20)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE+1, 20));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Вызывает CHECK с аргументами (ump_state == 1 && ump_count == 1) в текущей последовательности операций. */
|
||||
CHECK(ump_state == 1 && ump_count == 1);
|
||||
/* Вызывает ump_log_tick. Продвигает время регистратора в Timer1 и снимает записи с заданным периодом. */
|
||||
ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_time == 1) в текущей последовательности операций. */
|
||||
CHECK(ump_time == 1);
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 0)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 0));
|
||||
/* Записывает ump_archive_count значением 7; ump_generation = 2; ump archive число. */
|
||||
ump_archive_count = 7; ump_generation = 2;
|
||||
/* Записывает ump_pm67_voltage[0] значением 123; данные ump_pm67_voltage. */
|
||||
ump_pm67_voltage[0] = 123;
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Вызывает CHECK с аргументами (ump_time == 1 && ump_archive_count == 7 && ump_generation == 2) в текущей последовательности операций. */
|
||||
CHECK(ump_time == 1 && ump_archive_count == 7 && ump_generation == 2);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, 0, 40) == 123) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, 0, 40) == 123);
|
||||
/* Завершает main и возвращает 0. */
|
||||
return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,163 +1,311 @@
|
||||
/* Проверка ump_logger на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подключает "../../Source/Internal/log_to_mem.c": двухбанковый регистратор событий нагрузки во внешней RAM. */
|
||||
#include "../../Source/Internal/log_to_mem.c"
|
||||
/* Подключает "../../Source/Internal/Include/ump_can_protocol.h": настройки и интерфейс ump_can_protocol. */
|
||||
#include "../../Source/Internal/Include/ump_can_protocol.h"
|
||||
/* Описывает структуру mock_gpio GpioDataRegs;; порядок полей определяет расположение данных. */
|
||||
struct mock_gpio GpioDataRegs;
|
||||
/* Объявляет READY — данные READY; Desk — аппаратно определённый тип платы; Mode — рабочий адрес или режим платы, выбранный перемычками. Начальное значение задаётся справа от знака равенства. */
|
||||
int READY = 1, Desk = 6, Mode = 5;
|
||||
/* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
int modbus[128];
|
||||
/* Объявляет CanTimeOutErrorTR — CAN Time Out ошибка TR. */
|
||||
int CanTimeOutErrorTR;
|
||||
/* Объявляет IMPowse — данные IMPowse; WAKEpowse — данные WAKEpowse. */
|
||||
unsigned long IMPowse, WAKEpowse;
|
||||
/* Объявляет ADC_table — АЦП table. */
|
||||
unsigned int ADC_table[4];
|
||||
/* Задаёт CHECK = if (!(x)) return __LINE__; данные CHECK. */
|
||||
#define CHECK(x) if (!(x)) return __LINE__
|
||||
|
||||
/* Возвращаем номер строки при ошибке, ноль при успехе; CRT не требуется. */
|
||||
/* Вызывает __declspec с аргументами (dllexport) int run_tests(void) в текущей последовательности операций. */
|
||||
__declspec(dllexport) int run_tests(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет i — данные i; generation — данные generation; archived — данные archived; error — ошибка; length — длина. */
|
||||
unsigned int i, generation, archived, error, length;
|
||||
/* Объявляет reply — данные reply. */
|
||||
uint16_t reply[UMP_CAN_MAX_WORDS];
|
||||
/* Объявляет sequence — последовательность. */
|
||||
unsigned long sequence;
|
||||
/* Вызывает ump_log_init. Явно инициализирует оба банка регистратора до включения IRQ; повторный старт записи архив не стирает. */
|
||||
ump_log_init();
|
||||
/* Вызывает CHECK с аргументами (!ump_log_write(UMP_LOG_BASE+1, 0)) в текущей последовательности операций. */
|
||||
CHECK(!ump_log_write(UMP_LOG_BASE+1, 0));
|
||||
/* Вызывает CHECK с аргументами (!ump_log_write(UMP_LOG_BASE+1, 1001)) в текущей последовательности операций. */
|
||||
CHECK(!ump_log_write(UMP_LOG_BASE+1, 1001));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE+1, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE+1, 1));
|
||||
/* Записывает modbus[127] значением 0x80; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[127] = 0x80;
|
||||
/* Записывает modbus[0x50] значением 6; modbus[0x51] = 16; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[0x50] = 6; modbus[0x51] = 16;
|
||||
/* Записывает modbus[0x7B] значением 1234; modbus[0x1C] = 160; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[0x7B] = 1234; modbus[0x1C] = 160;
|
||||
/* PM67 reception is independent of recording; all three CAN slots work. */
|
||||
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
ump_log_can(0x8000U | 305U, 0xFEDCU, 0, 0);
|
||||
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
ump_log_can(0x4000U | 7U, 0, 456, 0);
|
||||
/* Вызывает CHECK с аргументами (ump_pm67_voltage[0] == 0xFEDCU && ump_pm67_voltage[1] == 456) в текущей последовательности операций. */
|
||||
CHECK(ump_pm67_voltage[0] == 0xFEDCU && ump_pm67_voltage[1] == 456);
|
||||
ump_log_can(305U, 1, 2, 3); /* Masked-out word must not overwrite. */
|
||||
ump_log_can(305U, 1, 2, 3); /* Masked-out word must not overwrite. */ /* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
ump_log_can(0x2000U | 303U, 0, 0, 123);
|
||||
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
ump_log_can(0x2000U | 6U, 0, 0, 789);
|
||||
/* Вызывает CHECK с аргументами (ump_pm67_voltage[0] == 123 && ump_pm67_voltage[1] == 789) в текущей последовательности операций. */
|
||||
CHECK(ump_pm67_voltage[0] == 123 && ump_pm67_voltage[1] == 789);
|
||||
ump_log_can(0x8000U | 306U, 999, 0, 0); /* Not a one-based CAN address. */
|
||||
ump_log_can(0x8000U | 306U, 999, 0, 0); /* Not a one-based CAN address. */ /* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, 0, 40) == 123 && ump_word(0, 0, 41) == 789) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, 0, 40) == 123 && ump_word(0, 0, 41) == 789);
|
||||
/* Вызывает CHECK с аргументами (2UL * UMP_LOG_CAPACITY * UMP_LOG_WORDS <= LOG_PAGE_LEN) в текущей последовательности операций. */
|
||||
CHECK(2UL * UMP_LOG_CAPACITY * UMP_LOG_WORDS <= LOG_PAGE_LEN);
|
||||
/* Вызывает CHECK с аргументами (!ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(!ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Вызывает CHECK с аргументами (!ump_log_write(UMP_LOG_BASE+1, 20)) в текущей последовательности операций. */
|
||||
CHECK(!ump_log_write(UMP_LOG_BASE+1, 20));
|
||||
/* Цикл for (i=0; i<900; i++) ump_log_tick();; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<900; i++) ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_count == UMP_LOG_CAPACITY) в текущей последовательности операций. */
|
||||
CHECK(ump_count == UMP_LOG_CAPACITY);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, 0, 0) == 901-UMP_LOG_CAPACITY) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, 0, 0) == 901-UMP_LOG_CAPACITY);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, UMP_LOG_CAPACITY-1, 0) == 900) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, UMP_LOG_CAPACITY-1, 0) == 900);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, 0, 8) == 1234) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, 0, 8) == 1234);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, 0, 24) == 6) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, 0, 24) == 6);
|
||||
/* Короткая CAN-команда должна остаться отдельным событием. */
|
||||
/* Записывает modbus[127] значением 0x40; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[127] = 0x40;
|
||||
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
ump_log_can(0x807F, 0x40, 0, 0);
|
||||
CHECK(ump_post == 0); /* A command alone is not an output transition. */
|
||||
CHECK(ump_post == 0); /* A command alone is not an output transition. */ /* Вызывает CHECK с аргументами (ump_post == 0) в текущей последовательности операций. */
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO58 значением 1; аппаратная линия ввода/вывода GPIO58. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO58 = 1;
|
||||
ump_log_io(); /* STOP may be sampled before RES_OUT_2 is cleared. */
|
||||
ump_log_io(); /* STOP may be sampled before RES_OUT_2 is cleared. */ /* Вызывает ump_log_io. Обслуживает изменения дискретных входов и выходов из главного цикла. */
|
||||
/* Вызывает CHECK с аргументами (ump_post == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 0);
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 1; аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 1;
|
||||
/* Вызывает ump_log_io. Обслуживает изменения дискретных входов и выходов из главного цикла. */
|
||||
ump_log_io();
|
||||
/* Вызывает CHECK с аргументами (ump_post == UMP_POST_POINTS) в текущей последовательности операций. */
|
||||
CHECK(ump_post == UMP_POST_POINTS);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, ump_count-1, 2) == 0x103) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, ump_count-1, 2) == 0x103);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, ump_count-1, 18) == 0x807F) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, ump_count-1, 18) == 0x807F);
|
||||
/* Цикл for (i=0; i<UMP_POST_POINTS-1; i++) ump_log_tick();; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<UMP_POST_POINTS-1; i++) ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_generation == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_generation == 0);
|
||||
/* Вызывает ump_log_tick. Продвигает время регистратора в Timer1 и снимает записи с заданным периодом. */
|
||||
ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_generation == 1) в текущей последовательности операций. */
|
||||
CHECK(ump_generation == 1);
|
||||
/* Вызывает CHECK с аргументами (ump_archive_count == UMP_LOG_CAPACITY) в текущей последовательности операций. */
|
||||
CHECK(ump_archive_count == UMP_LOG_CAPACITY);
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-UMP_POST_POINTS-1, 2) == 0x103) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-UMP_POST_POINTS-1, 2) == 0x103);
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 2) == 5) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 2) == 5);
|
||||
/* Вызывает CHECK с аргументами (ump_count == 0 && ump_state == 1) в текущей последовательности операций. */
|
||||
CHECK(ump_count == 0 && ump_state == 1);
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 40) == 123) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 40) == 123);
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 41) == 789) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 41) == 789);
|
||||
/* Вызывает ump_log_can. Обновляет последние CAN-данные и напряжения для следующего снимка регистратора. */
|
||||
ump_log_can(0x8000U | 305U, 999, 0, 0);
|
||||
/* Вызывает CHECK с аргументами (ump_word(0, ump_count-1, 40) == 999) в текущей последовательности операций. */
|
||||
CHECK(ump_word(0, ump_count-1, 40) == 999);
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 40) == 123) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 40) == 123);
|
||||
/* Записывает generation значением ump_generation; данные generation. */
|
||||
generation = ump_generation;
|
||||
/* Записывает archived значением ump_word(1, UMP_LOG_CAPACITY-1, 0); данные archived. */
|
||||
archived = ump_word(1, UMP_LOG_CAPACITY-1, 0);
|
||||
/* Записывает sequence значением ump_sequence; последовательность. */
|
||||
sequence = ump_sequence;
|
||||
/* Цикл for (i=0; i<200; i++) ump_log_tick();; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<200; i++) ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 0) == archived) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 0) == archived);
|
||||
/* Вызывает CHECK с аргументами (ump_generation == generation) в текущей последовательности операций. */
|
||||
CHECK(ump_generation == generation);
|
||||
/* Вызывает CHECK с аргументами (ump_sequence == sequence + 200) в текущей последовательности операций. */
|
||||
CHECK(ump_sequence == sequence + 200);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_LIVE+2) == UMP_LOG_LIVE_RECORDS) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_LIVE+2) == UMP_LOG_LIVE_RECORDS);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_LIVE+4) == ump_time-(UMP_LOG_LIVE_RECORDS-1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_LIVE+4) == ump_time-(UMP_LOG_LIVE_RECORDS-1));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE+3, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE+3, 1));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE+2, UMP_LOG_CAPACITY-1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE+2, UMP_LOG_CAPACITY-1));
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_DATA) == archived) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_DATA) == archived);
|
||||
/* Вызывает CHECK с аргументами (ump_log_read(UMP_LOG_DATA+UMP_LOG_WORDS) == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_log_read(UMP_LOG_DATA+UMP_LOG_WORDS) == 0);
|
||||
/* Вызывает CHECK с аргументами (!ump_log_write(UMP_LOG_BASE+2, UMP_LOG_CAPACITY)) в текущей последовательности операций. */
|
||||
CHECK(!ump_log_write(UMP_LOG_BASE+2, UMP_LOG_CAPACITY));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 0)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 0));
|
||||
/* Записывает sequence значением ump_sequence; последовательность. */
|
||||
sequence = ump_sequence;
|
||||
/* Вызывает ump_log_tick. Продвигает время регистратора в Timer1 и снимает записи с заданным периодом. */
|
||||
ump_log_tick(); ump_log_io(); ump_log_can(1,2,3,4);
|
||||
/* Вызывает CHECK с аргументами (sequence == ump_sequence) в текущей последовательности операций. */
|
||||
CHECK(sequence == ump_sequence);
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 0) == archived) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 0) == archived);
|
||||
/* Repeated reset/STOP pulses beyond the post interval preserve archive. */
|
||||
/* Цикл for (i=0; i<3; i++) ; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<3; i++) {
|
||||
/* Записывает modbus[127] значением 0; GpioDataRegs.GPBDAT.bit.GPIO58 = 0; ump_log_io(); массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[127] = 0; GpioDataRegs.GPBDAT.bit.GPIO58 = 0; ump_log_io();
|
||||
/* Записывает modbus[127] значением 0x40; ump_log_can(0x807F, 0x40, 0, 0); массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[127] = 0x40; ump_log_can(0x807F, 0x40, 0, 0);
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO58 значением 1; ump_log_io(); аппаратная линия ввода/вывода GPIO58. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO58 = 1; ump_log_io();
|
||||
/* Вызывает CHECK с аргументами (ump_post == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 0);
|
||||
/* Записывает tick значением 0; tick<1100; tick++) ump_log_tick(); }; данные tick. */
|
||||
{ unsigned int tick; for (tick=0; tick<1100; tick++) ump_log_tick(); }
|
||||
/* Вызывает CHECK с аргументами (ump_generation == generation) в текущей последовательности операций. */
|
||||
CHECK(ump_generation == generation);
|
||||
/* Вызывает CHECK с аргументами (ump_word(1, UMP_LOG_CAPACITY-1, 0) == archived) в текущей последовательности операций. */
|
||||
CHECK(ump_word(1, UMP_LOG_CAPACITY-1, 0) == archived);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Falling start alone does not freeze; a new real cycle does. */
|
||||
/* Записывает modbus[127] значением 0x80; ump_log_rs(); массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[127] = 0x80; ump_log_rs();
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO58 значением 0; аппаратная линия ввода/вывода GPIO58. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO58 = 0;
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 0; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 0; ump_log_io();
|
||||
/* Записывает modbus[127] значением 0; ump_log_rs(); массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
modbus[127] = 0; ump_log_rs();
|
||||
/* Вызывает CHECK с аргументами (ump_post == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 0);
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO58 значением 1; аппаратная линия ввода/вывода GPIO58. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO58 = 1;
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 1; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 1; ump_log_io();
|
||||
/* Вызывает CHECK с аргументами (ump_post == UMP_POST_POINTS) в текущей последовательности операций. */
|
||||
CHECK(ump_post == UMP_POST_POINTS);
|
||||
/* Цикл for (i=0; i<UMP_POST_POINTS; i++) ump_log_tick();; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<UMP_POST_POINTS; i++) ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_generation == generation+1) в текущей последовательности операций. */
|
||||
CHECK(ump_generation == generation+1);
|
||||
/* A RES_OUT_2 fall without STOP is not a shutdown trigger. */
|
||||
/* Записывает generation значением ump_generation; данные generation. */
|
||||
generation = ump_generation;
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO58 значением 0; аппаратная линия ввода/вывода GPIO58. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO58 = 0;
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 0; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 0; ump_log_io();
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 1; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 1; ump_log_io();
|
||||
/* Вызывает CHECK с аргументами (ump_post == 0) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 0);
|
||||
/* Starting the recorder with stopped outputs must not invent an edge. */
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 0)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 0));
|
||||
/* Записывает GpioDataRegs.GPBDAT.bit.GPIO58 значением 1; аппаратная линия ввода/вывода GPIO58. */
|
||||
GpioDataRegs.GPBDAT.bit.GPIO58 = 1;
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Вызывает CHECK с аргументами (ump_post == 0 && ump_generation == generation) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 0 && ump_generation == generation);
|
||||
/* At a slow sample period time alone cannot finish the point budget.
|
||||
* CAN and RS records count, and repeated edges do not restart it. */
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 0)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 0));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE+1, 1000)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE+1, 1000));
|
||||
/* Вызывает CHECK с аргументами (ump_log_write(UMP_LOG_BASE, 1)) в текущей последовательности операций. */
|
||||
CHECK(ump_log_write(UMP_LOG_BASE, 1));
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 0; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 0; ump_log_io();
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 1; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 1; ump_log_io();
|
||||
/* Вызывает CHECK с аргументами (ump_post == UMP_POST_POINTS) в текущей последовательности операций. */
|
||||
CHECK(ump_post == UMP_POST_POINTS);
|
||||
/* Цикл for (i=0; i<1000; i++) ump_log_tick();; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<1000; i++) ump_log_tick();
|
||||
/* Вызывает CHECK с аргументами (ump_post == UMP_POST_POINTS-1 && ump_generation == generation) в текущей последовательности операций. */
|
||||
CHECK(ump_post == UMP_POST_POINTS-1 && ump_generation == generation);
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 0; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 0; ump_log_io();
|
||||
/* Записывает GpioDataRegs.GPADAT.bit.GPIO3 значением 1; ump_log_io(); аппаратная линия ввода/вывода GPIO3. */
|
||||
GpioDataRegs.GPADAT.bit.GPIO3 = 1; ump_log_io();
|
||||
/* Вызывает CHECK с аргументами (ump_post == UMP_POST_POINTS-3) в текущей последовательности операций. */
|
||||
CHECK(ump_post == UMP_POST_POINTS-3);
|
||||
/* Цикл for (i=0; i<UMP_POST_POINTS-4; i++) ump_log_can(0x807F, 0, 0, 0);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=0; i<UMP_POST_POINTS-4; i++) ump_log_can(0x807F, 0, 0, 0);
|
||||
/* Вызывает CHECK с аргументами (ump_post == 1 && ump_generation == generation) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 1 && ump_generation == generation);
|
||||
/* Вызывает ump_log_rs. Регистрирует изменение слова команд после записи по последовательному интерфейсу. */
|
||||
ump_log_rs();
|
||||
/* Вызывает CHECK с аргументами (ump_post == 0 && ump_generation == generation+1) в текущей последовательности операций. */
|
||||
CHECK(ump_post == 0 && ump_generation == generation+1);
|
||||
/* Вызывает CHECK с аргументами (ump_archive_count == UMP_POST_POINTS+3) в текущей последовательности операций. */
|
||||
CHECK(ump_archive_count == UMP_POST_POINTS+3);
|
||||
/* CAN читает те же регистры и формирует цельный снимок из 124 слов.
|
||||
* Запись по старым технологическим адресам через сервис запрещена. */
|
||||
/* Записывает length значением ump_can_prepare(3, UMP_LOG_BASE, 16, reply, &error); длина. */
|
||||
length = ump_can_prepare(3, UMP_LOG_BASE, 16, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (!error && length == 16 && reply[0] == 0x554D && reply[1] == 3) в текущей последовательности операций. */
|
||||
CHECK(!error && length == 16 && reply[0] == 0x554D && reply[1] == 3);
|
||||
/* Записывает length значением ump_can_prepare(3, UMP_LOG_LIVE, 124, reply, &error); длина. */
|
||||
length = ump_can_prepare(3, UMP_LOG_LIVE, 124, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (!error && length == 124) в текущей последовательности операций. */
|
||||
CHECK(!error && length == 124);
|
||||
/* Вызывает CHECK с аргументами (reply[2] <= UMP_LOG_LIVE_RECORDS) в текущей последовательности операций. */
|
||||
CHECK(reply[2] <= UMP_LOG_LIVE_RECORDS);
|
||||
/* Цикл for (i=4+reply[2]*UMP_LOG_WORDS; i<124; i++) CHECK(reply[i] == 0);; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i=4+reply[2]*UMP_LOG_WORDS; i<124; i++) CHECK(reply[i] == 0);
|
||||
/* Записывает length значением ump_can_prepare(3, UMP_LOG_DATA, 84, reply, &error); длина. */
|
||||
length = ump_can_prepare(3, UMP_LOG_DATA, 84, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (!error && length == 84) в текущей последовательности операций. */
|
||||
CHECK(!error && length == 84);
|
||||
/* Записывает length значением ump_can_prepare(3, UMP_LOG_DATA, 42, reply, &error); длина. */
|
||||
length = ump_can_prepare(3, UMP_LOG_DATA, 42, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (!error && length == 42) в текущей последовательности операций. */
|
||||
CHECK(!error && length == 42);
|
||||
/* Вызывает ump_can_prepare с аргументами (3, UMP_LOG_LIVE, 126, reply, &error) в текущей последовательности операций. */
|
||||
ump_can_prepare(3, UMP_LOG_LIVE, 126, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (error == 2) в текущей последовательности операций. */
|
||||
CHECK(error == 2);
|
||||
/* Вызывает ump_can_prepare с аргументами (6, 127, 0x80, reply, &error) в текущей последовательности операций. */
|
||||
ump_can_prepare(6, 127, 0x80, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (error == 2 && modbus[127] == 0) в текущей последовательности операций. */
|
||||
CHECK(error == 2 && modbus[127] == 0);
|
||||
/* Записывает length значением ump_can_prepare(6, UMP_LOG_BASE, 0, reply, &error); длина. */
|
||||
length = ump_can_prepare(6, UMP_LOG_BASE, 0, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (!error && length == 2 && reply[0] == UMP_LOG_BASE && reply[1] == 0) в текущей последовательности операций. */
|
||||
CHECK(!error && length == 2 && reply[0] == UMP_LOG_BASE && reply[1] == 0);
|
||||
/* Вызывает CHECK с аргументами (ump_state == 3) в текущей последовательности операций. */
|
||||
CHECK(ump_state == 3);
|
||||
/* Вызывает ump_can_prepare с аргументами (6, UMP_LOG_BASE+1, 0, reply, &error) в текущей последовательности операций. */
|
||||
ump_can_prepare(6, UMP_LOG_BASE+1, 0, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (error == 3) в текущей последовательности операций. */
|
||||
CHECK(error == 3);
|
||||
/* Вызывает ump_can_prepare с аргументами (99, UMP_LOG_BASE, 16, reply, &error) в текущей последовательности операций. */
|
||||
ump_can_prepare(99, UMP_LOG_BASE, 16, reply, &error);
|
||||
/* Вызывает CHECK с аргументами (error == 1) в текущей последовательности операций. */
|
||||
CHECK(error == 1);
|
||||
/* Завершает функцию и возвращает 0. */
|
||||
return 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -1,35 +1,66 @@
|
||||
# Проверка ump_logger на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Boot regression independent of the external shared protocol checkout.; порядок аргументов сохраняется.
|
||||
"""Boot regression independent of the external shared protocol checkout.
|
||||
|
||||
Run with GCC in PATH: python tests/ump_logger/run_init_test.py
|
||||
The negative control must fail without the boot initialization call.
|
||||
"""
|
||||
# Подключает модуль os для этой проверки или подготовки сборки.
|
||||
import os
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
|
||||
# Задаёт root по выражению справа; значение используется последующими операциями.
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
# Задаёт source по выражению справа; значение используется последующими операциями.
|
||||
source = root / 'tests/ump_logger/init_test.c'
|
||||
# Задаёт compiler по выражению справа; значение используется последующими операциями.
|
||||
compiler = os.environ.get('CC', 'gcc')
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix='ump-init-') as directory с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory(prefix='ump-init-') as directory:
|
||||
# Задаёт directory по выражению справа; значение используется последующими операциями.
|
||||
directory = Path(directory)
|
||||
text = source.read_text().replace(
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
text = source.read_text(encoding="utf-8").replace(
|
||||
# Продолжает текущий вызов, список или выражение: '../../Source/Internal/log_to_mem.c',; порядок аргументов сохраняется.
|
||||
'../../Source/Internal/log_to_mem.c',
|
||||
# Продолжает текущий вызов, список или выражение: (root / 'Source/Internal/log_to_mem.c').as_posix(),; порядок аргументов сохраняется.
|
||||
(root / 'Source/Internal/log_to_mem.c').as_posix(),
|
||||
# Продолжает текущий вызов, список или выражение: ); порядок аргументов сохраняется.
|
||||
)
|
||||
# Перебирает initialize in (False, True) в указанном порядке.
|
||||
for initialize in (False, True):
|
||||
# Задаёт case по выражению справа; значение используется последующими операциями.
|
||||
case = directory / 'init_test.c'
|
||||
case.write_text(text if initialize else text.replace('ump_log_init();', ';'))
|
||||
# Сохраняет подготовленный файл в указанном формате для следующего шага.
|
||||
case.write_text(text if initialize else text.replace('ump_log_init();', ';'), encoding="utf-8")
|
||||
# Задаёт executable по выражению справа; значение используется последующими операциями.
|
||||
executable = directory / 'init_test.exe'
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([
|
||||
# Продолжает текущий вызов, список или выражение: compiler, '-Wno-unknown-pragmas', '-Wno-int-to-pointer-cast',; порядок аргументов сохраняется.
|
||||
compiler, '-Wno-unknown-pragmas', '-Wno-int-to-pointer-cast',
|
||||
# Продолжает текущий вызов, список или выражение: '-I' + str(root / 'tests/ump_logger/stubs'),; порядок аргументов сохраняется.
|
||||
'-I' + str(root / 'tests/ump_logger/stubs'),
|
||||
# Продолжает текущий вызов, список или выражение: '-I' + str(root / 'Source/Internal/Include'),; порядок аргументов сохраняется.
|
||||
'-I' + str(root / 'Source/Internal/Include'),
|
||||
# Продолжает текущий вызов, список или выражение: str(case), '-o', str(executable),; порядок аргументов сохраняется.
|
||||
str(case), '-o', str(executable),
|
||||
# Задаёт ], check по выражению справа; значение используется последующими операциями.
|
||||
], check=True)
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
result = subprocess.run([str(executable)])
|
||||
# Проверяет условие if initialize перед выполнением следующего блока.
|
||||
if initialize:
|
||||
# Проверяет обязательное условие result.returncode == 0, f'Initialization failed: {result.returncode}'; нарушение делает тест неуспешным.
|
||||
assert result.returncode == 0, f'Initialization failed: {result.returncode}'
|
||||
# Обрабатывает альтернативу предыдущего условия.
|
||||
else:
|
||||
# Проверяет обязательное условие result.returncode != 0, 'Negative control unexpectedly passed'; нарушение делает тест неуспешным.
|
||||
assert result.returncode != 0, 'Negative control unexpectedly passed'
|
||||
# Продолжает текущий вызов, список или выражение: print(f'{"Initialized boot" if initialize else "Dirty RAM negative control"}: PASS'); порядок аргументов сохраняется.
|
||||
print(f'{"Initialized boot" if initialize else "Dirty RAM negative control"}: PASS')
|
||||
|
||||
@@ -1,41 +1,76 @@
|
||||
# Проверка ump_logger на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Сборка и запуск исходного регистратора с подменой GPIO/IRQ на Windows.; порядок аргументов сохраняется.
|
||||
"""Сборка и запуск исходного регистратора с подменой GPIO/IRQ на Windows.
|
||||
|
||||
Нужны GCC либо Clang и lld-link в PATH. TEMPLATES_ROOT задаёт библиотеку. Проверяется алгоритм, но не ABI и тайминги TI.
|
||||
DLL создаётся во временной папке; исходные .out/.hex прошивки не затрагиваются.
|
||||
"""
|
||||
# Подключает модуль ctypes для этой проверки или подготовки сборки.
|
||||
import ctypes
|
||||
# Подключает модуль os для этой проверки или подготовки сборки.
|
||||
import os
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль shutil для этой проверки или подготовки сборки.
|
||||
import shutil
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
|
||||
# Задаёт root по выражению справа; значение используется последующими операциями.
|
||||
root = Path(__file__).resolve().parents[2]
|
||||
# Задаёт templates по выражению справа; значение используется последующими операциями.
|
||||
templates = Path(os.environ.get('TEMPLATES_ROOT', root.parent / 'newProject/SETGUI/third_party/templates'))
|
||||
# Задаёт protocol по выражению справа; значение используется последующими операциями.
|
||||
protocol = templates / 'c/set-protocol'
|
||||
# Задаёт compiler по выражению справа; значение используется последующими операциями.
|
||||
compiler = os.environ.get('CC') or shutil.which('clang') or shutil.which('gcc')
|
||||
# Проверяет условие if not compiler перед выполнением следующего блока.
|
||||
if not compiler:
|
||||
# Останавливает текущую операцию с исключением SystemExit('Clang or GCC is required in PATH').
|
||||
raise SystemExit('Clang or GCC is required in PATH')
|
||||
# Задаёт link_flags по выражению справа; значение используется последующими операциями.
|
||||
link_flags = [] if 'gcc' in Path(compiler).name else ['-nostdlib', '-fuse-ld=lld', '-Wl,/noentry,/nodefaultlib']
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory(prefix='ump-recorder-') as directory с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory(prefix='ump-recorder-') as directory:
|
||||
# Exercise the production identity binding too, using a build-local header.
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([
|
||||
# Продолжает текущий вызов, список или выражение: os.sys.executable, str(root / 'UKSSTMS320F28335/prepare_identity.py'),; порядок аргументов сохраняется.
|
||||
os.sys.executable, str(root / 'UKSSTMS320F28335/prepare_identity.py'),
|
||||
# Продолжает текущий вызов, список или выражение: '--project', str(root / 'UKSSTMS320F28335'), '--templates', str(templates),; порядок аргументов сохраняется.
|
||||
'--project', str(root / 'UKSSTMS320F28335'), '--templates', str(templates),
|
||||
# Продолжает текущий вызов, список или выражение: '--output', directory,; порядок аргументов сохраняется.
|
||||
'--output', directory,
|
||||
# Задаёт ], check по выражению справа; значение используется последующими операциями.
|
||||
], check=True)
|
||||
# Задаёт library по выражению справа; значение используется последующими операциями.
|
||||
library = Path(directory) / 'recorder_test.dll'
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([
|
||||
# Продолжает текущий вызов, список или выражение: compiler, '-shared', *link_flags, '-Wno-unknown-pragmas', '-Wno-int-to-pointer-cast',; порядок аргументов сохраняется.
|
||||
compiler, '-shared', *link_flags, '-Wno-unknown-pragmas', '-Wno-int-to-pointer-cast',
|
||||
# Продолжает текущий вызов, список или выражение: '-Itests/ump_logger/stubs', '-ISource/Internal/Include',; порядок аргументов сохраняется.
|
||||
'-Itests/ump_logger/stubs', '-ISource/Internal/Include',
|
||||
# Продолжает текущий вызов, список или выражение: '-I' + str(protocol), '-I' + str(protocol / 'ports/tms320f28335'),; порядок аргументов сохраняется.
|
||||
'-I' + str(protocol), '-I' + str(protocol / 'ports/tms320f28335'),
|
||||
# Продолжает текущий вызов, список или выражение: '-I' + str(templates / 'c/firmware-info/include'), '-I' + directory,; порядок аргументов сохраняется.
|
||||
'-I' + str(templates / 'c/firmware-info/include'), '-I' + directory,
|
||||
# Продолжает текущий вызов, список или выражение: 'tests/ump_logger/recorder_test.c', 'Source/Internal/shared_ump.c', '-o', str(library),; порядок аргументов сохраняется.
|
||||
'tests/ump_logger/recorder_test.c', 'Source/Internal/shared_ump.c', '-o', str(library),
|
||||
# Задаёт ], cwd по выражению справа; значение используется последующими операциями.
|
||||
], cwd=root, check=True)
|
||||
# Отдельный процесс освобождает DLL до удаления временной папки Windows.
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
subprocess.run([
|
||||
# Продолжает текущий вызов, список или выражение: os.sys.executable, '-c',; порядок аргументов сохраняется.
|
||||
os.sys.executable, '-c',
|
||||
# Задаёт 'import ctypes,sys; r по выражению справа; значение используется последующими операциями.
|
||||
'import ctypes,sys; r=ctypes.CDLL(sys.argv[1]).run_tests(); '
|
||||
# Задаёт 'print("PASS" if r по выражению справа; значение используется последующими операциями.
|
||||
'print("PASS" if r==0 else f"FAIL: C line {r}"); sys.exit(bool(r))',
|
||||
# Продолжает текущий вызов, список или выражение: str(library),; порядок аргументов сохраняется.
|
||||
str(library),
|
||||
# Задаёт ], check по выражению справа; значение используется последующими операциями.
|
||||
], check=True)
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Объявляет ADC_table — АЦП table. Память определена в другом модуле. */
|
||||
extern unsigned int ADC_table[4];
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Объявляет IMPowse — данные IMPowse; WAKEpowse — данные WAKEpowse. Память определена в другом модуле. */
|
||||
extern unsigned long IMPowse, WAKEpowse;
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Начинает условие: UMP_TEST_DEVICE_H ещё не определён; защищает повторное включение или задаёт значение сборки. */
|
||||
#ifndef UMP_TEST_DEVICE_H
|
||||
/* Определяет защитный символ или переключатель UMP_TEST_DEVICE_H для последующей компиляции. */
|
||||
#define UMP_TEST_DEVICE_H
|
||||
/* Описывает структуру mock_bits; порядок полей определяет расположение данных. */
|
||||
struct mock_bits { unsigned int GPIO3, GPIO6, GPIO8, GPIO11, GPIO58, GPIO62; };
|
||||
/* Описывает структуру mock_reg; порядок полей определяет расположение данных. */
|
||||
struct mock_reg { struct mock_bits bit; };
|
||||
/* Описывает структуру mock_gpio; порядок полей определяет расположение данных. */
|
||||
struct mock_gpio { struct mock_reg GPADAT, GPBDAT; };
|
||||
/* Продолжает список аргументов, полей или выражение extern struct mock_gpio GpioDataRegs;; порядок элементов сохраняется. */
|
||||
extern struct mock_gpio GpioDataRegs;
|
||||
/* Начинает функцию __disable_interrupts; назначение модуля — проверка ump_logger/stubs на модели ПК. */
|
||||
static unsigned int __disable_interrupts(void) { return 0; }
|
||||
/* Начинает функцию __restore_interrupts; назначение модуля — проверка ump_logger/stubs на модели ПК. */
|
||||
static void __restore_interrupts(unsigned int saved) { (void)saved; }
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
#endif
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подмена зависимостей для проверки регистратора без платы. */
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подмена зависимостей для проверки регистратора без платы. */
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Объявляет READY — данные READY; Desk — аппаратно определённый тип платы; Mode — рабочий адрес или режим платы, выбранный перемычками. Память определена в другом модуле. */
|
||||
extern int READY, Desk, Mode;
|
||||
/* Задаёт READY_FREQ = 1000; частота основного такта Timer1 в герцах. */
|
||||
#define READY_FREQ 1000
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подмена зависимостей для проверки регистратора без платы. */
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Объявляет modbus — массив технологических регистров; слово int на C28x занимает 16 бит. Память определена в другом модуле. */
|
||||
extern int modbus[128];
|
||||
/* Задаёт dsk_LOAD = 6; код платы нагрузки. */
|
||||
#define dsk_LOAD 6
|
||||
/* Задаёт Commands = modbus[127]; слово команд, технологический регистр 127. */
|
||||
#define Commands modbus[127]
|
||||
/* Задаёт sens_data = (modbus+24); sens данные. */
|
||||
#define sens_data (modbus+24)
|
||||
/* Задаёт DAC_go = modbus[0x50]; начальный ток нагрузки в мА, технологический регистр 0x50. */
|
||||
#define DAC_go modbus[0x50]
|
||||
/* Задаёт DAC_stop = modbus[0x51]; конечный ток нагрузки в мА, технологический регистр 0x51. */
|
||||
#define DAC_stop modbus[0x51]
|
||||
/* Задаёт DAC_min = modbus[0x79]; ЦАП min. */
|
||||
#define DAC_min() modbus[0x79]
|
||||
/* Задаёт DAC_max = modbus[0x78]; ЦАП max. */
|
||||
#define DAC_max() modbus[0x78]
|
||||
/* Задаёт DAC_cal = modbus[0x7A]; ЦАП cal. */
|
||||
#define DAC_cal() modbus[0x7A]
|
||||
/* Задаёт DAC_04 = modbus[0x6F]; ЦАП 04. */
|
||||
#define DAC_04 modbus[0x6F]
|
||||
/* Задаёт DAC_20 = modbus[0x6E]; ЦАП 20. */
|
||||
#define DAC_20 modbus[0x6E]
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
/* Проверка ump_logger/stubs на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Подмена зависимостей для проверки регистратора без платы. */
|
||||
|
||||
@@ -1,65 +1,117 @@
|
||||
# Проверка ump_logger на модели пк. Комментарии и исходный текст в UTF-8.
|
||||
# Продолжает текущий вызов, список или выражение: """Exercise the current board-specific SCI8 gate without TI tools or hardware."""; порядок аргументов сохраняется.
|
||||
"""Exercise the current board-specific SCI8 gate without TI tools or hardware."""
|
||||
# Импортирует необходимые имена: from pathlib import Path.
|
||||
from pathlib import Path
|
||||
# Подключает модуль struct для этой проверки или подготовки сборки.
|
||||
import struct
|
||||
# Подключает модуль subprocess для этой проверки или подготовки сборки.
|
||||
import subprocess
|
||||
# Подключает модуль sys для этой проверки или подготовки сборки.
|
||||
import sys
|
||||
# Подключает модуль tempfile для этой проверки или подготовки сборки.
|
||||
import tempfile
|
||||
# Подключает модуль unittest для этой проверки или подготовки сборки.
|
||||
import unittest
|
||||
|
||||
# Задаёт ROOT по выражению справа; значение используется последующими операциями.
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
# Задаёт LIMIT по выражению справа; значение используется последующими операциями.
|
||||
LIMIT = (0x3FFF - (128 + 1)) * 2
|
||||
|
||||
|
||||
# Объявляет функцию image и её входные параметры.
|
||||
def image(size):
|
||||
# Задаёт header по выражению справа; значение используется последующими операциями.
|
||||
header = struct.pack('<H', 0x08AA) + bytes(16) + struct.pack('<HH', 0, 0x8000)
|
||||
# Задаёт blocks по выражению справа; значение используется последующими операциями.
|
||||
blocks = max(1, (size-24+131075)//131076)
|
||||
# Задаёт remaining по выражению справа; значение используется последующими операциями.
|
||||
remaining = (size-24-blocks*6)//2
|
||||
# Задаёт result по выражению справа; значение используется последующими операциями.
|
||||
result = bytearray(header)
|
||||
# Перебирает _ in range(blocks) в указанном порядке.
|
||||
for _ in range(blocks):
|
||||
# Задаёт words по выражению справа; значение используется последующими операциями.
|
||||
words = min(65535, remaining)
|
||||
# Задаёт result + по выражению справа; значение используется последующими операциями.
|
||||
result += struct.pack('<HHH', words, 0, 0x8000) + bytes(words*2)
|
||||
# Задаёт remaining - по выражению справа; значение используется последующими операциями.
|
||||
remaining -= words
|
||||
# Возвращает bytes(result)+bytes(2) вызывающему коду и завершает функцию.
|
||||
return bytes(result)+bytes(2)
|
||||
|
||||
|
||||
# Объявляет класс FirmwareGateTest для группировки проверок.
|
||||
class FirmwareGateTest(unittest.TestCase):
|
||||
# Объявляет функцию check_image и её входные параметры.
|
||||
def check_image(self, data, success, profile="AT25256B"):
|
||||
# Открывает управляемый ресурс tempfile.TemporaryDirectory() as directory с автоматическим освобождением.
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
# Задаёт source по выражению справа; значение используется последующими операциями.
|
||||
source = Path(directory) / 'candidate.bin'
|
||||
# Сохраняет подготовленный файл в указанном формате для следующего шага.
|
||||
source.write_bytes(data)
|
||||
# Запускает внешний компилятор, генератор или тест; ненулевой результат проверяется параметрами вызова.
|
||||
result = subprocess.run([
|
||||
# Продолжает текущий вызов, список или выражение: sys.executable, str(ROOT / 'tests/gas167/check_image.py'),; порядок аргументов сохраняется.
|
||||
sys.executable, str(ROOT / 'tests/gas167/check_image.py'),
|
||||
# Продолжает текущий вызов, список или выражение: str(source), '--eeprom', profile,; порядок аргументов сохраняется.
|
||||
str(source), '--eeprom', profile,
|
||||
# Задаёт ], capture_output по выражению справа; значение используется последующими операциями.
|
||||
], capture_output=True)
|
||||
# Задаёт self.assertEqual(result.returncode по выражению справа; значение используется последующими операциями.
|
||||
self.assertEqual(result.returncode == 0, success,
|
||||
# Задаёт result.stderr.decode(errors по выражению справа; значение используется последующими операциями.
|
||||
result.stderr.decode(errors='replace'))
|
||||
# Читает исходный файл или образ для последующей проверки и разбора.
|
||||
self.assertEqual(source.read_bytes(), data)
|
||||
# Возвращает result.stdout + result.stderr вызывающему коду и завершает функцию.
|
||||
return result.stdout + result.stderr
|
||||
|
||||
# Объявляет функцию test_exact_boundary_is_accepted и её входные параметры.
|
||||
def test_exact_boundary_is_accepted(self):
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(LIMIT), True); порядок аргументов сохраняется.
|
||||
self.check_image(image(LIMIT), True)
|
||||
|
||||
# Объявляет функцию test_34a95bc5_size_is_rejected и её входные параметры.
|
||||
def test_34a95bc5_size_is_rejected(self):
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(32518), False); порядок аргументов сохраняется.
|
||||
self.check_image(image(32518), False)
|
||||
|
||||
# Объявляет функцию test_missing_boot_terminator_is_rejected и её входные параметры.
|
||||
def test_missing_boot_terminator_is_rejected(self):
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(100)[:-2], False); порядок аргументов сохраняется.
|
||||
self.check_image(image(100)[:-2], False)
|
||||
|
||||
# Объявляет функцию test_partial_block_is_rejected и её входные параметры.
|
||||
def test_partial_block_is_rejected(self):
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(100)[:-10], False); порядок аргументов сохраняется.
|
||||
self.check_image(image(100)[:-10], False)
|
||||
|
||||
# Объявляет функцию test_m95_capacity_does_not_expand_code_ram и её входные параметры.
|
||||
def test_m95_capacity_does_not_expand_code_ram(self):
|
||||
# Задаёт diagnostic по выражению справа; значение используется последующими операциями.
|
||||
diagnostic = self.check_image(image(261884), False, "M95M02")
|
||||
# Продолжает текущий вызов, список или выражение: self.assertIn(b'outside code RAM', diagnostic); порядок аргументов сохраняется.
|
||||
self.assertIn(b'outside code RAM', diagnostic)
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(261886), False, "M95M02"); порядок аргументов сохраняется.
|
||||
self.check_image(image(261886), False, "M95M02")
|
||||
|
||||
# Объявляет функцию test_m95_image_rejected_for_small_part и её входные параметры.
|
||||
def test_m95_image_rejected_for_small_part(self):
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(32734), True, "M95M02"); порядок аргументов сохраняется.
|
||||
self.check_image(image(32734), True, "M95M02")
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(image(32734), False, "AT25256B"); порядок аргументов сохраняется.
|
||||
self.check_image(image(32734), False, "AT25256B")
|
||||
|
||||
# Объявляет функцию test_wrong_format_is_rejected и её входные параметры.
|
||||
def test_wrong_format_is_rejected(self):
|
||||
# Продолжает текущий вызов, список или выражение: self.check_image(bytes(100), False); порядок аргументов сохраняется.
|
||||
self.check_image(bytes(100), False)
|
||||
|
||||
|
||||
# Проверяет условие if __name__ == '__main__' перед выполнением следующего блока.
|
||||
if __name__ == '__main__':
|
||||
# Продолжает текущий вызов, список или выражение: unittest.main(); порядок аргументов сохраняется.
|
||||
unittest.main()
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* Проверка ump_logger на модели ПК. Русские пояснения сохранены в UTF-8. */
|
||||
/* Декларации TI-интринсиков только для проверки синтаксиса на компьютере. */
|
||||
/* Объявляет интерфейс функции __disable_interrupts; реализация вызывается через этот прототип. */
|
||||
unsigned int __disable_interrupts(void);
|
||||
/* Объявляет интерфейс функции __restore_interrupts; реализация вызывается через этот прототип. */
|
||||
void __restore_interrupts(unsigned int saved);
|
||||
|
||||
Reference in New Issue
Block a user