#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "main.h" #include "cmdopt.h" #include "error.h" #include "output.h" #include "modbmst.h" ///////////////////////////////////////////////////////////////////////////// #define _IS_POWER_OF_2(x) (!!(x) && !((x) & ((x) - 1))) #define _IS_VALID_STATION_NUMBER(s) (((s) > 0) && ((s) <= 99)) #define _IS_VALID_BLOCK_SIZE(s) (((s) >= GFA_BOOTLOADER_MIN_SEND_DATA_BLOCK_SIZE) && ((s) <= GFA_BOOTLOADER_MAX_SEND_DATA_BLOCK_SIZE) && !((s) & 0x03)) ///////////////////////////////////////////////////////////////////////////// #define _OV_HAS_UPLOAD_IMG ((uint32_t)0x00000001) #define _OV_HAS_SHOW_FILE_IMG_INFO ((uint32_t)0x00000002) #define _OV_HAS_SHOW_DEV_IMG_INFO ((uint32_t)0x00000004) #define _OV_HAS_VALIDATE_IMG ((uint32_t)0x00000008) #define _OV_HAS_SHOW_MAT_SER ((uint32_t)0x00000010) #define _OV_HAS_SET_MAT_SER ((uint32_t)0x00000020) #define _OV_HAS_BOOT_PING ((uint32_t)0x00000040) #define _OV_HAS_START_BOOT ((uint32_t)0x00000080) #define _OV_HAS_RESET_BOOT ((uint32_t)0x00000100) #define _OV_HAS_RESCUE_BOOT ((uint32_t)0x00000200) #define _OV_HAS_IMG_FILE ((uint32_t)0x00001000) #define _OV_HAS_ITF_NAME ((uint32_t)0x00002000) #define _OV_HAS_BLOCK_SIZE ((uint32_t)0x00004000) #define _OV_HAS_APP_ADDR ((uint32_t)0x00008000) #define _OV_HAS_X_BAUD_RATE ((uint32_t)0x00010000) #define _OV_HAS_STATION_NUMBER ((uint32_t)0x00020000) #define _OV_HAS_NODE_ADDR ((uint32_t)0x00040000) #define _OV_HAS_SLAVE_ADDR ((uint32_t)0x00080000) #define _OV_HAS_MATERIAL ((uint32_t)0x00100000) #define _OV_HAS_SERIAL ((uint32_t)0x00200000) #define _OV_HAS_PING_INTERVAL ((uint32_t)0x00400000) #define _OV_HAS_NO_SHOW_PROGRESS ((uint32_t)0x00800000) #define _OV_HAS_PAGE_ERASE_TIME ((uint32_t)0x01000000) #define _OV_HAS_MODBUS_SLAVE_ID ((uint32_t)0x02000000) #define _OV_HAS_MODBUS_CTRL_REG ((uint32_t)0x04000000) #define _OV_HAS_FORCE_ALL_PARITIES ((uint32_t)0x08000000) #define _OV_HAS_PLUGIN_MODE ((uint32_t)0x10000000) ///////////////////////////////////////////////////////////////////////////// #define _OV_CMD_MASK ((uint32_t)0x00000FFF) #define _OV_OPT_MASK (~_OV_CMD_MASK) ///////////////////////////////////////////////////////////////////////////// #define _REQ_CONNECTION_OPTS (_OV_HAS_ITF_NAME | _OV_HAS_SLAVE_ADDR) #define _REQ_OPTS_UPLOAD_IMG (_OV_HAS_IMG_FILE | _REQ_CONNECTION_OPTS) #define _REQ_OPTS_SHOW_IMG_INFO_OFFLINE _OV_HAS_IMG_FILE #define _REQ_OPTS_SHOW_IMG_INFO_ONLINE _REQ_CONNECTION_OPTS #define _REQ_OPTS_VALIDATE_IMG (_OV_HAS_IMG_FILE | _REQ_CONNECTION_OPTS) #define _REQ_OPTS_SHOW_MAT_SER _REQ_CONNECTION_OPTS #define _REQ_OPTS_SET_MAT_SER (_REQ_CONNECTION_OPTS | _OV_HAS_MATERIAL | _OV_HAS_SERIAL) #define _REQ_OPTS_BOOT_PING _REQ_CONNECTION_OPTS #define _REQ_OPTS_START_BOOT _REQ_CONNECTION_OPTS #define _REQ_OPTS_RESET_BOOT _REQ_CONNECTION_OPTS #define _REQ_OPTS_RESCUE_BOOT _REQ_CONNECTION_OPTS ///////////////////////////////////////////////////////////////////////////// #define _OPT_CONNECTION_OPTS (_OV_HAS_STATION_NUMBER | _OV_HAS_NODE_ADDR | _OV_HAS_MODBUS_SLAVE_ID | _OV_HAS_MODBUS_CTRL_REG | _OV_HAS_FORCE_ALL_PARITIES) #define _OPT_OPTS_UPLOAD_IMG (_OPT_CONNECTION_OPTS | _OV_HAS_IMG_FILE | _OV_HAS_APP_ADDR | _OV_HAS_X_BAUD_RATE | _OV_HAS_NO_SHOW_PROGRESS | _OV_HAS_PAGE_ERASE_TIME | _OV_HAS_BLOCK_SIZE | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_SHOW_IMG_INFO_OFFLINE (_OV_HAS_APP_ADDR | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_SHOW_IMG_INFO_ONLINE (_OPT_CONNECTION_OPTS | _OV_HAS_X_BAUD_RATE | _OV_HAS_APP_ADDR | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_VALIDATE_IMG (_OPT_CONNECTION_OPTS | _OV_HAS_APP_ADDR | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_SHOW_MAT_SER (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_SET_MAT_SER (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_BOOT_PING (_OPT_CONNECTION_OPTS | _OV_HAS_PING_INTERVAL | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_START_BOOT (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_RESET_BOOT (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE) #define _OPT_OPTS_RESCUE_BOOT (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE) ///////////////////////////////////////////////////////////////////////////// #define _GET_OPTS(m) ((m) & _OV_OPT_MASK) #define _GET_CMD(m) ((m) & _OV_CMD_MASK) #define _HAS_CMD(m) (!!_GET_CMD(m)) #define _HAS_VALID_CMD(m) (_HAS_CMD(m) && _IS_POWER_OF_2(_GET_CMD(m))) #define _IS_OFFLINE_CMD(m) (_GET_CMD(m) == _OV_HAS_SHOW_FILE_IMG_INFO) #define _HAS_REQUIRED_OPTIONS(m, r) ((_GET_OPTS(m) & (r)) == (r)) #define _GET_MISSING_OPTS(m, r) ((_GET_OPTS(m) ^ (r)) & (r)) #define _GET_UNUSED_OPTS(m, r, o) ((_GET_OPTS(m) ^ (r)) & ~(o)) ///////////////////////////////////////////////////////////////////////////// #define _OPT_STRING_UPLOAD_IMG "upload-img" #define _OPT_STRING_VALIDATE_IMG "validate-img" #define _OPT_STRING_SHOW_FILE_IMG_INFO "show-file-img-info" #define _OPT_STRING_SHOW_DEV_IMG_INFO "show-dev-img-info" #define _OPT_STRING_SHOW_MAT_SER "show-mat-ser" #define _OPT_STRING_SET_MAT_SER "set-mat-ser" #define _OPT_STRING_BOOT_PING "ping-target" #define _OPT_STRING_START_BOOT "start-boot" #define _OPT_STRING_RESET_BOOT "reset-boot" #define _OPT_STRING_RESCUE_BOOT "revive-boot" #define _OPT_STRING_ITF_NAME "itf-name" #define _OPT_STRING_X_BAUD_RATE "x-baud-rate" #define _OPT_STRING_STATION_NUMBER "stat-num" #define _OPT_STRING_NODE_ADDR "node-addr" #define _OPT_STRING_MATERIAL "material" #define _OPT_STRING_SERIAL "serial" #define _OPT_STRING_SLAVE_ADDR "stat-num or node-addr" #define _OPT_STRING_APP_BASE_ADDR "app-addr" #define _OPT_STRING_BLOCK_SIZE "block-size" #define _OPT_STRING_PING_INTERVAL "ping-int" #define _OPT_STRING_PAGE_ERASE_TIME "page-erase-time" #define _OPT_STRING_NO_SHOW_PROGRESS "no-progress" #define _OPT_STRING_MODBUS_SLAVE_ID "mb-slave-id" #define _OPT_STRING_MODBUS_CTRL_REG "mb-bl-ctrl-reg" #define _OPT_STRING_FORCE_ALL_PARITIES "force-all-par" #define _OPT_STRING_PLUGIN_MODE "plugin-mode" #define _OPT_STRING_VERBOSITY "verbosity" #define _OPT_STRING_HELP "help" #define _OPT_STRING_IMG_FILE "" #define _MAX_CMD_LENGTH 18 #define _MAX_OPT_LENGTH 15 ///////////////////////////////////////////////////////////////////////////// int g_nVerbosity = CMD_OPT_DEFAULT_VERBOSITY; bool g_bPluginMode = false; ///////////////////////////////////////////////////////////////////////////// static const uint8_t g_nodeTable[] = { // 1 - 99 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9 }; ///////////////////////////////////////////////////////////////////////////// static const char* _GetOptName(uint32_t nOpt) { switch(nOpt) { case _OV_HAS_UPLOAD_IMG: return _OPT_STRING_UPLOAD_IMG; case _OV_HAS_VALIDATE_IMG: return _OPT_STRING_VALIDATE_IMG; case _OV_HAS_SHOW_FILE_IMG_INFO: return _OPT_STRING_SHOW_FILE_IMG_INFO; case _OV_HAS_SHOW_DEV_IMG_INFO: return _OPT_STRING_SHOW_DEV_IMG_INFO; case _OV_HAS_SHOW_MAT_SER: return _OPT_STRING_SHOW_MAT_SER; case _OV_HAS_BOOT_PING: return _OPT_STRING_BOOT_PING; case _OV_HAS_START_BOOT: return _OPT_STRING_START_BOOT; case _OV_HAS_RESET_BOOT: return _OPT_STRING_RESET_BOOT; case _OV_HAS_RESCUE_BOOT: return _OPT_STRING_RESCUE_BOOT; case _OV_HAS_PING_INTERVAL: return _OPT_STRING_PING_INTERVAL; case _OV_HAS_NO_SHOW_PROGRESS: return _OPT_STRING_NO_SHOW_PROGRESS; case _OV_HAS_ITF_NAME: return _OPT_STRING_ITF_NAME; case _OV_HAS_BLOCK_SIZE: return _OPT_STRING_BLOCK_SIZE; case _OV_HAS_APP_ADDR: return _OPT_STRING_APP_BASE_ADDR; case _OV_HAS_X_BAUD_RATE: return _OPT_STRING_X_BAUD_RATE; case _OV_HAS_PAGE_ERASE_TIME: return _OPT_STRING_PAGE_ERASE_TIME; case _OV_HAS_STATION_NUMBER: return _OPT_STRING_STATION_NUMBER; case _OV_HAS_NODE_ADDR: return _OPT_STRING_NODE_ADDR; case _OV_HAS_SLAVE_ADDR: return _OPT_STRING_SLAVE_ADDR; case _OV_HAS_MATERIAL: return _OPT_STRING_MATERIAL; case _OV_HAS_SERIAL: return _OPT_STRING_SERIAL; case _OV_HAS_SET_MAT_SER: return _OPT_STRING_SET_MAT_SER; case _OV_HAS_IMG_FILE: return _OPT_STRING_IMG_FILE; case _OV_HAS_MODBUS_SLAVE_ID: return _OPT_STRING_MODBUS_SLAVE_ID; case _OV_HAS_MODBUS_CTRL_REG: return _OPT_STRING_MODBUS_CTRL_REG; case _OV_HAS_FORCE_ALL_PARITIES: return _OPT_STRING_FORCE_ALL_PARITIES; case _OV_HAS_PLUGIN_MODE: return _OPT_STRING_PLUGIN_MODE; default: return NULL; } } static const char* _GetOptValue(uint32_t nOpt, LPCMD_LINE_ARGS pcla) { static char szValue[32]; switch(nOpt) { case _OV_HAS_UPLOAD_IMG: return _OPT_STRING_UPLOAD_IMG; case _OV_HAS_VALIDATE_IMG: return _OPT_STRING_VALIDATE_IMG; case _OV_HAS_SHOW_FILE_IMG_INFO: return _OPT_STRING_SHOW_FILE_IMG_INFO; case _OV_HAS_SHOW_DEV_IMG_INFO: return _OPT_STRING_SHOW_DEV_IMG_INFO; case _OV_HAS_SHOW_MAT_SER: return _OPT_STRING_SHOW_MAT_SER; case _OV_HAS_BOOT_PING: return _OPT_STRING_BOOT_PING; case _OV_HAS_START_BOOT: return _OPT_STRING_START_BOOT; case _OV_HAS_RESET_BOOT: return _OPT_STRING_RESET_BOOT; case _OV_HAS_RESCUE_BOOT: return _OPT_STRING_RESCUE_BOOT; case _OV_HAS_PING_INTERVAL: snprintf(szValue, sizeof(szValue) - 1, "%d", pcla->nPingIntervalSec); break; case _OV_HAS_ITF_NAME: return pcla->pszDevName ? pcla->pszDevName : "empty"; case _OV_HAS_BLOCK_SIZE: snprintf(szValue, sizeof(szValue) - 1, "%u", pcla->nBlockSize); break; case _OV_HAS_APP_ADDR: snprintf(szValue, sizeof(szValue) - 1, "0x%X", pcla->nStartAddr); break; case _OV_HAS_X_BAUD_RATE: snprintf(szValue, sizeof(szValue) - 1, "%u", pcla->nExBaudrate); break; case _OV_HAS_PAGE_ERASE_TIME: snprintf(szValue, sizeof(szValue) - 1, "%u", pcla->nPageErsaeTime); break; case _OV_HAS_STATION_NUMBER: snprintf(szValue, sizeof(szValue) - 1, "%hhu", pcla->nStationNr); break; case _OV_HAS_NODE_ADDR: snprintf(szValue, sizeof(szValue) - 1, "0x%02hhX", pcla->nNodeAddr); break; case _OV_HAS_SLAVE_ADDR: return _OPT_STRING_SLAVE_ADDR; case _OV_HAS_MATERIAL: return pcla->pszMaterial ? pcla->pszMaterial : "empty"; case _OV_HAS_SERIAL: return pcla->pszSerial ? pcla->pszSerial : "empty"; case _OV_HAS_IMG_FILE: return pcla->pszImgFile ? pcla->pszImgFile : "empty"; case _OV_HAS_NO_SHOW_PROGRESS: return pcla->bNoProgressBlock ? "true" : "false"; case _OV_HAS_MODBUS_SLAVE_ID: snprintf(szValue, sizeof(szValue) - 1, "%hhu", pcla->nModbusSlvID); break; case _OV_HAS_MODBUS_CTRL_REG: snprintf(szValue, sizeof(szValue) - 1, "%hu", pcla->nModbusCtrlReg); break; case _OV_HAS_FORCE_ALL_PARITIES: return "true"; case _OV_HAS_PLUGIN_MODE: return "true"; default: return "empty"; } szValue[31] = '\0'; return szValue; } ///////////////////////////////////////////////////////////////////////////// const char* GfaTfuCmdOpt2String(uint32_t nOpts) { static char szOptStr[600]; if(nOpts) { int nCount = 0; uint32_t nMask = 1; memset(szOptStr, '\0', sizeof(szOptStr)); while(nMask) { if(nOpts & nMask) { const char *pszOptName = _GetOptName(nMask); if(pszOptName) { if(nCount++) strcat(szOptStr, ", "); strcat(szOptStr, pszOptName); } } nMask <<= 1; } return szOptStr; } return ""; } ///////////////////////////////////////////////////////////////////////////// static const struct option g_lo[] = { { _OPT_STRING_UPLOAD_IMG, no_argument, NULL, ov_upload_img }, { _OPT_STRING_VALIDATE_IMG, no_argument, NULL, ov_validate_img }, { _OPT_STRING_SHOW_FILE_IMG_INFO, no_argument, NULL, ov_show_file_img_info }, { _OPT_STRING_SHOW_DEV_IMG_INFO, no_argument, NULL, ov_show_dev_img_info }, { _OPT_STRING_SHOW_MAT_SER, no_argument, NULL, ov_show_mat_ser }, { _OPT_STRING_SET_MAT_SER, no_argument, NULL, ov_set_mat_ser }, { _OPT_STRING_MATERIAL, required_argument, NULL, ov_material }, { _OPT_STRING_SERIAL, required_argument, NULL, ov_serial }, { _OPT_STRING_NO_SHOW_PROGRESS, no_argument, NULL, ov_no_progress }, { _OPT_STRING_BOOT_PING, no_argument, NULL, ov_boot_ping }, { _OPT_STRING_START_BOOT, no_argument, NULL, ov_start_boot }, { _OPT_STRING_RESET_BOOT, no_argument, NULL, ov_reset_boot }, { _OPT_STRING_RESCUE_BOOT, no_argument, NULL, ov_rescue_boot }, { _OPT_STRING_PING_INTERVAL, required_argument, NULL, ov_ping_interval }, { _OPT_STRING_ITF_NAME, required_argument, NULL, ov_itf_name }, { _OPT_STRING_X_BAUD_RATE, required_argument, NULL, ov_x_baud_rate }, { _OPT_STRING_STATION_NUMBER, required_argument, NULL, ov_station_number }, { _OPT_STRING_NODE_ADDR, required_argument, NULL, ov_node_addr }, { _OPT_STRING_PAGE_ERASE_TIME, required_argument, NULL, ov_page_erase_time }, { _OPT_STRING_APP_BASE_ADDR, required_argument, NULL, ov_app_addr }, { _OPT_STRING_BLOCK_SIZE, required_argument, NULL, ov_block_size }, { _OPT_STRING_MODBUS_SLAVE_ID, required_argument, NULL, ov_mb_slave_id }, { _OPT_STRING_MODBUS_CTRL_REG, required_argument, NULL, ov_mb_ctrl_reg }, { _OPT_STRING_FORCE_ALL_PARITIES, no_argument, NULL, ov_force_all_par }, { _OPT_STRING_PLUGIN_MODE, no_argument, NULL, ov_plugin_mode }, { _OPT_STRING_VERBOSITY, required_argument, NULL, ov_verbosity }, { _OPT_STRING_HELP, no_argument, NULL, ov_help }, { NULL, 0, NULL, 0 } }; ///////////////////////////////////////////////////////////////////////////// static int64_t _ArgStr2Num(const char *pszNum, int64_t nDefault) { if(pszNum && *pszNum) { char *pszEnd = NULL; int64_t n = strtoll(pszNum, &pszEnd, 0); if((((n == LLONG_MIN) || (n == LLONG_MAX)) && (errno == ERANGE)) || *pszEnd) return nDefault; return n; } return nDefault; } ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// void GfaTfuCmdOptInitOpts(LPCMD_LINE_ARGS pcla) { memset(pcla, 0, sizeof(CMD_LINE_ARGS)); pcla->nBootBaudrate = CMD_OPT_DEFAULT_BAUDRATE; pcla->nInitBaudrate = CMD_OPT_DEFAULT_BAUDRATE; pcla->nModbBaudrate = CMD_OPT_DEFAULT_BAUDRATE; pcla->modbParity = CMD_OPT_DEFAULT_MODBUS_PARITY; pcla->nBlockSize = GFA_BOOTLOADER_DEF_SEND_DATA_BLOCK_SIZE; pcla->nStartAddr = CMD_OPT_DEFAULT_APP_BASE_ADDRESS; pcla->nPageErsaeTime = CMD_OPT_DEFAULT_PAGE_ERASE_TIME; pcla->nVerbosity = CMD_OPT_DEFAULT_VERBOSITY; pcla->nModbusCtrlReg = CMD_OPT_DEFAULT_MODBUS_START_REGISTER; } ///////////////////////////////////////////////////////////////////////////// int GfaTfuCmdOptParse(int argc, char* argv[], LPCMD_LINE_ARGS pcla) { int opt, nCount = 0; pcla->nOptFlags = 0; while((opt = getopt_long(argc, argv, "-a:b:d:e:fgi:m:n:ps:t:v:x:?", g_lo, NULL)) != -1) { const char *arg = optarg; switch(opt) { case ov_img_file: if(arg) { const char *pszFileBase = strrchr(arg, '/'); pcla->pszImgFile = arg; if(pszFileBase) pcla->pszImgFileBase = ++pszFileBase; pcla->nOptFlags |= _OV_HAS_IMG_FILE; } break; case ov_itf_name: if(arg) { pcla->pszDevName = arg; pcla->nOptFlags |= _OV_HAS_ITF_NAME; } break; case ov_show_dev_img_info: pcla->bShowDevImgInfo = true; pcla->nOptFlags |= _OV_HAS_SHOW_DEV_IMG_INFO; break; case ov_show_file_img_info: pcla->bShowFileImgInfo = true; pcla->nOptFlags |= _OV_HAS_SHOW_FILE_IMG_INFO; break; case ov_show_mat_ser: pcla->bShowMatSer = true; pcla->nOptFlags |= _OV_HAS_SHOW_MAT_SER; break; case ov_set_mat_ser: pcla->bSetMatSer = true; pcla->nOptFlags |= _OV_HAS_SET_MAT_SER; break; case ov_validate_img: pcla->bValidateImg = true; pcla->nOptFlags |= _OV_HAS_VALIDATE_IMG; break; case ov_upload_img: pcla->bUploadImg = true; pcla->nOptFlags |= _OV_HAS_UPLOAD_IMG; break; case ov_boot_ping: pcla->bPing = true; pcla->nOptFlags |= _OV_HAS_BOOT_PING; break; case ov_start_boot: pcla->bStartBoot = true; pcla->nOptFlags |= _OV_HAS_START_BOOT; break; case ov_reset_boot: pcla->bResetBoot = true; pcla->nOptFlags |= _OV_HAS_RESET_BOOT; break; case ov_rescue_boot: pcla->bReviveBoot = true; pcla->nOptFlags |= _OV_HAS_RESCUE_BOOT; break; case ov_ping_interval: pcla->nPingIntervalSec = (int32_t)_ArgStr2Num(arg, 0); if(pcla->nPingIntervalSec > 0) pcla->nOptFlags |= _OV_HAS_PING_INTERVAL; break; case ov_material: if(arg && *arg) { pcla->pszMaterial = arg; pcla->nOptFlags |= _OV_HAS_MATERIAL; } break; case ov_serial: if(arg && *arg) { pcla->pszSerial = arg; pcla->nOptFlags |= _OV_HAS_SERIAL; } break; case ov_no_progress: pcla->bNoProgressBlock = true; pcla->nOptFlags |= _OV_HAS_NO_SHOW_PROGRESS; break; case ov_block_size: pcla->nBlockSize = (uint32_t)_ArgStr2Num(arg, GFA_BOOTLOADER_DEF_SEND_DATA_BLOCK_SIZE); pcla->nOptFlags |= _OV_HAS_BLOCK_SIZE; break; case ov_app_addr: pcla->nStartAddr = (uint32_t)_ArgStr2Num(arg, CMD_OPT_DEFAULT_APP_BASE_ADDRESS); pcla->nOptFlags |= _OV_HAS_APP_ADDR; break; case ov_x_baud_rate: pcla->nExBaudrate = (uint32_t)_ArgStr2Num(arg, 0); pcla->nOptFlags |= _OV_HAS_X_BAUD_RATE; break; case ov_page_erase_time: pcla->nPageErsaeTime = (uint32_t)_ArgStr2Num(arg, CMD_OPT_DEFAULT_PAGE_ERASE_TIME); pcla->nOptFlags |= _OV_HAS_PAGE_ERASE_TIME; break; case ov_station_number: pcla->nStationNr = (uint8_t)_ArgStr2Num(arg, 0); pcla->nOptFlags |= _OV_HAS_STATION_NUMBER; pcla->nOptFlags |= _OV_HAS_SLAVE_ADDR; break; case ov_node_addr: pcla->nNodeAddr = (uint8_t)_ArgStr2Num(arg, 0); pcla->nOptFlags |= _OV_HAS_NODE_ADDR; pcla->nOptFlags |= _OV_HAS_SLAVE_ADDR; break; case ov_mb_slave_id: pcla->nModbusSlvID = (uint8_t)_ArgStr2Num(arg, 0xFF); pcla->nOptFlags |= _OV_HAS_MODBUS_SLAVE_ID; break; case ov_mb_ctrl_reg: pcla->nModbusCtrlReg = (uint16_t)_ArgStr2Num(arg, CMD_OPT_DEFAULT_MODBUS_START_REGISTER); pcla->nOptFlags |= _OV_HAS_MODBUS_CTRL_REG; break; case ov_force_all_par: pcla->bForceAllParities = true; pcla->nOptFlags |= _OV_HAS_FORCE_ALL_PARITIES; break; case ov_plugin_mode: pcla->bPluginMode = true; pcla->nOptFlags |= _OV_HAS_PLUGIN_MODE; break; case ov_verbosity: pcla->nVerbosity = (int)_ArgStr2Num(arg, CMD_OPT_DEFAULT_VERBOSITY); break; case ov_help: ++pcla->nQuestionMarks; pcla->bShowHelp = true; break; } ++nCount; } if(nCount == 0) pcla->bShowHelp = true; return nCount; } ///////////////////////////////////////////////////////////////////////////// int GfaTfuCmdOptProcess(LPCMD_LINE_ARGS pcla) { ///////////////////////////////////////////////////////////////////////// // If help is requested, do nothing else if(pcla->bShowHelp) return 1; ///////////////////////////////////////////////////////////////////////// // adjust verbosity if(pcla->nVerbosity < CMD_OPT_MIN_VERBOSITY) pcla->nVerbosity = CMD_OPT_MIN_VERBOSITY; else if(pcla->nVerbosity > CMD_OPT_MAX_VERBOSITY) pcla->nVerbosity = CMD_OPT_MAX_VERBOSITY; g_nVerbosity = pcla->nVerbosity; ///////////////////////////////////////////////////////////////////////// // if we are in plugin-mode we produce formatted output only if(pcla->bPluginMode) { g_nVerbosity = pcla->nVerbosity = -1; g_bPluginMode = true; } ///////////////////////////////////////////////////////////////////////// // validate commands pcla->nCmdFlags = _GET_CMD(pcla->nOptFlags); if(!_HAS_CMD(pcla->nOptFlags)) { if(!(pcla->nOptFlags & (_OV_HAS_MATERIAL | _OV_HAS_SERIAL))) return GFA_FU_ERROR_NOTHING_TO_DO; } else if(!_HAS_VALID_CMD(pcla->nOptFlags)) return GFA_FU_ERROR_MULTIPLE_COMMANDS; ///////////////////////////////////////////////////////////////////////// // validate connection options if required if(!_IS_OFFLINE_CMD(pcla->nOptFlags)) { if(!pcla->nExBaudrate) pcla->nExBaudrate = pcla->nInitBaudrate; if(!GfaSerialIsValidBaudrate(pcla->nExBaudrate)) return GFA_FU_ERROR_INVALID_BAUDRATE; else if((pcla->nOptFlags & (_OV_HAS_STATION_NUMBER | _OV_HAS_NODE_ADDR)) == (_OV_HAS_STATION_NUMBER | _OV_HAS_NODE_ADDR)) return GFA_FU_ERROR_NODE_STATION_MUTEX; else if(pcla->nOptFlags & _OV_HAS_STATION_NUMBER) { if(!_IS_VALID_STATION_NUMBER(pcla->nStationNr)) return GFA_FU_ERROR_INVALID_STATION_NUM; pcla->nNodeAddr = g_nodeTable[pcla->nStationNr - 1]; } else if((pcla->nOptFlags & _OV_HAS_NODE_ADDR) && (NODE_IS_MULTICAST(pcla->nNodeAddr) || (pcla->nNodeAddr < MINET_MIN_NODE_ADDRESS))) return GFA_FU_ERROR_INVALID_NODE_ADDR; } ///////////////////////////////////////////////////////////////////////// // validate command options switch(pcla->nCmdFlags) { case _OV_HAS_UPLOAD_IMG: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_UPLOAD_IMG)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_UPLOAD_IMG); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } else if((pcla->nOptFlags & _OV_HAS_BLOCK_SIZE) && !_IS_VALID_BLOCK_SIZE(pcla->nBlockSize)) return GFA_FU_ERROR_INVALID_BLOCK_SIZE; else if(pcla->nStartAddr == (uint32_t)-1) return GFA_FU_ERROR_INVALID_APP_START_ADDR; pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_UPLOAD_IMG, _OPT_OPTS_UPLOAD_IMG); pcla->bNeedImgFile = true; break; case _OV_HAS_SHOW_FILE_IMG_INFO: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_OFFLINE)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_OFFLINE); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_OFFLINE, _OPT_OPTS_SHOW_IMG_INFO_OFFLINE); pcla->bNeedImgFile = true; break; case _OV_HAS_SHOW_DEV_IMG_INFO: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_ONLINE)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_ONLINE); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_ONLINE, _OPT_OPTS_SHOW_IMG_INFO_ONLINE); break; case _OV_HAS_VALIDATE_IMG: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_VALIDATE_IMG)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_VALIDATE_IMG); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_VALIDATE_IMG, _OPT_OPTS_VALIDATE_IMG); pcla->bNeedImgFile = true; break; case _OV_HAS_SHOW_MAT_SER: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SHOW_MAT_SER)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_MAT_SER); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_MAT_SER, _OPT_OPTS_SHOW_MAT_SER); break; case _OV_HAS_SET_MAT_SER: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SET_MAT_SER)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SET_MAT_SER); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } if( (strlen(pcla->pszMaterial) >= GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH) || (strlen(pcla->pszSerial) >= GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH)) { return GFA_FU_ERROR_MAT_OR_SER_TOO_LONG; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SET_MAT_SER, _OPT_OPTS_SET_MAT_SER); break; case _OV_HAS_BOOT_PING: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_BOOT_PING)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_BOOT_PING); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } else if(pcla->nPingIntervalSec < 0) return GFA_FU_ERROR_INVALID_COMMAND_OPT; pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_BOOT_PING, _OPT_OPTS_BOOT_PING); break; case _OV_HAS_START_BOOT: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_START_BOOT)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_START_BOOT); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_START_BOOT, _OPT_OPTS_START_BOOT); break; case _OV_HAS_RESET_BOOT: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_RESET_BOOT)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_RESET_BOOT); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_RESET_BOOT, _OPT_OPTS_RESET_BOOT); break; case _OV_HAS_RESCUE_BOOT: if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_RESCUE_BOOT)) { pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_RESCUE_BOOT); return GFA_FU_ERROR_MISSING_COMMAND_OPT; } pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_RESCUE_BOOT, _OPT_OPTS_RESCUE_BOOT); break; default: return 1; } ///////////////////////////////////////////////////////////////////////// // validate optional options if(pcla->nOptFlags & _OV_HAS_MODBUS_SLAVE_ID) { if(!MODBUS_IS_VALID_SLAVE_ID(pcla->nModbusSlvID)) { return GFA_FU_ERROR_INVALID_MODBUS_SLV_ID; } } return 0; } void GfaTfuCmdOptDumpOptions(LPCMD_LINE_ARGS pcla) { if(pcla) { uint32_t nMask, nOpts = 0; TRACE3("****************************\n"); TRACE3("COMMAND: %s\n", _GetOptName(pcla->nCmdFlags)); TRACE3("OPTIONS:\n"); switch(pcla->nCmdFlags) { case _OV_HAS_UPLOAD_IMG: nOpts = pcla->nOptFlags & (_REQ_OPTS_UPLOAD_IMG | _OPT_OPTS_UPLOAD_IMG) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_SHOW_FILE_IMG_INFO: nOpts = pcla->nOptFlags & (_REQ_OPTS_SHOW_IMG_INFO_OFFLINE | _OPT_OPTS_SHOW_IMG_INFO_OFFLINE) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_SHOW_DEV_IMG_INFO: nOpts = pcla->nOptFlags & (_REQ_OPTS_SHOW_IMG_INFO_ONLINE | _OPT_OPTS_SHOW_IMG_INFO_ONLINE) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_VALIDATE_IMG: nOpts = pcla->nOptFlags & (_REQ_OPTS_VALIDATE_IMG | _OPT_OPTS_VALIDATE_IMG) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_SHOW_MAT_SER: nOpts = pcla->nOptFlags & (_REQ_OPTS_SHOW_MAT_SER | _OPT_OPTS_SHOW_MAT_SER) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_SET_MAT_SER: nOpts = pcla->nOptFlags & (_REQ_OPTS_SET_MAT_SER | _OPT_OPTS_SET_MAT_SER) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_BOOT_PING: nOpts = pcla->nOptFlags & (_REQ_OPTS_BOOT_PING | _OPT_OPTS_BOOT_PING) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_START_BOOT: nOpts = pcla->nOptFlags & (_REQ_OPTS_START_BOOT | _OPT_OPTS_START_BOOT) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_RESET_BOOT: nOpts = pcla->nOptFlags & (_REQ_OPTS_RESET_BOOT | _OPT_OPTS_RESET_BOOT) & ~_OV_HAS_SLAVE_ADDR; break; case _OV_HAS_RESCUE_BOOT: nOpts = pcla->nOptFlags & (_REQ_OPTS_RESCUE_BOOT | _OPT_OPTS_RESCUE_BOOT) & ~_OV_HAS_SLAVE_ADDR; break; default: return; } for(nMask = 1; nMask; nMask <<= 1) { if(nOpts & nMask) { TRACE3(" %-*s: %s\n", _MAX_OPT_LENGTH, _GetOptName(nMask), _GetOptValue(nMask, pcla)); } } if(pcla->nUnusedOptFlags) TRACE3(" %-*s: %s\n", _MAX_OPT_LENGTH, "IGNORED", GfaTfuCmdOpt2String(pcla->nUnusedOptFlags)); TRACE3("****************************\n\n"); } } ///////////////////////////////////////////////////////////////////////////// // Examples: // // ./gfativaflashutil --upload-img --itf-name="/dev/ttyO4" -x-baud-rate 230400 -t1 "/opt/GfA/gfativaflashutil/OLS-1V1_0009_crc_9600Baud.bin" -v3 -p -b72 // ./gfativaflashutil --validate-img --itf-name="/dev/ttyO4" --app-addr=0x2000 --node-addr=0x11 "/opt/GfA/gfativaflashutil/OLS-1V1_0009_crc.bin" -v3 // ./gfativaflashutil --show-mat-ser --itf-name="/dev/ttyO4" --stat-num=1 --mb-slave-id 100 -v3 // ./gfativaflashutil --set-mat-ser --itf-name="/dev/ttyO4" --x-baud-rate=115200 --node-addr=0x11 -v3 --material="G.Z.40015 P01" --serial="18-080015 1409" // ./gfativaflashutil --show-file-img-info "/opt/GfA/gfativaflashutil/OLS-1V1_0009_crc.bin" -a0x2000 -v3 // ./gfativaflashutil --show-dev-img-info --itf-name="/dev/ttyO4" --x-baud-rate=115200 --node-addr=0x11 -v3 // ./gfativaflashutil --ping-target --ping-int=1 --itf-name="/dev/ttyO4" --node-addr=0x11 -v3 // ./gfativaflashutil --start-boot --itf-name="/dev/ttyO4" --node-addr=0x11 -v3 // ./gfativaflashutil --reset-boot --itf-name="/dev/ttyO4" --node-addr=0x11 -v3 // ./gfativaflashutil --mb-start-boot --itf-name="/dev/ttyO4" --mb-slave-id 100 -v3 // // void GfaTfuCmdOptDisplayHelp(bool bGfaUser) { printf("\n╔═══════════════════════════════════════════════════════╗\n"); printf("║ gfativaflashutil v%d.%d GfA GmbH (%s %s) ║\n", GFA_FU_VER_MAJOR, GFA_FU_VER_MINOR, __DATE__, __TIME__); printf("╚═══════════════════════════════════════════════════════╝\n\n"); printf(" USAGE: gfativaflashutil COMMAND [OPTIONS] [IMG FILE]\n\n"); printf(" COMMANDS (only one command per execution is permitted):\n"); printf(" --%-*s Upload to the device.\n", _MAX_CMD_LENGTH, _OPT_STRING_UPLOAD_IMG); printf(" --%-*s Validate with the device. (Attempts to\n", _MAX_CMD_LENGTH, _OPT_STRING_VALIDATE_IMG); printf(" %-*s match the material numbers as well).\n", _MAX_CMD_LENGTH, ""); printf(" --%-*s Validate offline and display image\n", _MAX_CMD_LENGTH, _OPT_STRING_SHOW_FILE_IMG_INFO); printf(" %-*s information.\n", _MAX_CMD_LENGTH, ""); printf(" --%-*s Display bootloader and (if available) application\n", _MAX_CMD_LENGTH, _OPT_STRING_SHOW_DEV_IMG_INFO); printf(" %-*s image information of the target device.\n", _MAX_CMD_LENGTH, ""); printf(" --%-*s Display the material and serial number of the\n", _MAX_CMD_LENGTH, _OPT_STRING_SHOW_MAT_SER); printf(" %-*s target device.\n", _MAX_CMD_LENGTH, ""); if(bGfaUser) { printf(" --%-*s Set the material and serial number of the\n", _MAX_CMD_LENGTH, _OPT_STRING_SET_MAT_SER); printf(" %-*s target device.\n", _MAX_CMD_LENGTH, ""); } printf(" --%-*s Ping the target device either once or continuously\n", _MAX_CMD_LENGTH, _OPT_STRING_BOOT_PING); printf(" %-*s dependig on the parameter --%s.\n", _MAX_CMD_LENGTH, "", _OPT_STRING_PING_INTERVAL); printf(" --%-*s Start the bootloader if an application is running.\n", _MAX_CMD_LENGTH, _OPT_STRING_START_BOOT); printf(" --%-*s Reset the bootloader if no application is running.\n", _MAX_CMD_LENGTH, _OPT_STRING_RESET_BOOT); printf(" %-*s If there is a valid application image in flash, it\n", _MAX_CMD_LENGTH, ""); printf(" %-*s will be subsequently started.\n", _MAX_CMD_LENGTH, ""); printf(" --%-*s Try to re-establish communication with the bootloader\n", _MAX_CMD_LENGTH, _OPT_STRING_RESCUE_BOOT); printf(" %-*s if it's in a non-responsive state. This may arise\n", _MAX_CMD_LENGTH, ""); printf(" %-*s after a failed image upload due to an interrupted\n", _MAX_CMD_LENGTH, ""); printf(" %-*s communication line or any transmission failures. It\n", _MAX_CMD_LENGTH, ""); printf(" %-*s seems, that a verbosity of 4 in combination with high\n", _MAX_CMD_LENGTH, ""); printf(" %-*s baud rates can also cause this problem.\n", _MAX_CMD_LENGTH, ""); printf("\n"); printf(" OPTIONS:\n"); printf(" --%-*s -d The name of the communication interface.\n", _MAX_OPT_LENGTH, _OPT_STRING_ITF_NAME); printf(" --%-*s -t Station number. Will be mapped internally\n", _MAX_OPT_LENGTH, _OPT_STRING_STATION_NUMBER); printf(" %-*s to a node address. Must not be used in\n", _MAX_OPT_LENGTH, ""); printf(" %-*s combination with --%s.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_NODE_ADDR); printf(" --%-*s -n The target's node address. Must not be used\n", _MAX_OPT_LENGTH, _OPT_STRING_NODE_ADDR); printf(" %-*s in combination with --%s.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_STATION_NUMBER); printf(" --%-*s -x Extended baud-rate to use for some (but not\n", _MAX_OPT_LENGTH, _OPT_STRING_X_BAUD_RATE); printf(" %-*s all) commands. Because a baud-rate switch\n", _MAX_OPT_LENGTH, ""); printf(" %-*s involves data transfer as well, it will\n", _MAX_OPT_LENGTH, ""); printf(" %-*s only be used with commands that require a\n", _MAX_OPT_LENGTH, ""); printf(" %-*s great amount of data to be transferred!\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s -a Flash address where to load .\n", _MAX_OPT_LENGTH, _OPT_STRING_APP_BASE_ADDR); printf(" %-*s Defaults to 0x%X.\n", _MAX_OPT_LENGTH, "", CMD_OPT_DEFAULT_APP_BASE_ADDRESS); if(bGfaUser) { printf(" --%-*s -m The material number to be set with the\n", _MAX_OPT_LENGTH, _OPT_STRING_MATERIAL); printf(" %-*s --%s command.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_SET_MAT_SER); printf(" --%-*s -s The serial number to be set with the\n", _MAX_OPT_LENGTH, _OPT_STRING_SERIAL); printf(" %-*s --%s command.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_SET_MAT_SER); } printf(" --%-*s -b Size of an upload-block in bytes. (4-76,\n", _MAX_OPT_LENGTH, _OPT_STRING_BLOCK_SIZE); printf(" %-*s must be a multiple of 4!). This option is\n", _MAX_OPT_LENGTH, ""); printf(" %-*s only used with the --%s command.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_UPLOAD_IMG); printf(" %-*s Defaults to %d. There is usually no need\n", _MAX_OPT_LENGTH, "", GFA_BOOTLOADER_DEF_SEND_DATA_BLOCK_SIZE); printf(" %-*s to alter this value.\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s -i The optional ping interval in seconds. If a\n", _MAX_OPT_LENGTH, _OPT_STRING_PING_INTERVAL); printf(" %-*s value greater than 0 is provided, a ping\n", _MAX_OPT_LENGTH, ""); printf(" %-*s will be made every seconds. If\n", _MAX_OPT_LENGTH, ""); printf(" %-*s the value is 0 (the default), only one ping\n", _MAX_OPT_LENGTH, ""); printf(" %-*s will be executed. Use Ctrl + 'C' to abort a\n", _MAX_OPT_LENGTH, ""); printf(" %-*s continuous ping.\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s -p Don't show block upload progress. This\n", _MAX_OPT_LENGTH, _OPT_STRING_NO_SHOW_PROGRESS); printf(" %-*s option is especially useful when redirecting\n", _MAX_OPT_LENGTH, ""); printf(" %-*s the program output to a file. No argument.\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s -e Timeout in milliseconds for erasing one\n", _MAX_OPT_LENGTH, _OPT_STRING_PAGE_ERASE_TIME); printf(" %-*s flash page (usually 1 Kb). This value will\n", _MAX_OPT_LENGTH, ""); printf(" %-*s be multiplied with the number of pages to\n", _MAX_OPT_LENGTH, ""); printf(" %-*s be erased. This option is only used with\n", _MAX_OPT_LENGTH, ""); printf(" %-*s the --%s command. Defaults to %d ms.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_UPLOAD_IMG, CMD_OPT_DEFAULT_PAGE_ERASE_TIME); printf(" %-*s It's usually not necessary to increase this\n", _MAX_OPT_LENGTH, ""); printf(" %-*s value.\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s The address of the modbus slave, if there is\n", _MAX_OPT_LENGTH, _OPT_STRING_MODBUS_SLAVE_ID); printf(" %-*s a modbus application running on the target.\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s Address of the first of the modbus registers\n", _MAX_OPT_LENGTH, _OPT_STRING_MODBUS_CTRL_REG); printf(" %-*s that control the start of the bootloader.\n", _MAX_OPT_LENGTH, ""); printf(" %-*s Defaults to %d.\n", _MAX_OPT_LENGTH, "", CMD_OPT_DEFAULT_MODBUS_START_REGISTER); printf(" --%-*s -f Force modbus and mininet auto-bauding to\n", _MAX_OPT_LENGTH, _OPT_STRING_FORCE_ALL_PARITIES); printf(" %-*s scan for a connection at all possible\n", _MAX_OPT_LENGTH, ""); printf(" %-*s parities. This option has no argument.\n", _MAX_OPT_LENGTH, ""); printf(" --%-*s -v <0-4> Verbosity. 0 = quiet, 1 = error, 2 = info,\n", _MAX_OPT_LENGTH, _OPT_STRING_VERBOSITY); printf(" %-*s 3 = status, 4 = debug. Be careful using a\n", _MAX_OPT_LENGTH, ""); printf(" %-*s verbosity of 4 with commands that can cause\n", _MAX_OPT_LENGTH, ""); printf(" %-*s heavy data transfer like --%s!\n", _MAX_OPT_LENGTH, "", _OPT_STRING_UPLOAD_IMG); printf(" --%-*s -? Show this help\n", _MAX_OPT_LENGTH, _OPT_STRING_HELP); printf("\n"); }