Klipper - 入口模块klippy源码解析

命令行帮助
  • 通过命令行查看帮助信息,可以获取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			# 支持导入模块测试
主流程

在这里插入图片描述

  1. 解析命令行参数信息
  2. 获取git信息
  3. 获取cpu信息和python版本信息
  4. 进入主循环
  5. 实例化主反应器对象(事件监测)
  6. 创建打印机对象
  7. 进入打印操作run方法
  8. 结果在 [‘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和步进电机配置。
  • 最后校验配置文件中是否存在没有定义的参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值