''' 4. UART 协议模块(midware/protocol/uart_protocol.py) 实现 UART 协议核心逻辑:寄存器配置、FIFO 缓冲区写入 / 读取、校验和检测、日志记录,严格遵循需求中的字节操作规则: ''' import struct from loguru import logger from midware.config.base_config import BUS_CONFIG, UART_CHIP_CONFIG, DEVICE_CONFIG_DICT from midware.bus.cache_handler import CacheHandler from midware.core.error_check import check_checksum class UARTProtocol: def __init__(self): self.cache_handler = CacheHandler() # 缓存交互实例 self.write_byte = BUS_CONFIG["WRITE_BYTE_UART"] # 每次写入2字节 self.read_byte = BUS_CONFIG["WRITE_BYTE_UART"] # 每次读取2字节 def write_uart_fifo(self, device_name, raw_data): """将原始数据写入虚拟芯片FIFO缓冲区,按UART协议每次2字节""" if device_name not in DEVICE_CONFIG_DICT: logger.error(f"UART外设不存在:{device_name}") return False # 获取外设基地址、偏移地址 base_addr = DEVICE_CONFIG_DICT[device_name]["base_addr"] offset_addr = DEVICE_CONFIG_DICT[device_name]["offset_addr"] # 校验和检测 if not check_checksum(raw_data, "UART", device_name): return False # 不定长数据分块,每次2字节写入 data_len = len(raw_data) for i in range(0, data_len, self.write_byte): # 截取2字节,不足补0 chunk = raw_data[i:i+self.write_byte] if len(chunk) < self.write_byte: chunk += b'\x00' * (self.write_byte - len(chunk)) # 计算内存地址:基地址+偏移地址 mem_addr = base_addr + offset_addr + UART_CHIP_CONFIG["TBR"] # 写入共享缓存(sysbus WriteDoubleWord) self.cache_handler.write_double_word(mem_addr, struct.unpack(">H", chunk)[0]) logger.debug(f"UART外设{device_name}写入FIFO完成,数据长度:{data_len}") return True def read_uart_fifo(self, device_name): """从虚拟芯片FIFO缓冲区读取数据,按UART协议每次2字节,组成完整帧""" if device_name not in DEVICE_CONFIG_DICT: logger.error(f"UART外设不存在:{device_name}") return b"" # 获取外设基地址、偏移地址 base_addr = DEVICE_CONFIG_DICT[device_name]["base_addr"] offset_addr = DEVICE_CONFIG_DICT[device_name]["offset_addr"] # 读取FIFO剩余字节数 remain_addr = base_addr + offset_addr + UART_CHIP_CONFIG["FIFO_REMAIN"] remain_bytes = self.cache_handler.read_double_word(remain_addr) if remain_bytes == 0: logger.debug(f"UART外设{device_name}FIFO缓冲区无数据") return b"" # 分块读取,每次2字节 raw_data = b"" for _ in range(0, remain_bytes, self.read_byte): mem_addr = base_addr + offset_addr + UART_CHIP_CONFIG["TBR"] # 从共享缓存读取(sysbus ReadDoubleWord) data = self.cache_handler.read_double_word(mem_addr) raw_data += struct.pack(">H", data) # 去除补0的空字节,得到完整帧 raw_data = raw_data.rstrip(b'\x00') logger.debug(f"UART外设{device_name}读取FIFO完成,数据长度:{len(raw_data)}") return raw_data # 全局UART协议实例 uart_protocol = UARTProtocol()