命令行帮助
- 通过命令行查看帮助信息,可以获取klippy支持的参数信息
- /home/cln/anaconda3/envs/klipper/bin/python /home/cln/work/klipper/klippy/klippy.py -h
Usage: klippy.py [options] <config file>
Options:
-h, --help show this help message and exit
-i DEBUGINPUT, --debuginput=DEBUGINPUT # 命令配置文件
read commands from file instead of from tty port
-I INPUTTTY, --input-tty=INPUTTTY # 指定输入终端名称
input tty name (default is /tmp/printer)
-a APISERVER, --api-server=APISERVER # 指定API服务器UNIX域套接字文件
api server unix domain socket filename
-l LOGFILE, --logfile=LOGFILE # 自定义日志输出文件
write log to file instead of stderr
-v enable debug messages
-o DEBUGOUTPUT, --debugoutput=DEBUGOUTPUT # debug信息输出文件
write output to file instead of to serial port
-d DICTIONARY, --dictionary=DICTIONARY # 单片机协议数据字典文件
file to read for mcu protocol dictionary
--import-test perform an import module test # 支持导入模块测试
主流程
- 解析命令行参数信息
- 获取git信息
- 获取cpu信息和python版本信息
- 进入主循环
- 实例化主反应器对象(事件监测)
- 创建打印机对象
- 进入打印操作run方法
- 结果在 [‘exit’, ‘error_exit’]状态,则退出主循环,否则清理资源,进入下一轮循环
打印机主控程序
def __init__(self, main_reactor, bglogger, start_args):
self.bglogger = bglogger
self.start_args = start_args
self.reactor = main_reactor
self.reactor.register_callback(self._connect)
self.state_message = message_startup
self.in_shutdown_state = False
self.run_result = None
self.event_handlers = {}
self.objects = collections.OrderedDict()
# Init printer components that must be setup prior to config
for m in [gcode, webhooks]:
m.add_early_printer_objects(self)
该函数是打印机对象类的构造函数,接收三个参数:main_reactor(主反应器)、bglogger(后台日志记录)、start_args(启动参数)。
- self.reactor.register_callback(self._connect):将self._connect 作为回调函数进行注册,在某个时刻满足特定条件时,self.reactor 会回调该函数。
- self.event_handlers: 事件处理字典实例变量,用于存储事件处理程序。
- self.objects:定义的有序字典实例变量,用于存储打印机的组件对象,包含gcode、webhooks、pins、mcu、toolhead、extruder等组件。
- for 循环 用于初始化一些在加载配置之前设置的打印机组件,包含gcode、webhooks,通过调用add_early_printer_objects 方法,将gcode、webhooks添加到 self.objects 里面。webhooks对象里边会初始化socket服务。
打印机对象初始化完成会调用run方法
def run(self):
systime = time.time()
monotime = self.reactor.monotonic()
logging.info("Start printer at %s (%.1f %.1f)",
time.asctime(time.localtime(systime)), systime, monotime)
# Enter main reactor loop
try:
self.reactor.run()
except:
msg = "Unhandled exception during run"
logging.exception(msg)
# Exception from a reactor callback - try to shutdown
try:
self.reactor.register_callback((lambda e:
self.invoke_shutdown(msg)))
self.reactor.run()
except:
logging.exception("Repeat unhandled exception during run")
# Another exception - try to exit
self.run_result = "error_exit"
# Check restart flags
run_result = self.run_result
try:
if run_result == 'firmware_restart':
for n, m in self.lookup_objects(module='mcu'):
m.microcontroller_restart()
self.send_event("klippy:disconnect")
except:
logging.exception("Unhandled exception during post run")
return run_result
这个函数的重点是self.reactor.run(), 进入反应器主循环,这时会回调初始化注册的_connect 方法。
def _connect(self, eventtime):
try:
self._read_config()
self.send_event("klippy:mcu_identify")
for cb in self.event_handlers.get("klippy:connect", []):
if self.state_message is not message_startup:
return
cb()
except (self.config_error, pins.error) as e:
logging.exception("Config error")
self._set_state("%s\n%s" % (str(e), message_restart))
return
except msgproto.error as e:
logging.exception("Protocol error")
self._set_state(self._build_protocol_error_message(e))
util.dump_mcu_build()
return
except mcu.error as e:
logging.exception("MCU error during connect")
self._set_state("%s%s" % (str(e), message_mcu_connect_error))
util.dump_mcu_build()
gcode = self.lookup_object('gcode') #flsun add
gcode.request_restart('firmware_restart') #flsun add
return
except Exception as e:
logging.exception("Unhandled exception during connect")
self._set_state("Internal error during connect: %s\n%s"
% (str(e), message_restart,))
return
try:
self._set_state(message_ready)
for cb in self.event_handlers.get("klippy:ready", []):
if self.state_message is not message_ready:
return
cb()
except Exception as e:
logging.exception("Unhandled exception during ready callback")
self.invoke_shutdown("Internal error during ready callback: %s"
% (str(e),))
该方法首先读取配置文件 self._read_config()
def _read_config(self):
self.objects['configfile'] = pconfig = configfile.PrinterConfig(self)
if self.bglogger is not None:
config = pconfig.read_main_config()
pconfig.log_config(config)
# Create printer components
for m in [pins, mcu]:
m.add_printer_objects(config)
for section_config in config.get_prefix_sections(''):
# 加载配置模块对象核心函数
self.load_object(config, section_config.get_name(), None)
for m in [toolhead]:
m.add_printer_objects(config)
# Validate that there are no undefined parameters in the config file
pconfig.check_unused_options(config)
- 该方法首先读取程序初始化传入的配置文件,对配置信息进行解析。
- 将 pins、mcu组件加入到打印机的self.objects 对象中。
- self.load_object函数,加载配置模块对象核心函数,将配置文件中的模块对象解析,进行import和初始化后,并将其加入到打印机的self.objects 对象。(备注:如果配置文件中出现了类似"[my_module]" 的字段名,程序会自动尝试加载 klippy/extras/my_module.py 文件内的模块。)
- 将toolhead 、extruder组件加入到打印机的self.objects 对象中,并初始化Delta和步进电机配置。
- 最后校验配置文件中是否存在没有定义的参数。