cmdopt.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047
  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stdlib.h>
  5. #include <stdarg.h>
  6. #include <limits.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <unistd.h>
  10. #include <stddef.h>
  11. #include <time.h>
  12. #include <errno.h>
  13. #include <getopt.h>
  14. #include <gfa/gfaserial.h>
  15. #include <gfa/gfabootlmast.h>
  16. #include "main.h"
  17. #include "cmdopt.h"
  18. #include "error.h"
  19. #include "output.h"
  20. #include "modbmst.h"
  21. /////////////////////////////////////////////////////////////////////////////
  22. #define _IS_POWER_OF_2(x) (!!(x) && !((x) & ((x) - 1)))
  23. #define _IS_VALID_STATION_NUMBER(s) (((s) > 0) && ((s) <= 99))
  24. #define _IS_VALID_BLOCK_SIZE(s) (((s) >= GFA_BOOTLOADER_MIN_SEND_DATA_BLOCK_SIZE) && ((s) <= GFA_BOOTLOADER_MAX_SEND_DATA_BLOCK_SIZE) && !((s) & 0x03))
  25. /////////////////////////////////////////////////////////////////////////////
  26. #define _OV_HAS_UPLOAD_IMG ((uint32_t)0x00000001)
  27. #define _OV_HAS_SHOW_FILE_IMG_INFO ((uint32_t)0x00000002)
  28. #define _OV_HAS_SHOW_DEV_IMG_INFO ((uint32_t)0x00000004)
  29. #define _OV_HAS_VALIDATE_IMG ((uint32_t)0x00000008)
  30. #define _OV_HAS_SHOW_MAT_SER ((uint32_t)0x00000010)
  31. #define _OV_HAS_SET_MAT_SER ((uint32_t)0x00000020)
  32. #define _OV_HAS_BOOT_PING ((uint32_t)0x00000040)
  33. #define _OV_HAS_START_BOOT ((uint32_t)0x00000080)
  34. #define _OV_HAS_RESET_BOOT ((uint32_t)0x00000100)
  35. #define _OV_HAS_RESCUE_BOOT ((uint32_t)0x00000200)
  36. #define _OV_HAS_IMG_FILE ((uint32_t)0x00001000)
  37. #define _OV_HAS_ITF_NAME ((uint32_t)0x00002000)
  38. #define _OV_HAS_BLOCK_SIZE ((uint32_t)0x00004000)
  39. #define _OV_HAS_APP_ADDR ((uint32_t)0x00008000)
  40. #define _OV_HAS_X_BAUD_RATE ((uint32_t)0x00010000)
  41. #define _OV_HAS_STATION_NUMBER ((uint32_t)0x00020000)
  42. #define _OV_HAS_NODE_ADDR ((uint32_t)0x00040000)
  43. #define _OV_HAS_SLAVE_ADDR ((uint32_t)0x00080000)
  44. #define _OV_HAS_MATERIAL ((uint32_t)0x00100000)
  45. #define _OV_HAS_SERIAL ((uint32_t)0x00200000)
  46. #define _OV_HAS_PING_INTERVAL ((uint32_t)0x00400000)
  47. #define _OV_HAS_NO_SHOW_PROGRESS ((uint32_t)0x00800000)
  48. #define _OV_HAS_PAGE_ERASE_TIME ((uint32_t)0x01000000)
  49. #define _OV_HAS_MODBUS_SLAVE_ID ((uint32_t)0x02000000)
  50. #define _OV_HAS_MODBUS_CTRL_REG ((uint32_t)0x04000000)
  51. #define _OV_HAS_FORCE_ALL_PARITIES ((uint32_t)0x08000000)
  52. #define _OV_HAS_PLUGIN_MODE ((uint32_t)0x10000000)
  53. /////////////////////////////////////////////////////////////////////////////
  54. #define _OV_CMD_MASK ((uint32_t)0x00000FFF)
  55. #define _OV_OPT_MASK (~_OV_CMD_MASK)
  56. /////////////////////////////////////////////////////////////////////////////
  57. #define _REQ_CONNECTION_OPTS (_OV_HAS_ITF_NAME | _OV_HAS_SLAVE_ADDR)
  58. #define _REQ_OPTS_UPLOAD_IMG (_OV_HAS_IMG_FILE | _REQ_CONNECTION_OPTS)
  59. #define _REQ_OPTS_SHOW_IMG_INFO_OFFLINE _OV_HAS_IMG_FILE
  60. #define _REQ_OPTS_SHOW_IMG_INFO_ONLINE _REQ_CONNECTION_OPTS
  61. #define _REQ_OPTS_VALIDATE_IMG (_OV_HAS_IMG_FILE | _REQ_CONNECTION_OPTS)
  62. #define _REQ_OPTS_SHOW_MAT_SER _REQ_CONNECTION_OPTS
  63. #define _REQ_OPTS_SET_MAT_SER (_REQ_CONNECTION_OPTS | _OV_HAS_MATERIAL | _OV_HAS_SERIAL)
  64. #define _REQ_OPTS_BOOT_PING _REQ_CONNECTION_OPTS
  65. #define _REQ_OPTS_START_BOOT _REQ_CONNECTION_OPTS
  66. #define _REQ_OPTS_RESET_BOOT _REQ_CONNECTION_OPTS
  67. #define _REQ_OPTS_RESCUE_BOOT _REQ_CONNECTION_OPTS
  68. /////////////////////////////////////////////////////////////////////////////
  69. #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)
  70. #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)
  71. #define _OPT_OPTS_SHOW_IMG_INFO_OFFLINE (_OV_HAS_APP_ADDR | _OV_HAS_PLUGIN_MODE)
  72. #define _OPT_OPTS_SHOW_IMG_INFO_ONLINE (_OPT_CONNECTION_OPTS | _OV_HAS_X_BAUD_RATE | _OV_HAS_APP_ADDR | _OV_HAS_PLUGIN_MODE)
  73. #define _OPT_OPTS_VALIDATE_IMG (_OPT_CONNECTION_OPTS | _OV_HAS_APP_ADDR | _OV_HAS_PLUGIN_MODE)
  74. #define _OPT_OPTS_SHOW_MAT_SER (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE)
  75. #define _OPT_OPTS_SET_MAT_SER (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE)
  76. #define _OPT_OPTS_BOOT_PING (_OPT_CONNECTION_OPTS | _OV_HAS_PING_INTERVAL | _OV_HAS_PLUGIN_MODE)
  77. #define _OPT_OPTS_START_BOOT (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE)
  78. #define _OPT_OPTS_RESET_BOOT (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE)
  79. #define _OPT_OPTS_RESCUE_BOOT (_OPT_CONNECTION_OPTS | _OV_HAS_PLUGIN_MODE)
  80. /////////////////////////////////////////////////////////////////////////////
  81. #define _GET_OPTS(m) ((m) & _OV_OPT_MASK)
  82. #define _GET_CMD(m) ((m) & _OV_CMD_MASK)
  83. #define _HAS_CMD(m) (!!_GET_CMD(m))
  84. #define _HAS_VALID_CMD(m) (_HAS_CMD(m) && _IS_POWER_OF_2(_GET_CMD(m)))
  85. #define _IS_OFFLINE_CMD(m) (_GET_CMD(m) == _OV_HAS_SHOW_FILE_IMG_INFO)
  86. #define _HAS_REQUIRED_OPTIONS(m, r) ((_GET_OPTS(m) & (r)) == (r))
  87. #define _GET_MISSING_OPTS(m, r) ((_GET_OPTS(m) ^ (r)) & (r))
  88. #define _GET_UNUSED_OPTS(m, r, o) ((_GET_OPTS(m) ^ (r)) & ~(o))
  89. /////////////////////////////////////////////////////////////////////////////
  90. #define _OPT_STRING_UPLOAD_IMG "upload-img"
  91. #define _OPT_STRING_VALIDATE_IMG "validate-img"
  92. #define _OPT_STRING_SHOW_FILE_IMG_INFO "show-file-img-info"
  93. #define _OPT_STRING_SHOW_DEV_IMG_INFO "show-dev-img-info"
  94. #define _OPT_STRING_SHOW_MAT_SER "show-mat-ser"
  95. #define _OPT_STRING_SET_MAT_SER "set-mat-ser"
  96. #define _OPT_STRING_BOOT_PING "ping-target"
  97. #define _OPT_STRING_START_BOOT "start-boot"
  98. #define _OPT_STRING_RESET_BOOT "reset-boot"
  99. #define _OPT_STRING_RESCUE_BOOT "revive-boot"
  100. #define _OPT_STRING_ITF_NAME "itf-name"
  101. #define _OPT_STRING_X_BAUD_RATE "x-baud-rate"
  102. #define _OPT_STRING_STATION_NUMBER "stat-num"
  103. #define _OPT_STRING_NODE_ADDR "node-addr"
  104. #define _OPT_STRING_MATERIAL "material"
  105. #define _OPT_STRING_SERIAL "serial"
  106. #define _OPT_STRING_SLAVE_ADDR "stat-num or node-addr"
  107. #define _OPT_STRING_APP_BASE_ADDR "app-addr"
  108. #define _OPT_STRING_BLOCK_SIZE "block-size"
  109. #define _OPT_STRING_PING_INTERVAL "ping-int"
  110. #define _OPT_STRING_PAGE_ERASE_TIME "page-erase-time"
  111. #define _OPT_STRING_NO_SHOW_PROGRESS "no-progress"
  112. #define _OPT_STRING_MODBUS_SLAVE_ID "mb-slave-id"
  113. #define _OPT_STRING_MODBUS_CTRL_REG "mb-bl-ctrl-reg"
  114. #define _OPT_STRING_FORCE_ALL_PARITIES "force-all-par"
  115. #define _OPT_STRING_PLUGIN_MODE "plugin-mode"
  116. #define _OPT_STRING_VERBOSITY "verbosity"
  117. #define _OPT_STRING_HELP "help"
  118. #define _OPT_STRING_IMG_FILE "<IMG FILE>"
  119. #define _MAX_CMD_LENGTH 18
  120. #define _MAX_OPT_LENGTH 15
  121. /////////////////////////////////////////////////////////////////////////////
  122. int g_nVerbosity = CMD_OPT_DEFAULT_VERBOSITY;
  123. bool g_bPluginMode = false;
  124. /////////////////////////////////////////////////////////////////////////////
  125. static const uint8_t g_nodeTable[] =
  126. {
  127. // 1 - 99
  128. 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
  129. 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A,
  130. 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
  131. 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
  132. 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
  133. 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
  134. 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A,
  135. 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
  136. 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A,
  137. 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9
  138. };
  139. /////////////////////////////////////////////////////////////////////////////
  140. static const char* _GetOptName(uint32_t nOpt)
  141. {
  142. switch(nOpt)
  143. {
  144. case _OV_HAS_UPLOAD_IMG:
  145. return _OPT_STRING_UPLOAD_IMG;
  146. case _OV_HAS_VALIDATE_IMG:
  147. return _OPT_STRING_VALIDATE_IMG;
  148. case _OV_HAS_SHOW_FILE_IMG_INFO:
  149. return _OPT_STRING_SHOW_FILE_IMG_INFO;
  150. case _OV_HAS_SHOW_DEV_IMG_INFO:
  151. return _OPT_STRING_SHOW_DEV_IMG_INFO;
  152. case _OV_HAS_SHOW_MAT_SER:
  153. return _OPT_STRING_SHOW_MAT_SER;
  154. case _OV_HAS_BOOT_PING:
  155. return _OPT_STRING_BOOT_PING;
  156. case _OV_HAS_START_BOOT:
  157. return _OPT_STRING_START_BOOT;
  158. case _OV_HAS_RESET_BOOT:
  159. return _OPT_STRING_RESET_BOOT;
  160. case _OV_HAS_RESCUE_BOOT:
  161. return _OPT_STRING_RESCUE_BOOT;
  162. case _OV_HAS_PING_INTERVAL:
  163. return _OPT_STRING_PING_INTERVAL;
  164. case _OV_HAS_NO_SHOW_PROGRESS:
  165. return _OPT_STRING_NO_SHOW_PROGRESS;
  166. case _OV_HAS_ITF_NAME:
  167. return _OPT_STRING_ITF_NAME;
  168. case _OV_HAS_BLOCK_SIZE:
  169. return _OPT_STRING_BLOCK_SIZE;
  170. case _OV_HAS_APP_ADDR:
  171. return _OPT_STRING_APP_BASE_ADDR;
  172. case _OV_HAS_X_BAUD_RATE:
  173. return _OPT_STRING_X_BAUD_RATE;
  174. case _OV_HAS_PAGE_ERASE_TIME:
  175. return _OPT_STRING_PAGE_ERASE_TIME;
  176. case _OV_HAS_STATION_NUMBER:
  177. return _OPT_STRING_STATION_NUMBER;
  178. case _OV_HAS_NODE_ADDR:
  179. return _OPT_STRING_NODE_ADDR;
  180. case _OV_HAS_SLAVE_ADDR:
  181. return _OPT_STRING_SLAVE_ADDR;
  182. case _OV_HAS_MATERIAL:
  183. return _OPT_STRING_MATERIAL;
  184. case _OV_HAS_SERIAL:
  185. return _OPT_STRING_SERIAL;
  186. case _OV_HAS_SET_MAT_SER:
  187. return _OPT_STRING_SET_MAT_SER;
  188. case _OV_HAS_IMG_FILE:
  189. return _OPT_STRING_IMG_FILE;
  190. case _OV_HAS_MODBUS_SLAVE_ID:
  191. return _OPT_STRING_MODBUS_SLAVE_ID;
  192. case _OV_HAS_MODBUS_CTRL_REG:
  193. return _OPT_STRING_MODBUS_CTRL_REG;
  194. case _OV_HAS_FORCE_ALL_PARITIES:
  195. return _OPT_STRING_FORCE_ALL_PARITIES;
  196. case _OV_HAS_PLUGIN_MODE:
  197. return _OPT_STRING_PLUGIN_MODE;
  198. default:
  199. return NULL;
  200. }
  201. }
  202. static const char* _GetOptValue(uint32_t nOpt, LPCMD_LINE_ARGS pcla)
  203. {
  204. static char szValue[32];
  205. switch(nOpt)
  206. {
  207. case _OV_HAS_UPLOAD_IMG:
  208. return _OPT_STRING_UPLOAD_IMG;
  209. case _OV_HAS_VALIDATE_IMG:
  210. return _OPT_STRING_VALIDATE_IMG;
  211. case _OV_HAS_SHOW_FILE_IMG_INFO:
  212. return _OPT_STRING_SHOW_FILE_IMG_INFO;
  213. case _OV_HAS_SHOW_DEV_IMG_INFO:
  214. return _OPT_STRING_SHOW_DEV_IMG_INFO;
  215. case _OV_HAS_SHOW_MAT_SER:
  216. return _OPT_STRING_SHOW_MAT_SER;
  217. case _OV_HAS_BOOT_PING:
  218. return _OPT_STRING_BOOT_PING;
  219. case _OV_HAS_START_BOOT:
  220. return _OPT_STRING_START_BOOT;
  221. case _OV_HAS_RESET_BOOT:
  222. return _OPT_STRING_RESET_BOOT;
  223. case _OV_HAS_RESCUE_BOOT:
  224. return _OPT_STRING_RESCUE_BOOT;
  225. case _OV_HAS_PING_INTERVAL:
  226. snprintf(szValue, sizeof(szValue) - 1, "%d", pcla->nPingIntervalSec);
  227. break;
  228. case _OV_HAS_ITF_NAME:
  229. return pcla->pszDevName ? pcla->pszDevName : "empty";
  230. case _OV_HAS_BLOCK_SIZE:
  231. snprintf(szValue, sizeof(szValue) - 1, "%u", pcla->nBlockSize);
  232. break;
  233. case _OV_HAS_APP_ADDR:
  234. snprintf(szValue, sizeof(szValue) - 1, "0x%X", pcla->nStartAddr);
  235. break;
  236. case _OV_HAS_X_BAUD_RATE:
  237. snprintf(szValue, sizeof(szValue) - 1, "%u", pcla->nExBaudrate);
  238. break;
  239. case _OV_HAS_PAGE_ERASE_TIME:
  240. snprintf(szValue, sizeof(szValue) - 1, "%u", pcla->nPageErsaeTime);
  241. break;
  242. case _OV_HAS_STATION_NUMBER:
  243. snprintf(szValue, sizeof(szValue) - 1, "%hhu", pcla->nStationNr);
  244. break;
  245. case _OV_HAS_NODE_ADDR:
  246. snprintf(szValue, sizeof(szValue) - 1, "0x%02hhX", pcla->nNodeAddr);
  247. break;
  248. case _OV_HAS_SLAVE_ADDR:
  249. return _OPT_STRING_SLAVE_ADDR;
  250. case _OV_HAS_MATERIAL:
  251. return pcla->pszMaterial ? pcla->pszMaterial : "empty";
  252. case _OV_HAS_SERIAL:
  253. return pcla->pszSerial ? pcla->pszSerial : "empty";
  254. case _OV_HAS_IMG_FILE:
  255. return pcla->pszImgFile ? pcla->pszImgFile : "empty";
  256. case _OV_HAS_NO_SHOW_PROGRESS:
  257. return pcla->bNoProgressBlock ? "true" : "false";
  258. case _OV_HAS_MODBUS_SLAVE_ID:
  259. snprintf(szValue, sizeof(szValue) - 1, "%hhu", pcla->nModbusSlvID);
  260. break;
  261. case _OV_HAS_MODBUS_CTRL_REG:
  262. snprintf(szValue, sizeof(szValue) - 1, "%hu", pcla->nModbusCtrlReg);
  263. break;
  264. case _OV_HAS_FORCE_ALL_PARITIES:
  265. return "true";
  266. case _OV_HAS_PLUGIN_MODE:
  267. return "true";
  268. default:
  269. return "empty";
  270. }
  271. szValue[31] = '\0';
  272. return szValue;
  273. }
  274. /////////////////////////////////////////////////////////////////////////////
  275. const char* GfaTfuCmdOpt2String(uint32_t nOpts)
  276. {
  277. static char szOptStr[600];
  278. if(nOpts)
  279. {
  280. int nCount = 0;
  281. uint32_t nMask = 1;
  282. memset(szOptStr, '\0', sizeof(szOptStr));
  283. while(nMask)
  284. {
  285. if(nOpts & nMask)
  286. {
  287. const char *pszOptName = _GetOptName(nMask);
  288. if(pszOptName)
  289. {
  290. if(nCount++)
  291. strcat(szOptStr, ", ");
  292. strcat(szOptStr, pszOptName);
  293. }
  294. }
  295. nMask <<= 1;
  296. }
  297. return szOptStr;
  298. }
  299. return "";
  300. }
  301. /////////////////////////////////////////////////////////////////////////////
  302. static const struct option g_lo[] =
  303. {
  304. {
  305. _OPT_STRING_UPLOAD_IMG,
  306. no_argument,
  307. NULL,
  308. ov_upload_img
  309. },
  310. {
  311. _OPT_STRING_VALIDATE_IMG,
  312. no_argument,
  313. NULL,
  314. ov_validate_img
  315. },
  316. {
  317. _OPT_STRING_SHOW_FILE_IMG_INFO,
  318. no_argument,
  319. NULL,
  320. ov_show_file_img_info
  321. },
  322. {
  323. _OPT_STRING_SHOW_DEV_IMG_INFO,
  324. no_argument,
  325. NULL,
  326. ov_show_dev_img_info
  327. },
  328. {
  329. _OPT_STRING_SHOW_MAT_SER,
  330. no_argument,
  331. NULL,
  332. ov_show_mat_ser
  333. },
  334. {
  335. _OPT_STRING_SET_MAT_SER,
  336. no_argument,
  337. NULL,
  338. ov_set_mat_ser
  339. },
  340. {
  341. _OPT_STRING_MATERIAL,
  342. required_argument,
  343. NULL,
  344. ov_material
  345. },
  346. {
  347. _OPT_STRING_SERIAL,
  348. required_argument,
  349. NULL,
  350. ov_serial
  351. },
  352. {
  353. _OPT_STRING_NO_SHOW_PROGRESS,
  354. no_argument,
  355. NULL,
  356. ov_no_progress
  357. },
  358. {
  359. _OPT_STRING_BOOT_PING,
  360. no_argument,
  361. NULL,
  362. ov_boot_ping
  363. },
  364. {
  365. _OPT_STRING_START_BOOT,
  366. no_argument,
  367. NULL,
  368. ov_start_boot
  369. },
  370. {
  371. _OPT_STRING_RESET_BOOT,
  372. no_argument,
  373. NULL,
  374. ov_reset_boot
  375. },
  376. {
  377. _OPT_STRING_RESCUE_BOOT,
  378. no_argument,
  379. NULL,
  380. ov_rescue_boot
  381. },
  382. {
  383. _OPT_STRING_PING_INTERVAL,
  384. required_argument,
  385. NULL,
  386. ov_ping_interval
  387. },
  388. {
  389. _OPT_STRING_ITF_NAME,
  390. required_argument,
  391. NULL,
  392. ov_itf_name
  393. },
  394. {
  395. _OPT_STRING_X_BAUD_RATE,
  396. required_argument,
  397. NULL,
  398. ov_x_baud_rate
  399. },
  400. {
  401. _OPT_STRING_STATION_NUMBER,
  402. required_argument,
  403. NULL,
  404. ov_station_number
  405. },
  406. {
  407. _OPT_STRING_NODE_ADDR,
  408. required_argument,
  409. NULL,
  410. ov_node_addr
  411. },
  412. {
  413. _OPT_STRING_PAGE_ERASE_TIME,
  414. required_argument,
  415. NULL,
  416. ov_page_erase_time
  417. },
  418. {
  419. _OPT_STRING_APP_BASE_ADDR,
  420. required_argument,
  421. NULL,
  422. ov_app_addr
  423. },
  424. {
  425. _OPT_STRING_BLOCK_SIZE,
  426. required_argument,
  427. NULL,
  428. ov_block_size
  429. },
  430. {
  431. _OPT_STRING_MODBUS_SLAVE_ID,
  432. required_argument,
  433. NULL,
  434. ov_mb_slave_id
  435. },
  436. {
  437. _OPT_STRING_MODBUS_CTRL_REG,
  438. required_argument,
  439. NULL,
  440. ov_mb_ctrl_reg
  441. },
  442. {
  443. _OPT_STRING_FORCE_ALL_PARITIES,
  444. no_argument,
  445. NULL,
  446. ov_force_all_par
  447. },
  448. {
  449. _OPT_STRING_PLUGIN_MODE,
  450. no_argument,
  451. NULL,
  452. ov_plugin_mode
  453. },
  454. {
  455. _OPT_STRING_VERBOSITY,
  456. required_argument,
  457. NULL,
  458. ov_verbosity
  459. },
  460. {
  461. _OPT_STRING_HELP,
  462. no_argument,
  463. NULL,
  464. ov_help
  465. },
  466. {
  467. NULL,
  468. 0,
  469. NULL,
  470. 0
  471. }
  472. };
  473. /////////////////////////////////////////////////////////////////////////////
  474. static int64_t _ArgStr2Num(const char *pszNum, int64_t nDefault)
  475. {
  476. if(pszNum && *pszNum)
  477. {
  478. char *pszEnd = NULL;
  479. int64_t n = strtoll(pszNum, &pszEnd, 0);
  480. if((((n == LLONG_MIN) || (n == LLONG_MAX)) && (errno == ERANGE)) || *pszEnd)
  481. return nDefault;
  482. return n;
  483. }
  484. return nDefault;
  485. }
  486. /////////////////////////////////////////////////////////////////////////////
  487. /////////////////////////////////////////////////////////////////////////////
  488. /////////////////////////////////////////////////////////////////////////////
  489. void GfaTfuCmdOptInitOpts(LPCMD_LINE_ARGS pcla)
  490. {
  491. memset(pcla, 0, sizeof(CMD_LINE_ARGS));
  492. pcla->nBootBaudrate = CMD_OPT_DEFAULT_BAUDRATE;
  493. pcla->nInitBaudrate = CMD_OPT_DEFAULT_BAUDRATE;
  494. pcla->nModbBaudrate = CMD_OPT_DEFAULT_BAUDRATE;
  495. pcla->modbParity = CMD_OPT_DEFAULT_MODBUS_PARITY;
  496. pcla->nBlockSize = GFA_BOOTLOADER_DEF_SEND_DATA_BLOCK_SIZE;
  497. pcla->nStartAddr = CMD_OPT_DEFAULT_APP_BASE_ADDRESS;
  498. pcla->nPageErsaeTime = CMD_OPT_DEFAULT_PAGE_ERASE_TIME;
  499. pcla->nVerbosity = CMD_OPT_DEFAULT_VERBOSITY;
  500. pcla->nModbusCtrlReg = CMD_OPT_DEFAULT_MODBUS_START_REGISTER;
  501. }
  502. /////////////////////////////////////////////////////////////////////////////
  503. int GfaTfuCmdOptParse(int argc, char* argv[], LPCMD_LINE_ARGS pcla)
  504. {
  505. int opt, nCount = 0;
  506. pcla->nOptFlags = 0;
  507. while((opt = getopt_long(argc, argv, "-a:b:d:e:fgi:m:n:ps:t:v:x:?", g_lo, NULL)) != -1)
  508. {
  509. const char *arg = optarg;
  510. switch(opt)
  511. {
  512. case ov_img_file:
  513. if(arg)
  514. {
  515. const char *pszFileBase = strrchr(arg, '/');
  516. pcla->pszImgFile = arg;
  517. if(pszFileBase)
  518. pcla->pszImgFileBase = ++pszFileBase;
  519. pcla->nOptFlags |= _OV_HAS_IMG_FILE;
  520. }
  521. break;
  522. case ov_itf_name:
  523. if(arg)
  524. {
  525. pcla->pszDevName = arg;
  526. pcla->nOptFlags |= _OV_HAS_ITF_NAME;
  527. }
  528. break;
  529. case ov_show_dev_img_info:
  530. pcla->bShowDevImgInfo = true;
  531. pcla->nOptFlags |= _OV_HAS_SHOW_DEV_IMG_INFO;
  532. break;
  533. case ov_show_file_img_info:
  534. pcla->bShowFileImgInfo = true;
  535. pcla->nOptFlags |= _OV_HAS_SHOW_FILE_IMG_INFO;
  536. break;
  537. case ov_show_mat_ser:
  538. pcla->bShowMatSer = true;
  539. pcla->nOptFlags |= _OV_HAS_SHOW_MAT_SER;
  540. break;
  541. case ov_set_mat_ser:
  542. pcla->bSetMatSer = true;
  543. pcla->nOptFlags |= _OV_HAS_SET_MAT_SER;
  544. break;
  545. case ov_validate_img:
  546. pcla->bValidateImg = true;
  547. pcla->nOptFlags |= _OV_HAS_VALIDATE_IMG;
  548. break;
  549. case ov_upload_img:
  550. pcla->bUploadImg = true;
  551. pcla->nOptFlags |= _OV_HAS_UPLOAD_IMG;
  552. break;
  553. case ov_boot_ping:
  554. pcla->bPing = true;
  555. pcla->nOptFlags |= _OV_HAS_BOOT_PING;
  556. break;
  557. case ov_start_boot:
  558. pcla->bStartBoot = true;
  559. pcla->nOptFlags |= _OV_HAS_START_BOOT;
  560. break;
  561. case ov_reset_boot:
  562. pcla->bResetBoot = true;
  563. pcla->nOptFlags |= _OV_HAS_RESET_BOOT;
  564. break;
  565. case ov_rescue_boot:
  566. pcla->bReviveBoot = true;
  567. pcla->nOptFlags |= _OV_HAS_RESCUE_BOOT;
  568. break;
  569. case ov_ping_interval:
  570. pcla->nPingIntervalSec = (int32_t)_ArgStr2Num(arg, 0);
  571. if(pcla->nPingIntervalSec > 0)
  572. pcla->nOptFlags |= _OV_HAS_PING_INTERVAL;
  573. break;
  574. case ov_material:
  575. if(arg && *arg)
  576. {
  577. pcla->pszMaterial = arg;
  578. pcla->nOptFlags |= _OV_HAS_MATERIAL;
  579. }
  580. break;
  581. case ov_serial:
  582. if(arg && *arg)
  583. {
  584. pcla->pszSerial = arg;
  585. pcla->nOptFlags |= _OV_HAS_SERIAL;
  586. }
  587. break;
  588. case ov_no_progress:
  589. pcla->bNoProgressBlock = true;
  590. pcla->nOptFlags |= _OV_HAS_NO_SHOW_PROGRESS;
  591. break;
  592. case ov_block_size:
  593. pcla->nBlockSize = (uint32_t)_ArgStr2Num(arg, GFA_BOOTLOADER_DEF_SEND_DATA_BLOCK_SIZE);
  594. pcla->nOptFlags |= _OV_HAS_BLOCK_SIZE;
  595. break;
  596. case ov_app_addr:
  597. pcla->nStartAddr = (uint32_t)_ArgStr2Num(arg, CMD_OPT_DEFAULT_APP_BASE_ADDRESS);
  598. pcla->nOptFlags |= _OV_HAS_APP_ADDR;
  599. break;
  600. case ov_x_baud_rate:
  601. pcla->nExBaudrate = (uint32_t)_ArgStr2Num(arg, 0);
  602. pcla->nOptFlags |= _OV_HAS_X_BAUD_RATE;
  603. break;
  604. case ov_page_erase_time:
  605. pcla->nPageErsaeTime = (uint32_t)_ArgStr2Num(arg, CMD_OPT_DEFAULT_PAGE_ERASE_TIME);
  606. pcla->nOptFlags |= _OV_HAS_PAGE_ERASE_TIME;
  607. break;
  608. case ov_station_number:
  609. pcla->nStationNr = (uint8_t)_ArgStr2Num(arg, 0);
  610. pcla->nOptFlags |= _OV_HAS_STATION_NUMBER;
  611. pcla->nOptFlags |= _OV_HAS_SLAVE_ADDR;
  612. break;
  613. case ov_node_addr:
  614. pcla->nNodeAddr = (uint8_t)_ArgStr2Num(arg, 0);
  615. pcla->nOptFlags |= _OV_HAS_NODE_ADDR;
  616. pcla->nOptFlags |= _OV_HAS_SLAVE_ADDR;
  617. break;
  618. case ov_mb_slave_id:
  619. pcla->nModbusSlvID = (uint8_t)_ArgStr2Num(arg, 0xFF);
  620. pcla->nOptFlags |= _OV_HAS_MODBUS_SLAVE_ID;
  621. break;
  622. case ov_mb_ctrl_reg:
  623. pcla->nModbusCtrlReg = (uint16_t)_ArgStr2Num(arg, CMD_OPT_DEFAULT_MODBUS_START_REGISTER);
  624. pcla->nOptFlags |= _OV_HAS_MODBUS_CTRL_REG;
  625. break;
  626. case ov_force_all_par:
  627. pcla->bForceAllParities = true;
  628. pcla->nOptFlags |= _OV_HAS_FORCE_ALL_PARITIES;
  629. break;
  630. case ov_plugin_mode:
  631. pcla->bPluginMode = true;
  632. pcla->nOptFlags |= _OV_HAS_PLUGIN_MODE;
  633. break;
  634. case ov_verbosity:
  635. pcla->nVerbosity = (int)_ArgStr2Num(arg, CMD_OPT_DEFAULT_VERBOSITY);
  636. break;
  637. case ov_help:
  638. ++pcla->nQuestionMarks;
  639. pcla->bShowHelp = true;
  640. break;
  641. }
  642. ++nCount;
  643. }
  644. if(nCount == 0)
  645. pcla->bShowHelp = true;
  646. return nCount;
  647. }
  648. /////////////////////////////////////////////////////////////////////////////
  649. int GfaTfuCmdOptProcess(LPCMD_LINE_ARGS pcla)
  650. {
  651. /////////////////////////////////////////////////////////////////////////
  652. // If help is requested, do nothing else
  653. if(pcla->bShowHelp)
  654. return 1;
  655. /////////////////////////////////////////////////////////////////////////
  656. // adjust verbosity
  657. if(pcla->nVerbosity < CMD_OPT_MIN_VERBOSITY)
  658. pcla->nVerbosity = CMD_OPT_MIN_VERBOSITY;
  659. else if(pcla->nVerbosity > CMD_OPT_MAX_VERBOSITY)
  660. pcla->nVerbosity = CMD_OPT_MAX_VERBOSITY;
  661. g_nVerbosity = pcla->nVerbosity;
  662. /////////////////////////////////////////////////////////////////////////
  663. // if we are in plugin-mode we produce formatted output only
  664. if(pcla->bPluginMode)
  665. {
  666. g_nVerbosity = pcla->nVerbosity = -1;
  667. g_bPluginMode = true;
  668. }
  669. /////////////////////////////////////////////////////////////////////////
  670. // validate commands
  671. pcla->nCmdFlags = _GET_CMD(pcla->nOptFlags);
  672. if(!_HAS_CMD(pcla->nOptFlags))
  673. {
  674. if(!(pcla->nOptFlags & (_OV_HAS_MATERIAL | _OV_HAS_SERIAL)))
  675. return GFA_FU_ERROR_NOTHING_TO_DO;
  676. }
  677. else if(!_HAS_VALID_CMD(pcla->nOptFlags))
  678. return GFA_FU_ERROR_MULTIPLE_COMMANDS;
  679. /////////////////////////////////////////////////////////////////////////
  680. // validate connection options if required
  681. if(!_IS_OFFLINE_CMD(pcla->nOptFlags))
  682. {
  683. if(!pcla->nExBaudrate)
  684. pcla->nExBaudrate = pcla->nInitBaudrate;
  685. if(!GfaSerialIsValidBaudrate(pcla->nExBaudrate))
  686. return GFA_FU_ERROR_INVALID_BAUDRATE;
  687. else if((pcla->nOptFlags & (_OV_HAS_STATION_NUMBER | _OV_HAS_NODE_ADDR)) == (_OV_HAS_STATION_NUMBER | _OV_HAS_NODE_ADDR))
  688. return GFA_FU_ERROR_NODE_STATION_MUTEX;
  689. else if(pcla->nOptFlags & _OV_HAS_STATION_NUMBER)
  690. {
  691. if(!_IS_VALID_STATION_NUMBER(pcla->nStationNr))
  692. return GFA_FU_ERROR_INVALID_STATION_NUM;
  693. pcla->nNodeAddr = g_nodeTable[pcla->nStationNr - 1];
  694. }
  695. else if((pcla->nOptFlags & _OV_HAS_NODE_ADDR) && (NODE_IS_MULTICAST(pcla->nNodeAddr) || (pcla->nNodeAddr < MINET_MIN_NODE_ADDRESS)))
  696. return GFA_FU_ERROR_INVALID_NODE_ADDR;
  697. }
  698. /////////////////////////////////////////////////////////////////////////
  699. // validate command options
  700. switch(pcla->nCmdFlags)
  701. {
  702. case _OV_HAS_UPLOAD_IMG:
  703. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_UPLOAD_IMG))
  704. {
  705. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_UPLOAD_IMG);
  706. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  707. }
  708. else if((pcla->nOptFlags & _OV_HAS_BLOCK_SIZE) && !_IS_VALID_BLOCK_SIZE(pcla->nBlockSize))
  709. return GFA_FU_ERROR_INVALID_BLOCK_SIZE;
  710. else if(pcla->nStartAddr == (uint32_t)-1)
  711. return GFA_FU_ERROR_INVALID_APP_START_ADDR;
  712. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_UPLOAD_IMG, _OPT_OPTS_UPLOAD_IMG);
  713. pcla->bNeedImgFile = true;
  714. break;
  715. case _OV_HAS_SHOW_FILE_IMG_INFO:
  716. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_OFFLINE))
  717. {
  718. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_OFFLINE);
  719. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  720. }
  721. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_OFFLINE, _OPT_OPTS_SHOW_IMG_INFO_OFFLINE);
  722. pcla->bNeedImgFile = true;
  723. break;
  724. case _OV_HAS_SHOW_DEV_IMG_INFO:
  725. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_ONLINE))
  726. {
  727. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_ONLINE);
  728. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  729. }
  730. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_IMG_INFO_ONLINE, _OPT_OPTS_SHOW_IMG_INFO_ONLINE);
  731. break;
  732. case _OV_HAS_VALIDATE_IMG:
  733. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_VALIDATE_IMG))
  734. {
  735. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_VALIDATE_IMG);
  736. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  737. }
  738. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_VALIDATE_IMG, _OPT_OPTS_VALIDATE_IMG);
  739. pcla->bNeedImgFile = true;
  740. break;
  741. case _OV_HAS_SHOW_MAT_SER:
  742. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SHOW_MAT_SER))
  743. {
  744. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_MAT_SER);
  745. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  746. }
  747. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SHOW_MAT_SER, _OPT_OPTS_SHOW_MAT_SER);
  748. break;
  749. case _OV_HAS_SET_MAT_SER:
  750. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_SET_MAT_SER))
  751. {
  752. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_SET_MAT_SER);
  753. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  754. }
  755. if( (strlen(pcla->pszMaterial) >= GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH) ||
  756. (strlen(pcla->pszSerial) >= GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH))
  757. {
  758. return GFA_FU_ERROR_MAT_OR_SER_TOO_LONG;
  759. }
  760. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_SET_MAT_SER, _OPT_OPTS_SET_MAT_SER);
  761. break;
  762. case _OV_HAS_BOOT_PING:
  763. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_BOOT_PING))
  764. {
  765. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_BOOT_PING);
  766. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  767. }
  768. else if(pcla->nPingIntervalSec < 0)
  769. return GFA_FU_ERROR_INVALID_COMMAND_OPT;
  770. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_BOOT_PING, _OPT_OPTS_BOOT_PING);
  771. break;
  772. case _OV_HAS_START_BOOT:
  773. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_START_BOOT))
  774. {
  775. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_START_BOOT);
  776. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  777. }
  778. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_START_BOOT, _OPT_OPTS_START_BOOT);
  779. break;
  780. case _OV_HAS_RESET_BOOT:
  781. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_RESET_BOOT))
  782. {
  783. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_RESET_BOOT);
  784. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  785. }
  786. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_RESET_BOOT, _OPT_OPTS_RESET_BOOT);
  787. break;
  788. case _OV_HAS_RESCUE_BOOT:
  789. if(!_HAS_REQUIRED_OPTIONS(pcla->nOptFlags, _REQ_OPTS_RESCUE_BOOT))
  790. {
  791. pcla->nMissingOptFlags = _GET_MISSING_OPTS(pcla->nOptFlags, _REQ_OPTS_RESCUE_BOOT);
  792. return GFA_FU_ERROR_MISSING_COMMAND_OPT;
  793. }
  794. pcla->nUnusedOptFlags = _GET_UNUSED_OPTS(pcla->nOptFlags, _REQ_OPTS_RESCUE_BOOT, _OPT_OPTS_RESCUE_BOOT);
  795. break;
  796. default:
  797. return 1;
  798. }
  799. /////////////////////////////////////////////////////////////////////////
  800. // validate optional options
  801. if(pcla->nOptFlags & _OV_HAS_MODBUS_SLAVE_ID)
  802. {
  803. if(!MODBUS_IS_VALID_SLAVE_ID(pcla->nModbusSlvID))
  804. {
  805. return GFA_FU_ERROR_INVALID_MODBUS_SLV_ID;
  806. }
  807. }
  808. return 0;
  809. }
  810. void GfaTfuCmdOptDumpOptions(LPCMD_LINE_ARGS pcla)
  811. {
  812. if(pcla)
  813. {
  814. uint32_t nMask, nOpts = 0;
  815. TRACE3("****************************\n");
  816. TRACE3("COMMAND: %s\n", _GetOptName(pcla->nCmdFlags));
  817. TRACE3("OPTIONS:\n");
  818. switch(pcla->nCmdFlags)
  819. {
  820. case _OV_HAS_UPLOAD_IMG:
  821. nOpts = pcla->nOptFlags & (_REQ_OPTS_UPLOAD_IMG | _OPT_OPTS_UPLOAD_IMG) & ~_OV_HAS_SLAVE_ADDR;
  822. break;
  823. case _OV_HAS_SHOW_FILE_IMG_INFO:
  824. nOpts = pcla->nOptFlags & (_REQ_OPTS_SHOW_IMG_INFO_OFFLINE | _OPT_OPTS_SHOW_IMG_INFO_OFFLINE) & ~_OV_HAS_SLAVE_ADDR;
  825. break;
  826. case _OV_HAS_SHOW_DEV_IMG_INFO:
  827. nOpts = pcla->nOptFlags & (_REQ_OPTS_SHOW_IMG_INFO_ONLINE | _OPT_OPTS_SHOW_IMG_INFO_ONLINE) & ~_OV_HAS_SLAVE_ADDR;
  828. break;
  829. case _OV_HAS_VALIDATE_IMG:
  830. nOpts = pcla->nOptFlags & (_REQ_OPTS_VALIDATE_IMG | _OPT_OPTS_VALIDATE_IMG) & ~_OV_HAS_SLAVE_ADDR;
  831. break;
  832. case _OV_HAS_SHOW_MAT_SER:
  833. nOpts = pcla->nOptFlags & (_REQ_OPTS_SHOW_MAT_SER | _OPT_OPTS_SHOW_MAT_SER) & ~_OV_HAS_SLAVE_ADDR;
  834. break;
  835. case _OV_HAS_SET_MAT_SER:
  836. nOpts = pcla->nOptFlags & (_REQ_OPTS_SET_MAT_SER | _OPT_OPTS_SET_MAT_SER) & ~_OV_HAS_SLAVE_ADDR;
  837. break;
  838. case _OV_HAS_BOOT_PING:
  839. nOpts = pcla->nOptFlags & (_REQ_OPTS_BOOT_PING | _OPT_OPTS_BOOT_PING) & ~_OV_HAS_SLAVE_ADDR;
  840. break;
  841. case _OV_HAS_START_BOOT:
  842. nOpts = pcla->nOptFlags & (_REQ_OPTS_START_BOOT | _OPT_OPTS_START_BOOT) & ~_OV_HAS_SLAVE_ADDR;
  843. break;
  844. case _OV_HAS_RESET_BOOT:
  845. nOpts = pcla->nOptFlags & (_REQ_OPTS_RESET_BOOT | _OPT_OPTS_RESET_BOOT) & ~_OV_HAS_SLAVE_ADDR;
  846. break;
  847. case _OV_HAS_RESCUE_BOOT:
  848. nOpts = pcla->nOptFlags & (_REQ_OPTS_RESCUE_BOOT | _OPT_OPTS_RESCUE_BOOT) & ~_OV_HAS_SLAVE_ADDR;
  849. break;
  850. default:
  851. return;
  852. }
  853. for(nMask = 1; nMask; nMask <<= 1)
  854. {
  855. if(nOpts & nMask)
  856. {
  857. TRACE3(" %-*s: %s\n", _MAX_OPT_LENGTH, _GetOptName(nMask), _GetOptValue(nMask, pcla));
  858. }
  859. }
  860. if(pcla->nUnusedOptFlags)
  861. TRACE3(" %-*s: %s\n", _MAX_OPT_LENGTH, "IGNORED", GfaTfuCmdOpt2String(pcla->nUnusedOptFlags));
  862. TRACE3("****************************\n\n");
  863. }
  864. }
  865. /////////////////////////////////////////////////////////////////////////////
  866. // Examples:
  867. //
  868. // ./gfativaflashutil --upload-img --itf-name="/dev/ttyO4" -x-baud-rate 230400 -t1 "/opt/GfA/gfativaflashutil/OLS-1V1_0009_crc_9600Baud.bin" -v3 -p -b72
  869. // ./gfativaflashutil --validate-img --itf-name="/dev/ttyO4" --app-addr=0x2000 --node-addr=0x11 "/opt/GfA/gfativaflashutil/OLS-1V1_0009_crc.bin" -v3
  870. // ./gfativaflashutil --show-mat-ser --itf-name="/dev/ttyO4" --stat-num=1 --mb-slave-id 100 -v3
  871. // ./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"
  872. // ./gfativaflashutil --show-file-img-info "/opt/GfA/gfativaflashutil/OLS-1V1_0009_crc.bin" -a0x2000 -v3
  873. // ./gfativaflashutil --show-dev-img-info --itf-name="/dev/ttyO4" --x-baud-rate=115200 --node-addr=0x11 -v3
  874. // ./gfativaflashutil --ping-target --ping-int=1 --itf-name="/dev/ttyO4" --node-addr=0x11 -v3
  875. // ./gfativaflashutil --start-boot --itf-name="/dev/ttyO4" --node-addr=0x11 -v3
  876. // ./gfativaflashutil --reset-boot --itf-name="/dev/ttyO4" --node-addr=0x11 -v3
  877. // ./gfativaflashutil --mb-start-boot --itf-name="/dev/ttyO4" --mb-slave-id 100 -v3
  878. //
  879. //
  880. void GfaTfuCmdOptDisplayHelp(bool bGfaUser)
  881. {
  882. printf("\n╔═══════════════════════════════════════════════════════╗\n");
  883. printf("║ gfativaflashutil v%d.%d GfA GmbH (%s %s) ║\n", GFA_FU_VER_MAJOR, GFA_FU_VER_MINOR, __DATE__, __TIME__);
  884. printf("╚═══════════════════════════════════════════════════════╝\n\n");
  885. printf(" USAGE: gfativaflashutil COMMAND [OPTIONS] [IMG FILE]\n\n");
  886. printf(" COMMANDS (only one command per execution is permitted):\n");
  887. printf(" --%-*s Upload <IMG FILE> to the device.\n", _MAX_CMD_LENGTH, _OPT_STRING_UPLOAD_IMG);
  888. printf(" --%-*s Validate <IMG FILE> with the device. (Attempts to\n", _MAX_CMD_LENGTH, _OPT_STRING_VALIDATE_IMG);
  889. printf(" %-*s match the material numbers as well).\n", _MAX_CMD_LENGTH, "");
  890. printf(" --%-*s Validate <IMG FILE> offline and display image\n", _MAX_CMD_LENGTH, _OPT_STRING_SHOW_FILE_IMG_INFO);
  891. printf(" %-*s information.\n", _MAX_CMD_LENGTH, "");
  892. printf(" --%-*s Display bootloader and (if available) application\n", _MAX_CMD_LENGTH, _OPT_STRING_SHOW_DEV_IMG_INFO);
  893. printf(" %-*s image information of the target device.\n", _MAX_CMD_LENGTH, "");
  894. printf(" --%-*s Display the material and serial number of the\n", _MAX_CMD_LENGTH, _OPT_STRING_SHOW_MAT_SER);
  895. printf(" %-*s target device.\n", _MAX_CMD_LENGTH, "");
  896. if(bGfaUser)
  897. {
  898. printf(" --%-*s Set the material and serial number of the\n", _MAX_CMD_LENGTH, _OPT_STRING_SET_MAT_SER);
  899. printf(" %-*s target device.\n", _MAX_CMD_LENGTH, "");
  900. }
  901. printf(" --%-*s Ping the target device either once or continuously\n", _MAX_CMD_LENGTH, _OPT_STRING_BOOT_PING);
  902. printf(" %-*s dependig on the parameter --%s.\n", _MAX_CMD_LENGTH, "", _OPT_STRING_PING_INTERVAL);
  903. printf(" --%-*s Start the bootloader if an application is running.\n", _MAX_CMD_LENGTH, _OPT_STRING_START_BOOT);
  904. printf(" --%-*s Reset the bootloader if no application is running.\n", _MAX_CMD_LENGTH, _OPT_STRING_RESET_BOOT);
  905. printf(" %-*s If there is a valid application image in flash, it\n", _MAX_CMD_LENGTH, "");
  906. printf(" %-*s will be subsequently started.\n", _MAX_CMD_LENGTH, "");
  907. printf(" --%-*s Try to re-establish communication with the bootloader\n", _MAX_CMD_LENGTH, _OPT_STRING_RESCUE_BOOT);
  908. printf(" %-*s if it's in a non-responsive state. This may arise\n", _MAX_CMD_LENGTH, "");
  909. printf(" %-*s after a failed image upload due to an interrupted\n", _MAX_CMD_LENGTH, "");
  910. printf(" %-*s communication line or any transmission failures. It\n", _MAX_CMD_LENGTH, "");
  911. printf(" %-*s seems, that a verbosity of 4 in combination with high\n", _MAX_CMD_LENGTH, "");
  912. printf(" %-*s baud rates can also cause this problem.\n", _MAX_CMD_LENGTH, "");
  913. printf("\n");
  914. printf(" OPTIONS:\n");
  915. printf(" --%-*s -d <INTERFACE> The name of the communication interface.\n", _MAX_OPT_LENGTH, _OPT_STRING_ITF_NAME);
  916. printf(" --%-*s -t <STATION> Station number. Will be mapped internally\n", _MAX_OPT_LENGTH, _OPT_STRING_STATION_NUMBER);
  917. printf(" %-*s to a node address. Must not be used in\n", _MAX_OPT_LENGTH, "");
  918. printf(" %-*s combination with --%s.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_NODE_ADDR);
  919. printf(" --%-*s -n <NODE> The target's node address. Must not be used\n", _MAX_OPT_LENGTH, _OPT_STRING_NODE_ADDR);
  920. printf(" %-*s in combination with --%s.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_STATION_NUMBER);
  921. printf(" --%-*s -x <BAUDRATE> Extended baud-rate to use for some (but not\n", _MAX_OPT_LENGTH, _OPT_STRING_X_BAUD_RATE);
  922. printf(" %-*s all) commands. Because a baud-rate switch\n", _MAX_OPT_LENGTH, "");
  923. printf(" %-*s involves data transfer as well, it will\n", _MAX_OPT_LENGTH, "");
  924. printf(" %-*s only be used with commands that require a\n", _MAX_OPT_LENGTH, "");
  925. printf(" %-*s great amount of data to be transferred!\n", _MAX_OPT_LENGTH, "");
  926. printf(" --%-*s -a <BASE ADDR> Flash address where to load <IMG FILE>.\n", _MAX_OPT_LENGTH, _OPT_STRING_APP_BASE_ADDR);
  927. printf(" %-*s Defaults to 0x%X.\n", _MAX_OPT_LENGTH, "", CMD_OPT_DEFAULT_APP_BASE_ADDRESS);
  928. if(bGfaUser)
  929. {
  930. printf(" --%-*s -m <MATERIAL> The material number to be set with the\n", _MAX_OPT_LENGTH, _OPT_STRING_MATERIAL);
  931. printf(" %-*s --%s command.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_SET_MAT_SER);
  932. printf(" --%-*s -s <SERIAL> The serial number to be set with the\n", _MAX_OPT_LENGTH, _OPT_STRING_SERIAL);
  933. printf(" %-*s --%s command.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_SET_MAT_SER);
  934. }
  935. printf(" --%-*s -b <BLOCKSIZE> Size of an upload-block in bytes. (4-76,\n", _MAX_OPT_LENGTH, _OPT_STRING_BLOCK_SIZE);
  936. printf(" %-*s must be a multiple of 4!). This option is\n", _MAX_OPT_LENGTH, "");
  937. printf(" %-*s only used with the --%s command.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_UPLOAD_IMG);
  938. printf(" %-*s Defaults to %d. There is usually no need\n", _MAX_OPT_LENGTH, "", GFA_BOOTLOADER_DEF_SEND_DATA_BLOCK_SIZE);
  939. printf(" %-*s to alter this value.\n", _MAX_OPT_LENGTH, "");
  940. printf(" --%-*s -i <SECONDS> The optional ping interval in seconds. If a\n", _MAX_OPT_LENGTH, _OPT_STRING_PING_INTERVAL);
  941. printf(" %-*s value greater than 0 is provided, a ping\n", _MAX_OPT_LENGTH, "");
  942. printf(" %-*s will be made every <SECONDS> seconds. If\n", _MAX_OPT_LENGTH, "");
  943. printf(" %-*s the value is 0 (the default), only one ping\n", _MAX_OPT_LENGTH, "");
  944. printf(" %-*s will be executed. Use Ctrl + 'C' to abort a\n", _MAX_OPT_LENGTH, "");
  945. printf(" %-*s continuous ping.\n", _MAX_OPT_LENGTH, "");
  946. printf(" --%-*s -p Don't show block upload progress. This\n", _MAX_OPT_LENGTH, _OPT_STRING_NO_SHOW_PROGRESS);
  947. printf(" %-*s option is especially useful when redirecting\n", _MAX_OPT_LENGTH, "");
  948. printf(" %-*s the program output to a file. No argument.\n", _MAX_OPT_LENGTH, "");
  949. printf(" --%-*s -e <MILLISEC> Timeout in milliseconds for erasing one\n", _MAX_OPT_LENGTH, _OPT_STRING_PAGE_ERASE_TIME);
  950. printf(" %-*s flash page (usually 1 Kb). This value will\n", _MAX_OPT_LENGTH, "");
  951. printf(" %-*s be multiplied with the number of pages to\n", _MAX_OPT_LENGTH, "");
  952. printf(" %-*s be erased. This option is only used with\n", _MAX_OPT_LENGTH, "");
  953. printf(" %-*s the --%s command. Defaults to %d ms.\n", _MAX_OPT_LENGTH, "", _OPT_STRING_UPLOAD_IMG, CMD_OPT_DEFAULT_PAGE_ERASE_TIME);
  954. printf(" %-*s It's usually not necessary to increase this\n", _MAX_OPT_LENGTH, "");
  955. printf(" %-*s value.\n", _MAX_OPT_LENGTH, "");
  956. printf(" --%-*s <SLAVEID> The address of the modbus slave, if there is\n", _MAX_OPT_LENGTH, _OPT_STRING_MODBUS_SLAVE_ID);
  957. printf(" %-*s a modbus application running on the target.\n", _MAX_OPT_LENGTH, "");
  958. printf(" --%-*s <REGISTER> Address of the first of the modbus registers\n", _MAX_OPT_LENGTH, _OPT_STRING_MODBUS_CTRL_REG);
  959. printf(" %-*s that control the start of the bootloader.\n", _MAX_OPT_LENGTH, "");
  960. printf(" %-*s Defaults to %d.\n", _MAX_OPT_LENGTH, "", CMD_OPT_DEFAULT_MODBUS_START_REGISTER);
  961. printf(" --%-*s -f Force modbus and mininet auto-bauding to\n", _MAX_OPT_LENGTH, _OPT_STRING_FORCE_ALL_PARITIES);
  962. printf(" %-*s scan for a connection at all possible\n", _MAX_OPT_LENGTH, "");
  963. printf(" %-*s parities. This option has no argument.\n", _MAX_OPT_LENGTH, "");
  964. printf(" --%-*s -v <0-4> Verbosity. 0 = quiet, 1 = error, 2 = info,\n", _MAX_OPT_LENGTH, _OPT_STRING_VERBOSITY);
  965. printf(" %-*s 3 = status, 4 = debug. Be careful using a\n", _MAX_OPT_LENGTH, "");
  966. printf(" %-*s verbosity of 4 with commands that can cause\n", _MAX_OPT_LENGTH, "");
  967. printf(" %-*s heavy data transfer like --%s!\n", _MAX_OPT_LENGTH, "", _OPT_STRING_UPLOAD_IMG);
  968. printf(" --%-*s -? Show this help\n", _MAX_OPT_LENGTH, _OPT_STRING_HELP);
  969. printf("\n");
  970. }