cmdopt.c 40 KB

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