Files
2026-06-16 15:40:19 +08:00

171 lines
5.7 KiB
Python
Raw Permalink 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.
"""
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("程序正常退出")