主回路函数 protocol_main_loop - beginner-lei/GRBL GitHub Wiki
- include "grbl.h"
- define COMMENT_NONE 0
- define COMMENT_TYPE_PARENTHESES 1
- define COMMENT_TYPE_SEMICOLON 2
//指示并执行来自protocol_process的一行格式化输入。虽然主要是传入流g-code块,这也指导和执行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) { // Empty or comment line. Send status message for syncing purposes. report_status_message(STATUS_OK);
} 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)); }
}
/*
GRBL PRIMARY LOOP:
- /
uint8_t comment = COMMENT_NONE;//注释 uint8_t char_counter = 0;//要执行的串行输入流中的行缓冲区大小 uint8_t c; // Complete initialization procedures upon a power-up or reset. // 在上电或复位时完成初始化过程 // Print welcome message 打印欢迎消息 report_init_message();
// 主回路!当系统中止时,将退出到main()以重置系统。
for (;;) {
while((c = serial_read()) != SERIAL_NO_DATA) { //serial_read()获取串行读取缓冲区中的第一个字节。由主程序调用 if ((c == '\n') || (c == '\r')) { // End of line reached到达行尾 line[char_counter] = 0; // Set string termination character.设置字符串终止字符 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 == ')') { // End of comment. Resume line. But, not if semicolon type comment. if (comment == COMMENT_TYPE_PARENTHESES) { comment = COMMENT_NONE; } } } else { if (c <= ' ') { // Throw away whitepace and control characters 扔掉空格和控制字符 } else if (c == '/') { // 不支持块删除。忽略字符,如果支持,只需要检查系统,如果块删除启用 } else if (c == '(') { //启用注释标记,忽略所有字符直到')'或EOL。注意:这并不完全遵循NIST的定义,但是现在已经足够了。 将来,我们可以简单地删除注释中的项,但保留注释控制字符,以便g-code解析器可以对其进行错误检查。 comment = COMMENT_TYPE_PARENTHESES; } else if (c == ';') { // NOTE: ';' comment to EOL is a LinuxCNC definition. Not NIST.注意:对EOL的注释';'是LinuxCNC的定义。没有国家标准。 comment = COMMENT_TYPE_SEMICOLON; // TODO: Install '%' feature // } else if (c == '%') { //程序开始-结束百分号不支持。注意:这可能是安装来告诉Grbl当一个程序正在运行vs手动输入, 在程序运行期间,系统自动循环启动将继续执行所有内容,直到下一个'%'符号。 这将有助于修复某些函数的恢复问题,这些函数清空规划器缓冲区以按时执行其任务。
} else if (char_counter >= (LINE_BUFFER_SIZE-1)) {//串口接收数据大于80字符时 // 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') { // Upcase lowercase 小写改大写 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.
//当用户手动输入一个有效的运动命令时,自动开始循环。这是为初学者提供的功能,帮助新用户理解g-code。可以禁用它作为一个初学者工具,但是仍然可以操作。如果禁用,则循环启动操作。当用户准备好并且有一个有效的动作时,手动发出循环启动命令 protocol_auto_cycle_start();//自动开始协议循环
}
// return; /* Never reached */ }
void protocol_auto_cycle_start(void) { bit_true_atomic(sys_rt_exec_state, EXEC_CYCLE_START); }