grbl源代码protocal部分

grbl源代码protocal部分

 

serial 收到 G代码命令后,要通过 protocal 来处理

protocol.h

#ifndef protocol_h

#define protocol_h

//行执行串行输入流的缓冲区大小。 线缓存器大小来自于可执行串口输入流

//注意:不是一个问题,除了极端的情况下,但线缓冲区大小太小了和G代码块可以截断。正式,G代码标准支持多达256

//字符。在未来的版本中,这将会增加,当我们知道多少额外

//内存空间我们可以投资或重写刀位点解析器没有这个

//缓冲区。

 

#ifndef LINE_BUFFER_SIZE

#define LINE_BUFFER_SIZE 80

#endif

 

//开始Grbl主循环。它处理所有从串口输入的字符并执行

//他们完成。它还负责完成初始化过程。

void protocol_main_loop();

//检查和执行实时命令在主程序的各种停止点

void protocol_execute_realtime();

.

// void protocol_cycle_start(); //通知步进子系统开始执行刀位点程序缓冲区。

 

// Reinitializes the buffer after a feed hold for a resume.

// void protocol_cycle_reinitialize(); //重新启动缓冲后饲料保持一份简历。

 

// void protocol_feed_hold();   //启动一个提要的正在运行的程序

 

//执行自动循环功能,如果启用。

void protocol_auto_cycle_start();

 

//阻塞,直到所有缓冲的步骤执行

void protocol_buffer_synchronize();

 

#endif

_____________________________________________________________________________________________

实现代码实际上是一个封装代码没有具体实现代码

预先解析定义不同的注释类型。

#define COMMENT_NONE 0

#define COMMENT_TYPE_PARENTHESES 1

#define COMMENT_TYPE_SEMICOLON 2

 

static char line[LINE_BUFFER_SIZE]; // Line to be executed. Zero-terminated. G代码缓存

//指导和执行一行从protocol_process格式化的输入。虽然大多

//输入流刀位点,这也指导和执行Grbl内部命令,

//设置等发起寻的周期,和切换开关状态

static void protocol_execute_line(char *line) 

{      

  protocol_execute_realtime(); // Runtime command check point.

  if (sys.abort) { return; } // Bail to calling function upon system abort  保释调用函数时系统中止

 

  #ifdef REPORT_ECHO_LINE_RECEIVED //选择打印接收路线

    report_echo_line_received(line);

  #endif

 

  if (line[0] == 0) { // 第一个字节等于0表示空行或者是注释行

    // Empty or comment line. Send status message for syncing purposes.

    // 空或注释行。发送状态信息进行同步。

    report_status_message(STATUS_OK);

 

  } else if (line[0] == '$') { //$表示系统命令,执行sys_execute_line()并打印报告信息

    // Grbl '$' system command

    report_status_message(system_execute_line(line));

    

  } else if (sys.state == STATE_ALARM) {

    // Everything else is gcode. Block if in alarm mode.

    report_status_message(STATUS_ALARM_LOCK);

 

  } else {

    // Parse and execute g-code block!

    report_status_message(gc_execute_line(line)); // 执行G代码解析

  }

}

___________________________________________________________________________________________

下面是grbl 循环

void protocol_main_loop()

{

  //完成初始化过程在一个电或复位。

  // Print welcome message   

  report_init_message();

 

  // 检查和报告报警状态重置后,错误,初始化上电。

  if (sys.state == STATE_ALARM) {

    report_feedback_message(MESSAGE_ALARM_LOCK); 

  } else {

    // All systems go! But first check for safety door.

    if (system_check_safety_door_ajar()) {

      bit_true(sys.rt_exec_state, EXEC_SAFETY_DOOR);

      protocol_execute_realtime(); // Enter safety door mode. Should return as IDLE state.

    } else {

      sys.state = STATE_IDLE; // Set system to ready. Clear all state flags.

    } 

    system_execute_startup(line); // Execute startup script.

  }

    

  // ---------------------------------------------------------------------------------  

  // Primary loop! Upon a system abort, this exits back to main() to reset the system. 

  // ---------------------------------------------------------------------------------  

  

  uint8_t comment = COMMENT_NONE;

  uint8_t char_counter = 0;

  uint8_t c;

  for (;;) {

//一行输入的串行数据的过程,作为数据变得可用。执行一个

//初始过滤去除空间和评论和利用所有的信件。

 

//注意:评论时,空间和块删除(如果支持的话)处理技术

//在刀位点解析器,它有助于压缩到Grbl传入的数据

//线缓冲区,这是有限的。刀位点标准实际上州一行不行

//超过256个字符,但是Arduino Uno没有内存空间。

//有更好的处理器,它会很容易把这个初步解析的

//分离任务共享的刀位点解析器和Grbl系统命令。   

    

    while((c = serial_read()) != SERIAL_NO_DATA) {

      if ((c == 'n') || (c == 'r')) { // 回车

        line[char_counter] = 0; // 设置结束

        protocol_execute_line(line); // Line is complete. Execute it!

        comment = COMMENT_NONE;

        char_counter = 0;

      } else {

        if (comment != COMMENT_NONE) {

          // Throw away all comment characters 去掉注释

          if (c == ')') {  //c==41

            // End of comment. Resume line. But, not if semicolon type comment.

            if (comment == COMMENT_TYPE_PARENTHESES) { comment = COMMENT_NONE; }

          }

        } else {

          if (c <= ' ') { 

            // c<20去掉空格和控制字符 

          } else if (c == '/') {

  //块删除不支持。忽略字符。

//注意:如果支持,只需要检查系统是否启用了块删除。           

          } else if (c == '(') {   

            // Enable comments flag and ignore all characters until ')' or EOL.

            // NOTE: This doesn't follow the NIST definition exactly, but is good enough for now.

            // In the future, we could simply remove the items within the comments, but retain the

            // comment control characters, so that the g-code parser can error-check it.

            comment = COMMENT_TYPE_PARENTHESES;

          } else if (c == ';') {

            // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST.

            comment = COMMENT_TYPE_SEMICOLON;

            

          // TODO: Install '%' feature 

          // } else if (c == '%') {

            // Program start-end percent sign NOT SUPPORTED.

            // NOTE: This maybe installed to tell Grbl when a program is running vs manual input,

            // where, during a program, the system auto-cycle start will continue to execute 

            // everything until the next '%' sign. This will help fix resuming issues with certain

            // functions that empty the planner buffer to execute its task on-time.

 

          } else if (char_counter >= (LINE_BUFFER_SIZE-1)) {

            // Detect line buffer overflow. Report error and reset line buffer.

            report_status_message(STATUS_OVERFLOW);

            comment = COMMENT_NONE;

            char_counter = 0;

          } else if (c >= 'a' && c <= 'z') { // 小写转大写

            line[char_counter++] = c-'a'+'A';

          } else {

            line[char_counter++] = c;

          }

        }

      }

    }

    

    // If there are no more characters in the serial read buffer to be processed and executed,

    // this indicates that g-code streaming has either filled the planner buffer or has 

    // completed. In either case, auto-cycle start, if enabled, any queued moves.

 

    protocol_auto_cycle_start(); //系统开始循环

 

    protocol_execute_realtime();  // Runtime command check point. 运行实时命令

 

    if (sys.abort) { return; } // Bail to main() program loop to reset system.            

  }

  

  return;

}

____________________________________________________________________________________________

protocol_execute_realtime()函数主要是是设置各种状态

void protocol_execute_realtime()

{

  uint8_t rt_exec; // Temp variable to avoid calling volatile multiple times.

 

  do { // If system is suspended, suspend loop restarts here.

    

  // Check and execute alarms. 

  rt_exec = sys.rt_exec_alarm; //拷贝全局各自报警标志位变量到rt_exec

  if (rt_exec) { // 如果rt_exec为真进入    

  //系统报警。一切都已经关闭了已经严重错误的东西。报告

//用户错误的来源。如果重要,Grbl禁用通过输入死循环直到系统重置/中止。

    sys.state = STATE_ALARM; // 设置系统为报警状态

    if (rt_exec & EXEC_ALARM_HARD_LIMIT) {

      report_alarm_message(ALARM_HARD_LIMIT_ERROR); //报告报警信息为接近极限值

    } else if (rt_exec & EXEC_ALARM_SOFT_LIMIT) { //报告执行软件限位报警

      report_alarm_message(ALARM_SOFT_LIMIT_ERROR); //报告出现软件限位报警

    } else if (rt_exec & EXEC_ALARM_ABORT_CYCLE) { //执行停止循环报警      

      report_alarm_message(ALARM_ABORT_CYCLE); //出现终止循环报警

    } else if (rt_exec & EXEC_ALARM_PROBE_FAIL) { //执行探查失败报警

      report_alarm_message(ALARM_PROBE_FAIL); //出现探查失败报警

    } else if (rt_exec & EXEC_ALARM_HOMING_FAIL) { //执行返回原点失败报警

      report_alarm_message(ALARM_HOMING_FAIL); //出现返回原点失败报警

    }

    // Halt everything upon a critical event flag. Currently hard and soft limits flag this.

    

    // 停止一切在一个关键事件标志。目前硬和软限制旗帜。

    

    if (rt_exec & EXEC_CRITICAL_EVENT) { //如果系统是循环实际进入

      report_feedback_message(MESSAGE_CRITICAL_EVENT); //报告反馈信息

      bit_false_atomic(sys.rt_exec_state,EXEC_RESET); //清除目前的复位状态

      do { 

        // Nothing. Block EVERYTHING until user issues reset or power cycles. Hard limits

        // typically occur while unattended or not paying attention. Gives the user time

        // to do what is needed before resetting, like killing the incoming stream. The 

        // same could be said about soft limits. While the position is not lost, the incoming

        // stream could be still engaged and cause a serious crash if it continues afterwards.

        

        // TODO: Allow status reports during a critical alarm. Still need to think about implications of this.

//         if (sys.rt_exec_state & EXEC_STATUS_REPORT) { 

//           report_realtime_status();

//           bit_false_atomic(sys.rt_exec_state,EXEC_STATUS_REPORT); 

//         }

      } while (bit_isfalse(sys.rt_exec_state,EXEC_RESET)); //((x & mask) == 0)

    }

    bit_false_atomic(sys.rt_exec_alarm,0xFF); // 清除所有报警标志

  }

  

  // Check amd execute realtime commands /校验和执行实时命令

  rt_exec = sys.rt_exec_state; //拷贝全局各自报警标志位变量到rt_exec

  if (rt_exec) { // Enter only if any bit flag is true

  

    // Execute system abort. 

    if (rt_exec & EXEC_RESET) {

      sys.abort = true;  // Only place this is set true.

      return; // Nothing else to do but exit.

    }

    

    // Execute and serial print status

    if (rt_exec & EXEC_STATUS_REPORT) { 

      report_realtime_status();

      bit_false_atomic(sys.rt_exec_state,EXEC_STATUS_REPORT);

    }

  

    // Execute hold states.

    // NOTE: The math involved to calculate the hold should be low enough for most, if not all, 

    // operational scenarios. Once hold is initiated, the system enters a suspend state to block

    // all main program processes until either reset or resumed.

 

//执行保持状态。

//注意:所涉及的数学计算持有应该足够低对大多数人来说,即使不是全部,

//操作场景。一旦启动,系统进入暂停状态主程序流程,直到重置或恢复。

 

//如果全局各自报警标志位其中(执行取消动作) | (执行进给保持) | (执行安全门)任意一位为真进入

    if (rt_exec & (EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR)) {

      

      // TODO: CHECK MODE? How to handle this? Likely nothing, since it only works when IDLE and then resets Grbl.

  //待办事项:检查模式?如何处理呢?可能没有,因为它只会在空闲,然后重置Grbl。  

                

      // State check for allowable states for hold methods. 状态检查容许状态的方法。

      //系统为闲着状态, 开始循环状态, 回原点状态, 控制取消状态, 开始保持状态, 开始安全门状态时进入

      if ((sys.state == STATE_IDLE) || (sys.state & (STATE_CYCLE | STATE_HOMING | STATE_MOTION_CANCEL | STATE_HOLD | STATE_SAFETY_DOOR))) {

 

        // If in CYCLE state, all hold states immediately initiate a motion HOLD.

//如果在循环状态,所有保持状态立即启动运动。

 

        if (sys.state == STATE_CYCLE) { //如果是循环状态执行暂停状态

          st_update_plan_block_parameters(); // Notify stepper module to recompute for hold deceleration.通知持有减速步进模块来验算。

          sys.suspend = SUSPEND_ENABLE_HOLD; // Initiate holding cycle with flag.

        }

        // If IDLE, Grbl is not in motion. Simply indicate suspend ready state.

        if (sys.state == STATE_IDLE) { sys.suspend = SUSPEND_ENABLE_READY; }

        

        // Execute and flag a motion cancel with deceleration and return to idle. Used primarily by probing cycle

        // to halt and cancel the remainder of the motion.

 

//执行和标志和减速运动取消并返回空闲。主要由探测使用周期停止和取消剩余的运动。

        if (rt_exec & EXEC_MOTION_CANCEL) {

          // MOTION_CANCEL only occurs during a CYCLE, but a HOLD and SAFETY_DOOR may been initiated beforehand

          // to hold the CYCLE. If so, only flag that motion cancel is complete.

          

          // 动作取消只发生在一个周期中,但是,安全门可能事先被启动循环。如果是这样,只有运动标志取消已经完成。

          if (sys.state == STATE_CYCLE) { sys.state = STATE_MOTION_CANCEL; }

          sys.suspend |= SUSPEND_MOTION_CANCEL; // Indicate motion cancel when resuming. Special motion complete.

        }

    

        // Execute a feed hold with deceleration, only during cycle.

        if (rt_exec & EXEC_FEED_HOLD) {

          // Block SAFETY_DOOR state from prematurely changing back to HOLD.

          if (bit_isfalse(sys.state,STATE_SAFETY_DOOR)) { sys.state = STATE_HOLD; }

        }

  

        // Execute a safety door stop with a feed hold, only during a cycle, and disable spindle/coolant.

        // NOTE: Safety door differs from feed holds by stopping everything no matter state, disables powered

        // devices (spindle/coolant), and blocks resuming until switch is re-engaged. The power-down is 

        // executed here, if IDLE, or when the CYCLE completes via the EXEC_CYCLE_STOP flag.

        if (rt_exec & EXEC_SAFETY_DOOR) {

          report_feedback_message(MESSAGE_SAFETY_DOOR_AJAR); 

          // If already in active, ready-to-resume HOLD, set CYCLE_STOP flag to force de-energize.

          // NOTE: Only temporarily sets the 'rt_exec' variable, not the volatile 'rt_exec_state' variable.

          if (sys.suspend & SUSPEND_ENABLE_READY) { bit_true(rt_exec,EXEC_CYCLE_STOP); }

          sys.suspend |= SUSPEND_ENERGIZE;

          sys.state = STATE_SAFETY_DOOR;

        }

         

      }

      bit_false_atomic(sys.rt_exec_state,(EXEC_MOTION_CANCEL | EXEC_FEED_HOLD | EXEC_SAFETY_DOOR));  //清除(执行取消动作)(执行进给保持)(执行安全门)标志位    

    }

          

    // Execute a cycle start by starting the stepper interrupt to begin executing the blocks in queue.

    // 执行一个循环开始启动步进开始执行中断队列的街区

    if (rt_exec & EXEC_CYCLE_START) { //循环开始状态进入

      // Block if called at same time as the hold commands: feed hold, motion cancel, and safety door.

      // Ensures auto-cycle-start doesn't resume a hold without an explicit user-input.

 //块如果在同时举行的命令:保持进给,运动取消,和安全的门。 //确保auto-cycle-start没有简历没有显式的用户输入。

  

      if (!(rt_exec & (EXEC_FEED_HOLD | EXEC_MOTION_CANCEL | EXEC_SAFETY_DOOR))) {   //状态机如果不是保持进给,运动取消,和安全的门。 

        // Cycle start only when IDLE or when a hold is complete and ready to resume.

        // NOTE: SAFETY_DOOR is implicitly blocked. It reverts to HOLD when the door is closed.

//循环开始时只有当闲置或持有完成并准备简历。

//注意:SAFETY_DOOR是隐式地屏蔽。它返回的时候门是关闭的。    

 

// 如果系统状态为闲着状态,系统状态为开始进给或运动取消,暂停标志为位重新开始

        if ((sys.state == STATE_IDLE) || ((sys.state & (STATE_HOLD | STATE_MOTION_CANCEL)) && (sys.suspend & SUSPEND_ENABLE_READY))) {

          // Re-energize powered components, if disabled by SAFETY_DOOR.

          // 由SAFETY_DOOR重振组件供电,如果禁用。

          if (sys.suspend & SUSPEND_ENERGIZE) { 

            // Delayed Tasks: Restart spindle and coolant, delay to power-up, then resume cycle.

            //延迟任务:重新启动主轴和冷却剂,延迟升高,然后恢复周期。

            if (gc_state.modal.spindle != SPINDLE_DISABLE) {   //主轴模式不是失能进入

              spindle_set_state(gc_state.modal.spindle, gc_state.spindle_speed); //设置状态和速度

              delay_ms(SAFETY_DOOR_SPINDLE_DELAY); // TODO: Blocking function call. Need a non-blocking one eventually.

            }

            if (gc_state.modal.coolant != COOLANT_DISABLE) { 

              coolant_set_state(gc_state.modal.coolant); 

              delay_ms(SAFETY_DOOR_COOLANT_DELAY); // TODO: Blocking function call. Need a non-blocking one eventually.

            }

            // TODO: Install return to pre-park position.

          }

          // Start cycle only if queued motions exist in planner buffer and the motion is not canceled.

 

 //开始循环只有排队运动存在于运动没有取消和绘图缓冲器。

 

 //只有在队列马达存在规定的缓冲,并且动机没有让取消,才会循环

 

          if (plan_get_current_block() && bit_isfalse(sys.suspend,SUSPEND_MOTION_CANCEL)) {

            sys.state = STATE_CYCLE;

            st_prep_buffer(); // Initialize step segment buffer before beginning cycle.初始化步开始循环之前

            st_wake_up();

          } else { // Otherwise, do nothing. Set and resume IDLE state.否则,什么也不做,设置和复位空闲模式

            sys.state = STATE_IDLE;

          }

          sys.suspend = SUSPEND_DISABLE; // Break suspend state.

        }

      }    

      bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_START);

    }

    

    // Reinitializes the cycle plan and stepper system after a feed hold for a resume. Called by 

    // realtime command execution in the main program, ensuring that the planner re-plans safely.

    // NOTE: Bresenham algorithm variables are still maintained through both the planner and stepper

    // cycle reinitializations. The stepper path should continue exactly as if nothing has happened.   

    // NOTE: EXEC_CYCLE_STOP is set by the stepper subsystem when a cycle or feed hold completes.

 

//重新启动后循环计划和步进系统的进给保持简历。通过实时命令执行主程序,确保安全计划重新计划。

//注意:画线算法变量仍保持通过规划师和步进

//循环仅。步进路径应该继续,好像什么都没发生一样。

//注意:EXEC_CYCLE_STOP由步进子系统周期或进给保持时完成。

 

    if (rt_exec & EXEC_CYCLE_STOP) { //如果是循环停止状态进入

      if (sys.state & (STATE_HOLD | STATE_SAFETY_DOOR)) {

        // Hold complete. Set to indicate ready to resume.  Remain in HOLD or DOOR states until user

        // has issued a resume command or reset.

 

//保存完整。设置为指示准备简历。继续持有或门状态,直到用户

//已发布了一份简历命令或重置。

        if (sys.suspend & SUSPEND_ENERGIZE) { // De-energize system if safety door has been opened. 如果安全的门已被打开。断开系统

          spindle_stop();

          coolant_stop();

          // TODO: Install parking motion here. 安装停车动作。

        }

        bit_true(sys.suspend,SUSPEND_ENABLE_READY);

      } else { // Motion is complete. Includes CYCLE, HOMING, and MOTION_CANCEL states. 电机完成,循环,回原点,,MOTION_CANCEL

        sys.suspend = SUSPEND_DISABLE;

        sys.state = STATE_IDLE;

      }

      bit_false_atomic(sys.rt_exec_state,EXEC_CYCLE_STOP);

    }

    

  }

 

  // Overrides flag byte (sys.override) and execution should be installed here, since they 

  // are realtime and require a direct and controlled interface to the main stepper program.

 

  //重写标志字节(sys.override)和执行应该安装在这里,因为他们

  //实时和需要直接和控制接口的主要步进程序。

 

 

  // Reload step segment buffer 重新加载步段缓冲

  if (sys.state & (STATE_CYCLE | STATE_HOLD | STATE_MOTION_CANCEL | STATE_SAFETY_DOOR | STATE_HOMING)) { st_prep_buffer(); }  

  

  // If safety door was opened, actively check when safety door is closed and ready to resume.

  // NOTE: This unlocks the SAFETY_DOOR state to a HOLD state, such that CYCLE_START can activate a resume.

 

  //如果安全的门被打开,积极检查当安全门关闭,准备简历。

  //注意:这解锁SAFETY_DOOR状态保持状态,这样CYCLE_START可以激活一个简历。

 

  if (sys.state == STATE_SAFETY_DOOR) { //安全门状态进入

    if (bit_istrue(sys.suspend,SUSPEND_ENABLE_READY)) { 

      if (!(system_check_safety_door_ajar())) {

        sys.state = STATE_HOLD; // Update to HOLD state to indicate door is closed and ready to resume. 更新保存状态指示门关闭,准备简历。

      }

    }

  }

 

  } while(sys.suspend); // Check for system suspend state before exiting.

  

__________________________________________________________________________________________

//阻塞,直到所有缓冲的步骤执行或循环状态。与进给保持

//在一个同步调用,如果它会发生。同时,等待清洁周期结束。

 

void protocol_buffer_synchronize()

{

  // If system is queued, ensure cycle resumes if the auto start flag is present.

  //如果排队系统,确保循环简历如果汽车开始标记。

 

  protocol_auto_cycle_start();

  do {

    protocol_execute_realtime();   // Check and execute run-time commands

    if (sys.abort) { return; } // Check for system abort

  } while (plan_get_current_block() || (sys.state == STATE_CYCLE));

}

 

分享:

你可能感兴趣的:(grbl源代码protocal部分)