Files
Balsam_167/tests/rs232_fifo/run_test.py
Andrey 3ebfdca0a0 Исправить скорость SCI и добавить диагностику ошибок приёма RS232
Округлить делитель SCI по формуле аппаратуры, настроить вход RX и обработку ошибок FIFO. Добавить диагностические поля и проверки модели, установить 9600 бод для RS485 при Owen. Сохранить скрипт сборки, обновлённый образ прошивки и карту линковки.
2026-10-12 16:44:51 +03:00

128 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Проверка 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):
# Возвращает 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')
# Извлекает инициализацию и обработчики UART, чтобы проверить старт на неочищенной RAM вместе с обменом.
names=['create_uart_vars','RS_SetLineSpeed','RS_RX_Handler','RS_TX_Handler','RS_Send','RS_BSend','RS_SetBitMode', # Проверяет настоящий расчёт делителя SCI вместе с обработчиками приёма и передачи.
# Продолжает текущий вызов, список или выражение: '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>
#include <string.h>
#include <stdint.h>
typedef unsigned short Uint16;
#define interrupt
#define true 1
#define false 0
#define BM_CHAR32 0
#define BM_PACKED 1
#define CNTRL_ADDR_UNIVERSAL 16
#define CNTRL_ADDR 5
#define ADDR_FOR_ALL 0
#define LOBYTE(x) ((x)&255)
#define HIBYTE(x) (((x)>>8)&255)
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(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, 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)