Files

171 lines
5.7 KiB
Python
Raw Permalink Normal View History

2026-06-16 15:40:19 +08:00
"""
anthor:Tan Mingyan
time2026/3/6
功能主函数实现多线程UDP收发和总线收发
"""
import sys
import os
import io
import time
from pathlib import Path
# main.py 导入解耦模块
from midware.core import start_all_threads, stop_all_threads
from midware.network.udp_handler import MultiUDPServer
from loguru import logger
from midware.config.base_config import (
init_base_config,
update_device_config,
get_device_config
)
import midware.config.base_config as base_config
from midware.drivers import DRIVER_MAPPING #2026/3/9
# 添加工程根目录到环境变量(确保配置文件路径正确)
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
sys.path.append(PROJECT_ROOT)
# 修正配置文件路径为绝对路径(避免相对路径导致文件找不到)
CSV_CONFIG_PATH = os.path.join(PROJECT_ROOT, "config_files/device_config.csv")
# 驱动配置可从yaml文件加载波特率暂时无效
DRIVER_CONFIGS = {
"1553B": {"board_id": 0, "bc_address": 0x01},
"CAN": {"channel": 0, "baudrate": 500000},
"UART": {"port": "COM3", "baudrate": 9600},
"AD": {"sampling_rate": 1000},
"OC": {"output_voltage": 5.0},
"网络": {"ip": "192.168.1.100", "port": 8080}
}
# ========== 修复点3初始化日志避免日志写入触发流错误 ==========
def init_logger():
"""初始化日志使用原始stdout避免重定向流关闭问题"""
# 清空默认日志配置
logger.remove()
# 确保日志目录存在
Path("logs").mkdir(exist_ok=True)
# 运行日志
logger.add(
"logs/run_{time:YYYY-MM-DD}.log",
rotation="daily",
level="INFO",
format="{time} | {level} | {module}:{line} | {message}",
enqueue=True, # 异步写入避免句柄阻塞
catch=True # 捕获日志写入异常
)
# 错误日志
logger.add(
"logs/error_{time:YYYY-MM-DD}.log",
rotation="daily",
level="ERROR",
format="{time} | {level} | {module}:{line} | {message}",
enqueue=True,
catch=True
)
# 控制台输出关键使用原始stdout避免重定向流关闭报错
logger.add(
sys.__stdout__,
level="INFO",
format="{time} | {level} | {module}:{line} | {message}",
enqueue=True,
catch=True
)
return logger
# 启动线程(无需写冗长路径)
#threads = start_all_threads(udp_server)
# main.py 核心修改
if __name__ == "__main__":
# 初始化日志、加载配置、实例化UDP服务原有逻辑...
# 初始化日志(最先执行,避免后续报错无日志)
log = init_logger()
log.info("虚拟仿真平台中间层软件启动")
logger.info("========== 虚拟仿真平台中间层软件 启动 ==========")
# 初始化基础配置
try:
init_base_config()
device_config = get_device_config()
if not device_config:
logger.error("基础配置加载为空,工程无法启动!")
sys.exit(1)
logger.info("基础配置初始化成功")
except Exception as e:
logger.error(f"基础配置初始化失败:{str(e)}", exc_info=True)
sys.exit(1)
# 检查外设配置
if not base_config.DEVICE_CONFIG_DICT:
logger.error("外设配置加载失败,工程启动终止")
sys.exit(1)
else:
logger.info("外设配置加载成功")
# 改用logger输出避免print触发流错误
logger.info("程序运行到这里了")
# 实例化UDP服务避免global关键字减少生命周期问题
udp_server = None
try:
udp_server = MultiUDPServer()
logger.info(
f"工程启动成功|外设数量:{len(device_config)}"
f"UDP监听端口{list(udp_server.udp_sockets.keys()) if hasattr(udp_server, 'udp_sockets') else []}"
)
except Exception as e:
logger.error(f"UDP服务初始化失败{str(e)}", exc_info=True)
sys.exit(1)
# 启动所有解耦线程(替代原主循环)
#threads = start_all_threads(udp_server)
threads = start_all_threads(
udp_server=udp_server,
bus_driver_configs=DRIVER_CONFIGS # 2026/3/9 新增驱动配置参数
)
# main.py 主线程
'''
while True:
# 打印各队列长度
logger.info("队列状态:")
for proto, q in bus_recv_queues.items():
logger.info(f" {proto} 接收队列:{q.qsize()}/{q.maxsize}")
for proto, q in bus_send_queues.items():
logger.info(f" {proto} 发送队列:{q.qsize()}/{q.maxsize}")
time.sleep(1) # 每秒监控一次
'''
# 主线程:仅负责等待退出信号,不处理业务
# main.py
from midware.drivers.renode_agent import renode, renode_async_data_dispatcher
# 只加这一行
if not renode.start():
exit()
time.sleep(5)
renode.start_async_listener(renode_async_data_dispatcher)
time.sleep(10)
# 加载完DEVICE_CONFIG_DICT之后加
from midware.drivers.renode_agent import start_renode_uart_redirect
from midware.drivers.tcp_uart_agent import start_all_tcp_uart_clients
# 启动Renode的UART TCP重定向
start_renode_uart_redirect()
time.sleep(1)
# 启动所有TCP客户端接收
start_all_tcp_uart_clients()
try:
while True:
time.sleep(1) # 主线程休眠避免CPU占用
except KeyboardInterrupt:
logger.info("用户终止程序,开始优雅退出...")
stop_all_threads() # 等待队列处理完成
udp_server.close() # 关闭UDP服务
udp_server.socket.close() # 强制关闭系统套接字
logger.info("程序正常退出")