Округлить делитель SCI по формуле аппаратуры, настроить вход RX и обработку ошибок FIFO. Добавить диагностические поля и проверки модели, установить 9600 бод для RS485 при Owen. Сохранить скрипт сборки, обновлённый образ прошивки и карту линковки.
128 lines
12 KiB
Python
128 lines
12 KiB
Python
# Проверка 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)
|