cmdopt.c 37 KB

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