📄 halcmd_commands.c
字号:
/* Copyright (C) 2007 Jeff Epler <jepler@unpythonic.net> * Copyright (C) 2003 John Kasunich * <jmkasunich AT users DOT sourceforge DOT net> * * Other contributers: * Martin Kuhnle * <mkuhnle AT users DOT sourceforge DOT net> * Alex Joni * <alex_joni AT users DOT sourceforge DOT net> * Benn Lipkowitz * <fenn AT users DOT sourceforge DOT net> * Stephen Wille Padnos * <swpadnos AT users DOT sourceforge DOT net> * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General * Public License as published by the Free Software Foundation. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA * * THE AUTHORS OF THIS LIBRARY ACCEPT ABSOLUTELY NO LIABILITY FOR * ANY HARM OR LOSS RESULTING FROM ITS USE. IT IS _EXTREMELY_ UNWISE * TO RELY ON SOFTWARE ALONE FOR SAFETY. Any machinery capable of * harming persons must have provisions for completely removing power * from all motors, etc, before persons enter any danger area. All * machinery must be designed to comply with local and national safety * codes, and the authors of this software can not, and do not, take * any responsibility for such compliance. * * This code was written as part of the EMC HAL project. For more * information, go to www.linuxcnc.org. */#include "config.h"#include "rtapi.h" /* RTAPI realtime OS API */#include "hal.h" /* HAL public API decls */#include "../hal_priv.h" /* private HAL decls */#include "halcmd_commands.h"#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>#include <sys/stat.h>#include <sys/wait.h>#include <unistd.h>#include <fcntl.h>#include <signal.h>#include <errno.h>#include <time.h>#include <fnmatch.h>static int unloadrt_comp(char *mod_name);static void print_comp_info(char **patterns);static void print_pin_info(char **patterns);static void print_sig_info(char **patterns);static void print_script_sig_info(char **patterns);static void print_param_info(char **patterns);static void print_funct_info(char **patterns);static void print_thread_info(char **patterns);static void print_comp_names(char **patterns);static void print_pin_names(char **patterns);static void print_sig_names(char **patterns);static void print_param_names(char **patterns);static void print_funct_names(char **patterns);static void print_thread_names(char **patterns);static void print_lock_status();static int count_list(int list_root);static void print_mem_status();static char *data_type(int type);static char *data_type2(int type);static char *pin_data_dir(int dir);static char *param_data_dir(int dir);static char *data_arrow1(int dir);static char *data_arrow2(int dir);static char *data_value(int type, void *valptr);static char *data_value2(int type, void *valptr);static void save_comps(FILE *dst);static void save_signals(FILE *dst, int only_unlinked);static void save_links(FILE *dst, int arrows);static void save_nets(FILE *dst, int arrows);static void save_params(FILE *dst);static void save_threads(FILE *dst);static void print_help_commands(void);static int match(char **patterns, char *value) { int i; if(!patterns || !patterns[0] || !patterns[0][0]) return 1; for(i=0; patterns[i] && *patterns[i]; i++) { char *pattern = patterns[i]; if(strncmp(pattern, value, strlen(pattern)) == 0) return 1; if (fnmatch(pattern, value, 0) == 0) return 1; } return 0;}int do_lock_cmd(char *command){ int retval=0; /* if command is blank or "all", want to lock everything */ if ((command == NULL) || (strcmp(command, "all") == 0)) { retval = hal_set_lock(HAL_LOCK_ALL); } else if (strcmp(command, "none") == 0) { retval = hal_set_lock(HAL_LOCK_NONE); } else if (strcmp(command, "tune") == 0) { retval = hal_set_lock(HAL_LOCK_LOAD & HAL_LOCK_CONFIG); } else if (strcmp(command, "all") == 0) { retval = hal_set_lock(HAL_LOCK_ALL); } if (retval == 0) { /* print success message */ halcmd_info("Locking completed"); } else { halcmd_error("Locking failed\n"); } return retval;}int do_unlock_cmd(char *command){ int retval=0; /* if command is blank or "all", want to unlock everything */ if ((command == NULL) || (strcmp(command, "all") == 0)) { retval = hal_set_lock(HAL_LOCK_NONE); } else if (strcmp(command, "all") == 0) { retval = hal_set_lock(HAL_LOCK_NONE); } else if (strcmp(command, "tune") == 0) { retval = hal_set_lock(HAL_LOCK_LOAD & HAL_LOCK_CONFIG); } if (retval == 0) { /* print success message */ halcmd_info("Unlocking completed"); } else { halcmd_error("Unlocking failed\n"); } return retval;}int do_linkpp_cmd(char *first_pin_name, char *second_pin_name){ int retval; hal_pin_t *first_pin, *second_pin; static int dep_msg_printed = 0; if ( dep_msg_printed == 0 ) { halcmd_warning("linkpp command is deprecated, use 'net'\n"); dep_msg_printed = 1; } rtapi_mutex_get(&(hal_data->mutex)); /* check if the pins are there */ first_pin = halpr_find_pin_by_name(first_pin_name); second_pin = halpr_find_pin_by_name(second_pin_name); if (first_pin == 0) { /* first pin not found*/ rtapi_mutex_give(&(hal_data->mutex)); halcmd_error("pin '%s' not found\n", first_pin_name); return HAL_INVAL; } else if (second_pin == 0) { rtapi_mutex_give(&(hal_data->mutex)); halcmd_error("pin '%s' not found\n", second_pin_name); return HAL_INVAL; } /* give the mutex, as the other functions use their own mutex */ rtapi_mutex_give(&(hal_data->mutex)); /* check that both pins have the same type, don't want to create a sig, which after that won't be usefull */ if (first_pin->type != second_pin->type) { halcmd_error("pins '%s' and '%s' not of the same type\n", first_pin_name, second_pin_name); return HAL_INVAL; } /* now create the signal */ retval = hal_signal_new(first_pin_name, first_pin->type); if (retval == HAL_SUCCESS) { /* if it worked, link the pins to it */ retval = hal_link(first_pin_name, first_pin_name); if ( retval == HAL_SUCCESS ) { /* if that worked, link the second pin to the new signal */ retval = hal_link(second_pin_name, first_pin_name); } } if (retval != HAL_SUCCESS) { halcmd_error("linkpp failed\n"); } return retval;}int do_linkps_cmd(char *pin, char *sig){ int retval; retval = hal_link(pin, sig); if (retval == 0) { /* print success message */ halcmd_info("Pin '%s' linked to signal '%s'\n", pin, sig); } else { halcmd_error("link failed\n"); } return retval;}int do_linksp_cmd(char *sig, char *pin) { return do_linkps_cmd(pin, sig);}int do_unlinkp_cmd(char *pin){ int retval; retval = hal_unlink(pin); if (retval == 0) { /* print success message */ halcmd_info("Pin '%s' unlinked\n", pin); } else { halcmd_error("unlink failed\n"); } return retval;}int do_source_cmd(char *hal_filename) { FILE *f = fopen(hal_filename, "r"); char buf[MAX_CMD_LEN+1]; int fd; int result = HAL_SUCCESS; int lineno_save = halcmd_get_linenumber(); int linenumber = 0; const char *filename_save = halcmd_get_filename(); if(!f) { fprintf(stderr, "Could not open hal file '%s': %s\n", hal_filename, strerror(errno)); return HAL_FAIL; } fd = fileno(f); fcntl(fd, F_SETFD, FD_CLOEXEC); halcmd_set_filename(hal_filename); while(1) { char *readresult = fgets(buf, MAX_CMD_LEN, f); halcmd_set_linenumber(linenumber++); if(readresult == 0) { if(feof(f)) break; halcmd_error("Error reading file: %s\n", strerror(errno)); result = HAL_FAIL; break; } result = halcmd_parse_line(buf); if(result != 0) break; } halcmd_set_linenumber(lineno_save); halcmd_set_filename(filename_save); linenumber = lineno_save; fclose(f); return result;}int do_start_cmd(void) { int retval = hal_start_threads(); if (retval == 0) { /* print success message */ halcmd_info("Realtime threads started\n"); } return retval;}int do_stop_cmd(void) { int retval = hal_stop_threads(); if (retval == 0) { /* print success message */ halcmd_info("Realtime threads stopped\n"); } return retval;}int do_addf_cmd(char *func, char *thread, char **opt) { char *position_str = opt ? opt[0] : NULL; int position = -1; int retval; if(position_str && *position_str) position = atoi(position_str); retval = hal_add_funct_to_thread(func, thread, position); if(retval == 0) { halcmd_info("Function '%s' added to thread '%s'\n", func, thread); } else { halcmd_error("addf failed\n"); } return retval;}int do_delf_cmd(char *func, char *thread) { int retval; retval = hal_del_funct_from_thread(func, thread); if(retval == 0) { halcmd_info("Function '%s' removed from thread '%s'\n", func, thread); } else { halcmd_error("delf failed\n"); } return retval;}static int preflight_net_cmd(char *signal, hal_sig_t *sig, char *pins[]) { int i, type=-1, writers=0, bidirs=0, pincnt=0; /* if signal already exists, use its info */ if (sig) { type = sig->type; writers = sig->writers; bidirs = sig->bidirs; } for(i=0; pins[i] && *pins[i]; i++) { hal_pin_t *pin = 0; pin = halpr_find_pin_by_name(pins[i]); if(!pin) { halcmd_error("pin '%s' does not exist\n", pins[i]); return HAL_NOTFND; } if(SHMPTR(pin->signal) == sig) { /* Already on this signal */ pincnt++; continue; } else if(pin->signal != 0) { halcmd_error("pin '%s' was already linked\n", pin->name); return HAL_INVAL; } if (type == -1) { /* no pre-existing type, use this pin's type */ type = pin->type; } if(type != pin->type) { halcmd_error("Type mismatch on pin '%s'\n", pin->name); return HAL_INVAL; } if(pin->dir == HAL_OUT) { if(writers || bidirs) { halcmd_error("Signal '%s' can not add OUT pin '%s'\n", signal, pin->name); return HAL_INVAL; } writers++; } if(pin->dir == HAL_IO) { if(writers) { halcmd_error("Signal '%s' can not add I/O pin '%s'\n", signal, pin->name); return HAL_INVAL; } bidirs++; } pincnt++; } if(pincnt) return HAL_SUCCESS; halcmd_error("'net' requires at least one pin, none given\n"); return HAL_INVAL;}int do_net_cmd(char *signal, char *pins[]) { hal_sig_t *sig; int i, retval; rtapi_mutex_get(&(hal_data->mutex)); /* see if signal already exists */ sig = halpr_find_sig_by_name(signal); /* verify that everything matches up (pin types, etc) */ retval = preflight_net_cmd(signal, sig, pins); if(retval != HAL_SUCCESS) { rtapi_mutex_give(&(hal_data->mutex)); return retval; } { hal_pin_t *pin = halpr_find_pin_by_name(signal); if(pin) { halcmd_error("Signal name '%s' must not be the same as a pin.\n", signal); rtapi_mutex_give(&(hal_data->mutex)); return HAL_BADVAR; } } if(!sig) { /* Create the signal with the type of the first pin */ hal_pin_t *pin = halpr_find_pin_by_name(pins[0]); rtapi_mutex_give(&(hal_data->mutex)); if(!pin) { return HAL_NOTFND; } retval = hal_signal_new(signal, pin->type); } else { /* signal already exists */ rtapi_mutex_give(&(hal_data->mutex)); } /* add pins to signal */ for(i=0; retval == HAL_SUCCESS && pins[i] && *pins[i]; i++) { retval = do_linkps_cmd(pins[i], signal); } return retval;}#if 0 /* newinst deferred to version 2.2 */int do_newinst_cmd(char *comp_name, char *inst_name) { hal_comp_t *comp = halpr_find_comp_by_name(comp_name); if(!comp) { halcmd_error( "No such component: %s\n", comp_name); return HAL_NOTFND; } if(!comp->make) { halcmd_error( "%s does not support 'newinst'\n", comp_name); return HAL_UNSUP; } if ( *inst_name == '\0' ) { halcmd_error( "Must supply name for new instance\n"); return HAL_INVAL; } #if defined(RTAPI_SIM) { char *argv[MAX_TOK]; int m = 0, result; argv[m++] = EMC2_BIN_DIR "/rtapi_app"; argv[m++] = "newinst"; argv[m++] = comp_name; argv[m++] = inst_name; argv[m++] = 0; result = hal_systemv(argv); if(result != 0) { halcmd_error( "newinst failed: %d\n", result); return HAL_FAIL; } }#else { FILE *f; f = fopen("/proc/rtapi/hal/newinst", "w"); if(!f) { halcmd_error( "cannot open proc entry: %s\n", strerror(errno)); return HAL_FAIL; } rtapi_mutex_get(&(hal_data->mutex)); while(hal_data->pending_constructor) { struct timespec ts = {0, 100 * 1000 * 1000}; // 100ms rtapi_mutex_give(&(hal_data->mutex));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -