Files
virtual_simulation_midware/midware/protocol/uart_protocol.py

69 lines
3.4 KiB
Python
Raw Normal View History

2026-06-16 15:40:19 +08:00
'''
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()