1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252 |
- #include <stdio.h>
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <limits.h>
- #include <string.h>
- #include <ctype.h>
- #include <unistd.h>
- #include <stddef.h>
- #include <signal.h>
- #include <time.h>
- #include <errno.h>
- #include <getopt.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <gfaserial.h>
- #include <gfabootlmast.h>
- #include "main.h"
- #include "cmdopt.h"
- #include "image.h"
- #include "output.h"
- #include "modbmst.h"
- #include "error.h"
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- #define _ABBR_BOOTLOADER "Boot"
- #define _ABBR_APPLICATION "Appl"
- #define _ABBR_MININET "MiNe"
- #define _ABBR_MODBUS "ModB"
- /////////////////////////////////////////////////////////////////////////////
- static bool g_bSig = false;
- /////////////////////////////////////////////////////////////////////////////
- static void _SigHandler(int sig)
- {
- g_bSig = !!sig;
- TRACE3("\n");
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _ShowDevImgInfo(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- GFA_BL_APP_IMG_INFO aii;
- UNUSED(hIf);
- TRACE3("Getting image information.\n");
- TTRACE3("Getting image information");
- if((ctx == GfaBlmCtx_App) && ((nRet = GfaBlmGetInfoBI(hBlm, pcla->nNodeAddr, &aii)) == 0))
- {
- GfaTfuDumpImageInfo("Bootloader", &aii.bl);
- GfaTfuDumpImageInfo("Application", &aii.app);
- if( (aii.bl.nImgLength != 0xFFFFFFFF) &&
- (aii.bl.nImgCRC32 != 0xFFFFFFFF) &&
- (*aii.bl.szImgMaterialNum != 0xFF) &&
- (*aii.bl.szImgNameBuild != 0xFF))
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_BOOT, "%u", aii.bl.nImgLength);
- TTRACE(PLUGIN_TAG_IMG_CRC32_BOOT, "%u", aii.bl.nImgCRC32);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_BOOT, "%s", aii.bl.szImgMaterialNum);
- TTRACE(PLUGIN_TAG_IMG_BUILD_BOOT, "%s", aii.bl.szImgNameBuild);
- }
- else
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_BOOT, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_CRC32_BOOT, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_BOOT, "%s", "n/a");
- TTRACE(PLUGIN_TAG_IMG_BUILD_BOOT, "%s", "n/a");
- }
- if( (aii.app.nImgLength != 0xFFFFFFFF) &&
- (aii.app.nImgCRC32 != 0xFFFFFFFF) &&
- (*aii.app.szImgMaterialNum != 0xFF) &&
- (*aii.app.szImgNameBuild != 0xFF))
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_APP, "%u", aii.app.nImgLength);
- TTRACE(PLUGIN_TAG_IMG_CRC32_APP, "%u", aii.app.nImgCRC32);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_APP, "%s", aii.app.szImgMaterialNum);
- TTRACE(PLUGIN_TAG_IMG_BUILD_APP, "%s", aii.app.szImgNameBuild);
- }
- else
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_APP, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_CRC32_APP, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_APP, "%s", "n/a");
- TTRACE(PLUGIN_TAG_IMG_BUILD_APP, "%s", "n/a");
- }
- }
- else
- {
- bool bStartApp = false;
- if(ctx == GfaBlmCtx_App)
- {
- TRACE3("Application doesn't recognize BI command!\n");
- TRACE3("Starting bootloader.\n");
- TTRACE3("Application doesn't recognize BI command");
- TTRACE3("Starting bootloader");
- if((nRet = GfaBlmBootloaderExecute(hBlm, pcla->nNodeAddr, NULL, 1000)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- bStartApp = true;
- }
- if(pcla->nExBaudrate != pcla->nInitBaudrate)
- {
- TRACE3("Setting baud-rate to %u.\n", pcla->nExBaudrate);
- TTRACE3("Setting baud-rate to %u", pcla->nExBaudrate);
- if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, pcla->nNodeAddr, pcla->nExBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- if((nRet = GfaBlmGetInfoBD(hBlm, pcla->nNodeAddr, pcla->nStartAddr, &aii)) > -2)
- {
- GfaTfuDumpImageInfo("Bootloader", &aii.bl);
- GfaTfuDumpImageInfo("Application", &aii.app);
- if( (aii.bl.nImgLength != 0xFFFFFFFF) &&
- (aii.bl.nImgCRC32 != 0xFFFFFFFF) &&
- (*aii.bl.szImgMaterialNum != 0xFF) &&
- (*aii.bl.szImgNameBuild != 0xFF))
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_BOOT, "%u", aii.bl.nImgLength);
- TTRACE(PLUGIN_TAG_IMG_CRC32_BOOT, "%u", aii.bl.nImgCRC32);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_BOOT, "%s", aii.bl.szImgMaterialNum);
- TTRACE(PLUGIN_TAG_IMG_BUILD_BOOT, "%s", aii.bl.szImgNameBuild);
- }
- else
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_BOOT, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_CRC32_BOOT, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_BOOT, "%s", "n/a");
- TTRACE(PLUGIN_TAG_IMG_BUILD_BOOT, "%s", "n/a");
- }
- if( (aii.app.nImgLength != 0xFFFFFFFF) &&
- (aii.app.nImgCRC32 != 0xFFFFFFFF) &&
- (*aii.app.szImgMaterialNum != 0xFF) &&
- (*aii.app.szImgNameBuild != 0xFF))
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_APP, "%u", aii.app.nImgLength);
- TTRACE(PLUGIN_TAG_IMG_CRC32_APP, "%u", aii.app.nImgCRC32);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_APP, "%s", aii.app.szImgMaterialNum);
- TTRACE(PLUGIN_TAG_IMG_BUILD_APP, "%s", aii.app.szImgNameBuild);
- }
- else
- {
- TTRACE(PLUGIN_TAG_IMG_LENGTH_APP, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_CRC32_APP, "%u", 0);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_APP, "%s", "n/a");
- TTRACE(PLUGIN_TAG_IMG_BUILD_APP, "%s", "n/a");
- }
- }
- else
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- if(pcla->nExBaudrate != pcla->nInitBaudrate)
- {
- TRACE3("Setting baud-rate to %u.\n", pcla->nInitBaudrate);
- TTRACE3("Setting baud-rate to %u", pcla->nInitBaudrate);
- if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, pcla->nNodeAddr, pcla->nInitBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- if(bStartApp)
- {
- TRACE3("Starting application.\n");
- TTRACE3("Starting application");
- if((nRet = GfaBlmBUCmdReset(hBlm, pcla->nNodeAddr, pcla->nInitBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _ValidateImg(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- GFA_IMG_INFO ii;
- char szMaterial[16], szSerial[16];
- UNUSED(ctx);
- TRACE3("Reading material number.\n");
- TTRACE3("Reading material number");
- if((nRet = GfaBlmReadMaterialAndSerialID(hBlm, pcla->nNodeAddr, szMaterial, sizeof(szMaterial), szSerial, sizeof(szSerial))) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- if(szMaterial[0] == '\xFF')
- strcpy(szMaterial, "n/a");
- if(szSerial[0] == '\xFF')
- strcpy(szSerial, "n/a");
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_EEPROM, szMaterial);
- TTRACE(PLUGIN_TAG_IMG_SERIAL_EEPROM, szSerial);
- GfaTfuImageFileGetInfo(hIf, &ii);
- TRACE2("Material number target: \"%s\"\n", szMaterial);
- TRACE2("Material number file: \"%s\"\n", ii.szImgMaterialNum);
- TTRACE2("Material number target: \"%s\"", szMaterial);
- TTRACE2("Material number file: \"%s\"", ii.szImgMaterialNum);
- if(!GfaTfuImageFileMatchMaterialNum(hIf, szMaterial))
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return -1;
- }
- TRACE2("\"%s\" - Image is valid for target @ node 0x%02hhX!\n", pcla->pszImgFileBase, pcla->nNodeAddr);
- TTRACE2("\"%s\" - Image is valid for target @ node 0x%02hhX", pcla->pszImgFileBase, pcla->nNodeAddr);
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _ShowMatSer(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- char szMaterial[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH], szSerial[GFA_APP_MAX_IMG_SERIAL_NUM_LENGTH];
- UNUSED(hIf);
- UNUSED(ctx);
- TRACE3("Reading material and serial number.\n");
- TTRACE3("Reading material and serial number");
- if((nRet = GfaBlmReadMaterialAndSerialID(hBlm, pcla->nNodeAddr, szMaterial, sizeof(szMaterial), szSerial, sizeof(szSerial))) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- if(szMaterial[0] == '\xFF')
- strcpy(szMaterial, "n/a");
- if(szSerial[0] == '\xFF')
- strcpy(szSerial, "n/a");
- TRACE2("Material and Serial number:\n");
- TRACE2(" Material: \"%s\"\n", szMaterial);
- TRACE2(" Serial: \"%s\"\n", szSerial);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_EEPROM, szMaterial);
- TTRACE(PLUGIN_TAG_IMG_SERIAL_EEPROM, szSerial);
- return nRet;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _SetMatSer(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- bool bStartApp = false;
- if(ctx == GfaBlmCtx_App)
- {
- TRACE3("Starting bootloader.\n");
- if((nRet = GfaBlmBootloaderExecute(hBlm, pcla->nNodeAddr, NULL, 1000)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- bStartApp = true;
- }
- TRACE3("Setting material and serial number.\n");
- TRACE2(" Mat.Nr.: \"%s\"\n", pcla->pszMaterial);
- TRACE2(" Serial: \"%s\"\n", pcla->pszSerial);
- if((nRet = GfaBlmWriteMaterialAndSerialID(hBlm, pcla->nNodeAddr, pcla->pszMaterial, pcla->pszSerial)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- TRACE2("Material and serial number successfully set!\n");
- if(bStartApp)
- {
- TRACE3("Starting application.\n");
- if((nRet = GfaBlmBUCmdReset(hBlm, pcla->nNodeAddr, pcla->nInitBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- return _ShowMatSer(hIf, hBlm, pcla, ctx);
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _Ping(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- time_t t;
- char szTime[64];
- struct timespec tsStart, tsEnd, ts = {0, 0};
- int64_t nIntervalBoot = 0, nIntervalMini = 0, nIntervalModB = 0;
- HGFAMINEMST hMst = GfaBlmGetMininetMasterHandle(hBlm);
- HMINETDEV hDev = GfaMininetMasterGetDeviceHandle(hMst);
- HGFAMBMST hMbm = NULL;
- GFA_SER_CFG_PARAMS scp, scpSave;
- UNUSED(hIf);
- if(ctx == GfaBlmCtx_ModB)
- {
- if(!(hMbm = GfaMbMstOpen(hMst, pcla->nModbBaudrate, pcla->modbParity, pcla->nModbusCtrlReg)))
- return -1;
- GfaMbMstSetVerbosity(hMbm, pcla->nVerbosity);
- if(GfaMininetDeviceGetConfigParams(hDev, &scp, sizeof(scp)) != sizeof(scp))
- {
- GfaMbMstClose(hMbm);
- return -1;
- }
- memcpy(&scpSave, &scp, sizeof(scpSave));
- scp.parity = pcla->modbParity;
- scp.baud = pcla->nModbBaudrate;
- if(GfaMininetDeviceSetConfigParams(hDev, &scp, sizeof(scp)) != 0)
- {
- GfaMbMstClose(hMbm);
- return -1;
- }
- }
- do
- {
- t = time(NULL);
- strftime(szTime, sizeof(szTime), "%T", localtime(&t));
- GfaTfuGetClock(&tsStart);
- if(ctx == GfaBlmCtx_ModB)
- {
- if((nRet = GfaMbMstPing(hMbm, pcla->nModbusSlvID)) == 0)
- {
- GfaTfuGetClock(&tsEnd);
- nIntervalModB = GfaTfuClockDiff(&tsEnd, &tsStart);
- TRACE2("Slave 0x%02hhX [%s] ping success [%.1f ms] - %s.\n", pcla->nModbusSlvID, _ABBR_MODBUS, (double)nIntervalModB / 1000000.0, szTime);
- TTRACE2("Slave 0x%02hhX [%s] ping success [%.1f ms] - %s", pcla->nModbusSlvID, _ABBR_MODBUS, (double)nIntervalModB / 1000000.0, szTime);
- }
- else
- {
- TRACE1("Slave 0x%02hhX [%s] ping error: %s - %s.\n", pcla->nModbusSlvID, _ABBR_MODBUS, GfaTfuStrError(errno), szTime);
- TTRACE1("Slave 0x%02hhX [%s] ping error: %s - %s", pcla->nModbusSlvID, _ABBR_MODBUS, GfaTfuStrError(errno), szTime);
- }
- }
- else if((nRet = GfaBlmMininetPing(hBlm, pcla->nNodeAddr)) == 0)
- {
- GfaTfuGetClock(&tsEnd);
- nIntervalMini = GfaTfuClockDiff(&tsEnd, &tsStart);
- GfaTfuGetClock(&tsStart);
- if((nRet = GfaBlmBUCmdPing(hBlm, pcla->nNodeAddr)) != 0)
- {
- if( (ctx == GfaBlmCtx_Boot) ||
- (errno != -MINET_SLAVE_STATUS_INDEX_INVALID_PARAM))
- {
- if(errno == -MINET_SLAVE_STATUS_INDEX_ERROR)
- {
- if((nRet = GfaBlmResetSlaveIndex(hBlm, pcla->nNodeAddr)) != 0)
- {
- TRACE1("Node 0x%02hhX [%s] ping error: %s - %s.\n", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, GfaTfuStrError(errno), szTime);
- TTRACE1("Node 0x%02hhX [%s] ping error: %s - %s", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, GfaTfuStrError(errno), szTime);
- break;
- }
- if((ctx = GfaBlmGetExecutionContext(hBlm, pcla->nNodeAddr)) == GfaBlmCtx_Err)
- {
- TRACE1("Node 0x%02hhX ping error: %s - %s.\n", pcla->nNodeAddr, GfaTfuStrError(errno), szTime);
- TTRACE1("Node 0x%02hhX ping error: %s - %s", pcla->nNodeAddr, GfaTfuStrError(errno), szTime);
- break;
- }
- continue;
- }
- }
- else
- {
- nRet = 0;
- }
- }
- if(nRet == 0)
- {
- GfaTfuGetClock(&tsEnd);
- nIntervalBoot = GfaTfuClockDiff(&tsEnd, &tsStart);
- TRACE2("Node 0x%02hhX [%s] ping success [%.1f ms] - %s.\n", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, (double)nIntervalBoot / 1000000.0, szTime);
- TTRACE2("Node 0x%02hhX [%s] ping success [%.1f ms] - %s", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, (double)nIntervalBoot / 1000000.0, szTime);
- }
- else
- {
- TRACE2("Node 0x%02hhX [%s] ping success [%.1f ms] - %s.\n", pcla->nNodeAddr, _ABBR_MININET, (double)nIntervalMini / 1000000.0, szTime);
- TTRACE2("Node 0x%02hhX [%s] ping success [%.1f ms] - %s", pcla->nNodeAddr, _ABBR_MININET, (double)nIntervalMini / 1000000.0, szTime);
- TRACE1("Node 0x%02hhX [%s] ping error: %s - %s.\n", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, GfaTfuStrError(errno), szTime);
- TTRACE1("Node 0x%02hhX [%s] ping error: %s - %s", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, GfaTfuStrError(errno), szTime);
- }
- }
- else
- {
- if(errno == -MINET_SLAVE_STATUS_INDEX_ERROR)
- {
- if((nRet = GfaBlmResetSlaveIndex(hBlm, pcla->nNodeAddr)) != 0)
- {
- TRACE1("Node 0x%02hhX [%s] ping error: %s - %s.\n", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, GfaTfuStrError(errno), szTime);
- TTRACE1("Node 0x%02hhX [%s] ping error: %s - %s", pcla->nNodeAddr, (ctx == GfaBlmCtx_Boot) ? _ABBR_BOOTLOADER : _ABBR_APPLICATION, GfaTfuStrError(errno), szTime);
- break;
- }
- continue;
- }
- TRACE1("Node 0x%02hhX [%s] ping error: %s - %s.\n", pcla->nNodeAddr, _ABBR_MININET, GfaTfuStrError(errno), szTime);
- TTRACE1("Node 0x%02hhX [%s] ping error: %s - %s", pcla->nNodeAddr, _ABBR_MININET, GfaTfuStrError(errno), szTime);
- }
- if(pcla->nPingIntervalSec > 0)
- {
- ts.tv_sec = pcla->nPingIntervalSec;
- if(nanosleep(&ts, NULL) < 0)
- break;
- }
- }
- while(pcla->nPingIntervalSec && !g_bSig);
- if(hMbm)
- {
- GfaMbMstClose(hMbm);
- if(GfaMininetDeviceSetConfigParams(hDev, &scpSave, sizeof(scpSave)) != 0)
- return -1;
- }
- return nRet;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _UploadImg(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- uint32_t nCntFlashPages;
- size_t nImgLength;
- const void *pImgData;
- if((nRet = _ValidateImg(hIf, hBlm, pcla, ctx)) == 0)
- {
- if(ctx == GfaBlmCtx_App)
- {
- TRACE3("Starting bootloader.\n");
- TTRACE3("Starting bootloader");
- if((nRet = GfaBlmBootloaderExecute(hBlm, pcla->nNodeAddr, NULL, 1000)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- if(pcla->nExBaudrate != pcla->nBootBaudrate)
- {
- TRACE3("Setting baud-rate to %u.\n", pcla->nExBaudrate);
- TTRACE3("Setting baud-rate to %u", pcla->nExBaudrate);
- if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, pcla->nNodeAddr, pcla->nExBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- pImgData = GfaTfuImageFileGetData(hIf);
- nImgLength = GfaTfuImageFileGetSize(hIf);
- nCntFlashPages = (nImgLength + GFA_BOOTLOADER_FLASH_PAGE_SIZE - 1) / GFA_BOOTLOADER_FLASH_PAGE_SIZE;
- if((nRet = GfaBlmBUCmdDownload(hBlm, pcla->nNodeAddr, pcla->nStartAddr, nImgLength, nCntFlashPages * pcla->nPageErsaeTime)) == 0)
- {
- if((nRet = GfaBlmBUCmdSendData(hBlm, pcla->nNodeAddr, pImgData, nImgLength, pcla->nBlockSize)) != 0)
- {
- if(pcla->nExBaudrate != pcla->nBootBaudrate)
- {
- TRACE3("Trying to reset baud-rate to %u.\n", pcla->nBootBaudrate);
- TTRACE3("Trying to reset baud-rate to %u", pcla->nBootBaudrate);
- if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, pcla->nNodeAddr, pcla->nBootBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- }
- }
- return -1;
- }
- }
- else
- {
- if(pcla->nExBaudrate != pcla->nBootBaudrate)
- {
- TRACE3("Trying to reset baud-rate to %u.\n", pcla->nBootBaudrate);
- TTRACE3("Trying to reset baud-rate to %u", pcla->nBootBaudrate);
- if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, pcla->nNodeAddr, pcla->nBootBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- }
- }
- return -1;
- }
- TRACE3("Starting application.\n");
- TTRACE3("Starting application");
- if((nRet = GfaBlmBUCmdReset(hBlm, pcla->nNodeAddr, pcla->nInitBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- }
- return nRet;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _ResetBootloader(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- UNUSED(hIf);
- if(ctx == GfaBlmCtx_App)
- {
- TRACE2("Application already executing!\n");
- TTRACE2("Application already executing");
- return 0; // no error
- }
- TRACE3("Resetting bootloader.\n");
- TTRACE3("Resetting bootloader");
- if((nRet = GfaBlmBUCmdReset(hBlm, pcla->nNodeAddr, pcla->nInitBaudrate)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _ReviveBootloader(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx, bool bImplicitCall)
- {
- int nLen, nRet = 0, nCnt = 0;
- uint8_t nStatus;
- struct timespec ts = {0, 250000000};
- UNUSED(hIf);
- if(ctx == GfaBlmCtx_App)
- {
- TRACE1("Bootloader not executing!\n");
- TTRACE1("Bootloader not executing");
- return 0;
- }
- uint8_t data[128], frm[256], rx[256], cmd[256];
- size_t nCbData = sizeof(data);
- HGFAMINEMST hMst = GfaBlmGetMininetMasterHandle(hBlm);
- memset(data, 0, sizeof(data));
- if(!bImplicitCall)
- {
- TRACE2("Reviving bootloader.\n");
- TTRACE2("Reviving bootloader");
- }
- while(!g_bSig)
- {
- nLen = GfaBlmBuildCmdDataPacket("BU", 0, data, nCbData, cmd, sizeof(cmd), false);
- nLen = GfaMininetMasterBuildFrame(hMst, pcla->nNodeAddr, 0, cmd, nLen, frm, sizeof(frm));
- if((nRet = GfaMininetMasterTransmitFrame(hMst, frm, nLen)) != nLen)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return -1;
- }
- if((nRet = GfaMininetMasterReceiveFrame(hMst, rx, sizeof(rx), true)) <= 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return -1;
- }
- nRet = GfaMininetMasterEvaluateSlaveResponse(hMst, pcla->nNodeAddr, rx, nRet, true, &nStatus);
- if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(-nStatus));
- TTRACE1(GfaTfuStrError(-nStatus));
- return -1;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
- {
- nCbData = 0;
- }
- else if(nRet == MINET_SLAVE_RESPONSE_ACK)
- {
- nCbData = sizeof(data);
- ++nCnt;
- }
- if(nCnt >= 3)
- return 0;
- if(nanosleep(&ts, NULL) < 0)
- break;
- }
- return nRet;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _ModbusStartBootloader(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- HGFAMINEMST hMst = GfaBlmGetMininetMasterHandle(hBlm);
- UNUSED(hIf);
- UNUSED(ctx);
- TRACE3("Starting bootloader.\n");
- TTRACE3("Starting bootloader");
- if(hMst)
- {
- HGFAMBMST hMbm = GfaMbMstOpen(hMst, pcla->nModbBaudrate, pcla->modbParity, pcla->nModbusCtrlReg);
- if(hMbm)
- {
- int nRet;
- GfaMbMstSetVerbosity(hMbm, pcla->nVerbosity);
- if((nRet = GfaMbMstBootloaderExecute(hMbm, pcla->nModbusSlvID)) == 0)
- {
- if(pcla->nNodeAddr)
- GfaMininetMasterResetLocalIndex(hMst, pcla->nNodeAddr);
- }
- else
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- }
- GfaMbMstClose(hMbm);
- return nRet;
- }
- }
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return -1;
- }
- /////////////////////////////////////////////////////////////////////////////
- static int _StartBootloader(HIMGFILE hIf, HGFABLM hBlm, LPCCMD_LINE_ARGS pcla, GFA_BLM_EXEC_CONTEXT ctx)
- {
- int nRet;
- if(ctx == GfaBlmCtx_Boot)
- {
- TRACE2("Bootloader already executing!\n");
- TTRACE2("Bootloader already executing");
- return 0; // no error
- }
- else if(ctx == GfaBlmCtx_ModB)
- {
- return _ModbusStartBootloader(hIf, hBlm, pcla, ctx);
- }
- TRACE3("Starting bootloader.\n");
- TTRACE3("Starting bootloader");
- if((nRet = GfaBlmBootloaderExecute(hBlm, pcla->nNodeAddr, NULL, 1000)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- return nRet;
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- static bool _AutoBaud(HGFABLM hBlm, LPCMD_LINE_ARGS pcla)
- {
- const uint32_t nBaudrates[] = {19200, 9600, 38400, 57600, 115200, 230400, 4800, 460800/*, 921600, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400*/};
- const uint8_t nParities[] = {'N', 'E', 'O'};
- size_t nCntParities = pcla->bForceAllParities ? _countof(nParities) : 1;
- HGFAMINEMST hMst = GfaBlmGetMininetMasterHandle(hBlm);
- HMINETDEV hDev = GfaMininetMasterGetDeviceHandle(hMst);
- if(hDev)
- {
- int nRet;
- size_t i, j;
- bool bBaudrateHit = false;
- struct timeval tvRX = {0, 100000};
- GFA_SER_CFG_PARAMS scp, scpSave;
- if(GfaMininetDeviceGetConfigParams(hDev, &scp, sizeof(scp)) != sizeof(scp))
- return false;
- memcpy(&scpSave, &scp, sizeof(scpSave));
- GfaMininetMasterSaveTimeouts(hMst);
- GfaMininetMasterSetTimeouts(hMst, &tvRX, NULL);
- for(i = 0; i < nCntParities; ++i)
- {
- scp.parity = nParities[i];
- for(j = 0; j < _countof(nBaudrates); ++j)
- {
- scp.baud = nBaudrates[j];
- TRACE4("MiniNet - Try to connect @ %u,8,1,%c\n", scp.baud, scp.parity);
- if(GfaMininetDeviceSetConfigParams(hDev, &scp, sizeof(scp)) != 0)
- {
- nRet = -1;
- break;
- }
- if((nRet = GfaBlmResetSlaveIndex(hBlm, pcla->nNodeAddr)) == 0)
- {
- pcla->nInitBaudrate = nBaudrates[j];
- if(!pcla->nExBaudrate)
- pcla->nExBaudrate = pcla->nInitBaudrate;
- bBaudrateHit = true;
- TRACE3("Detected MiniNet connection @ %u,8,1,%c\n", scp.baud, scp.parity);
- TTRACE3("Detected MiniNet connection @ %u,8,1,%c", scp.baud, scp.parity);
- break;
- }
- usleep(10000);
- }
- if(bBaudrateHit)
- break;
- }
- GfaMininetMasterRestoreTimeouts(hMst);
- if(nRet)
- {
- GfaMininetDeviceSetConfigParams(hDev, &scpSave, sizeof(scpSave));
- return false;
- }
- return true;
- }
- return false;
- }
- /////////////////////////////////////////////////////////////////////////////
- static bool _ModbusAutobaud(HGFABLM hBlm, LPCMD_LINE_ARGS pcla)
- {
- const uint32_t nBaudrates[] = {19200, 9600, 38400, 57600, 115200, 230400, 4800, 460800/*, 921600, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400*/};
- const uint8_t nParities[] = {'E', 'O', 'N'};
- size_t nCntParities = pcla->bForceAllParities ? _countof(nParities) : 2;
- uint32_t i, j;
- HGFAMINEMST hMst = GfaBlmGetMininetMasterHandle(hBlm);
- HMINETDEV hDev = GfaMininetMasterGetDeviceHandle(hMst);
- if(hDev)
- {
- HGFAMBMST hMbm;
- GFA_SER_CFG_PARAMS scp, scpSave;
- if(GfaMininetDeviceGetConfigParams(hDev, &scp, sizeof(scp)) != sizeof(scp))
- return false;
- memcpy(&scpSave, &scp, sizeof(scpSave));
- hMbm = GfaMbMstOpen(hMst, pcla->nModbBaudrate, pcla->modbParity, pcla->nModbusCtrlReg);
- if(hMbm)
- {
- int nRet;
- bool bBaudrateHit = false;
- struct timeval tvRX = {0, 200000};
- GfaMbMstSetVerbosity(hMbm, pcla->nVerbosity);
- GfaMininetMasterSaveTimeouts(hMst);
- GfaMininetMasterSetTimeouts(hMst, &tvRX, NULL);
- for(i = 0; i < nCntParities; ++i)
- {
- scp.parity = nParities[i];
- for(j = 0; j < _countof(nBaudrates); ++j)
- {
- scp.baud = nBaudrates[j];
- TRACE4("Modbus - Try to connect @ %u,8,1,%c\n", scp.baud, scp.parity);
- if(GfaMininetDeviceSetConfigParams(hDev, &scp, sizeof(scp)) != 0)
- {
- nRet = -1;
- break;
- }
- if((nRet = GfaMbMstPing(hMbm, pcla->nModbusSlvID)) == 0)
- {
- pcla->modbParity = nParities[i];
- pcla->nModbBaudrate = nBaudrates[j];
- TRACE3("Detected Modbus application @ %u,8,1,%c\n", pcla->nModbBaudrate, pcla->modbParity);
- TTRACE3("Detected Modbus application @ %u,8,1,%c", pcla->nModbBaudrate, pcla->modbParity);
- bBaudrateHit = true;
- GfaMbMstWaitFrameDelay(hMbm);
- break;
- }
- GfaMbMstWaitFrameDelay(hMbm);
- }
- if(bBaudrateHit)
- break;
- }
- GfaMininetMasterRestoreTimeouts(hMst);
- GfaMbMstClose(hMbm);
- if(GfaMininetDeviceSetConfigParams(hDev, &scpSave, sizeof(scpSave)) != 0)
- return false;
- return (nRet == 0);
- }
- }
- return false;
- }
- /////////////////////////////////////////////////////////////////////////////
- static void _OnUploadProgress(const char *pszFile, int nLine, LPGFA_BLM_DL_PROGRESS_PARAMS pdlpp)
- {
- if(pdlpp)
- {
- static struct timespec tsStart, tsEnd;
- static uint32_t nBlockNr;
- static int nOldPerc;
- LPCCMD_LINE_ARGS pcla = (LPCCMD_LINE_ARGS)pdlpp->pParam;
- int64_t nInterval = 0;
- char szPercString[8];
- int nPerc;
- switch(pdlpp->nCtx)
- {
- case GBDPS_Error:
- UNUSED(pszFile);
- UNUSED(nLine);
- TRACE1("Error: %s!\n", GfaBlmStrError(pdlpp->nErrorCode));
- TTRACE1(GfaBlmStrError(pdlpp->nErrorCode));
- TTRACE(PLUGIN_TAG_UPLOAD_ERROR, "%d", pdlpp->nErrorCode);
- break;
- case GBDPS_StartEraseFlash:
- TRACE2("Start download of %u bytes to node 0x%02hhX @ address 0x%X.\n", pdlpp->nCbTotal, pdlpp->nNodeAddr, pdlpp->nFlashStartAddr);
- TRACE2("Erasing %u flash pages.\n", pdlpp->nCntFlashPages);
- TTRACE2("Start download of %u bytes to node 0x%02hhX @ address 0x%X", pdlpp->nCbTotal, pdlpp->nNodeAddr, pdlpp->nFlashStartAddr);
- TTRACE2("Erasing %u flash pages", pdlpp->nCntFlashPages);
- TTRACE(PLUGIN_TAG_UPLOAD_START_ERASE_FLASH, "%u|%u", pdlpp->nCntFlashPages, pdlpp->nCbTotal);
- GfaTfuGetClock(&tsStart);
- break;
- case GBDPS_EndEraseFlash:
- GfaTfuGetClock(&tsEnd);
- nInterval = GfaTfuClockDiff(&tsEnd, &tsStart);
- TRACE2("Erased %u flash pages in %lld ms (%.1f ms/page).\n", pdlpp->nCntFlashPages, nInterval / 1000000, ((double)nInterval / 1000000.0) / (double)pdlpp->nCntFlashPages);
- TTRACE2("Erased %u flash pages in %lld ms (%.1f ms/page)", pdlpp->nCntFlashPages, nInterval / 1000000, ((double)nInterval / 1000000.0) / (double)pdlpp->nCntFlashPages);
- TTRACE(PLUGIN_TAG_UPLOAD_END_ERASE_FLASH, "%u|%u", pdlpp->nCntFlashPages, pdlpp->nCbTotal);
- break;
- case GBDPS_StartUploadBlocks:
- nBlockNr = 0;
- nOldPerc = -1;
- TRACE2("Start sending data to node 0x%02hhX - block size: %u bytes.\n", pdlpp->nNodeAddr, pdlpp->nCbBlock);
- TTRACE2("Start sending data to node 0x%02hhX - block size: %u bytes", pdlpp->nNodeAddr, pdlpp->nCbBlock);
- TTRACE(PLUGIN_TAG_UPLOAD_BLOCKS_START, "%u", pdlpp->nCbBlock);
- GfaTfuGetClock(&tsStart);
- break;
- case GBDPS_UploadBlock:
- if(!pcla || !pcla->bNoProgressBlock)
- {
- if((nPerc = GfaTfuGetPercentString(pdlpp->nCbSent, pdlpp->nCbTotal, szPercString, sizeof(szPercString)))!= nOldPerc)
- {
- if((pcla->nVerbosity < 4) && (nBlockNr > 0))
- TRACE2("\b\b\b\b\b");
- TRACE2("%s", szPercString);
- nOldPerc = nPerc;
- }
- }
- ++nBlockNr;
- TTRACE(PLUGIN_TAG_UPLOAD_BLOCK, "%u|%u", pdlpp->nCbSent, nBlockNr);
- break;
- case GBDPS_EndUploadBlocks:
- GfaTfuGetClock(&tsEnd);
- nInterval = GfaTfuClockDiff(&tsEnd, &tsStart);
- if(!pcla || !pcla->bNoProgressBlock)
- TRACE2(" - Done.\n");
- TRACE2("Sent %u blocks to node 0x%02hhX in %llu ms (%.1f Kb/s).\n", nBlockNr, pdlpp->nNodeAddr, nInterval / 1000000, (double)pdlpp->nCbTotal / ((double)nInterval / 1000000000.0) / 1024.0);
- TTRACE2("Sent %u blocks to node 0x%02hhX in %llu ms (%.1f Kb/s)", nBlockNr, pdlpp->nNodeAddr, nInterval / 1000000, (double)pdlpp->nCbTotal / ((double)nInterval / 1000000000.0) / 1024.0);
- TTRACE(PLUGIN_TAG_UPLOAD_BLOCKS_END, "%u", nBlockNr);
- break;
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////
- int main(int argc, char* argv[])
- {
- int nRet = 0;
- HIMGFILE hIf = NULL; // Handle to the image file
- HGFABLM hBlm = NULL; // Handle to the bootloader master
- CMD_LINE_ARGS cla; // structure that receives all required options and parameters
- struct sigaction sa;
- /////////////////////////////////////////////////////////////////////////
- // process command line
- GfaTfuCmdOptInitOpts(&cla); // set options defaults
- GfaTfuCmdOptParse(argc, argv, &cla); // parse the command line
- if((nRet = GfaTfuCmdOptProcess(&cla)) != 0) // validate the options in their context
- {
- if(nRet > 0)
- {
- if(!cla.bPluginMode)
- {
- GfaTfuCmdOptDisplayHelp(cla.nQuestionMarks == 3); // show Help and exit
- return 0;
- }
- else
- {
- TTRACE1("Invalid command or option");
- TTRACEEXIT("1");
- return 1;
- }
- }
- else if(nRet == (int)GFA_FU_ERROR_MISSING_COMMAND_OPT) // A required option is missing
- {
- TRACE0("Error: %s: %s!\n", GfaTfuStrError(nRet), GfaTfuCmdOpt2String(cla.nMissingOptFlags));
- TTRACE1("%s: %s", GfaTfuStrError(nRet), GfaTfuCmdOpt2String(cla.nMissingOptFlags));
- }
- else if(nRet == (int)GFA_FU_ERROR_MULTIPLE_COMMANDS) // Multiple commands were given
- {
- TRACE0("Error: %s: %s!\n", GfaTfuStrError(nRet), GfaTfuCmdOpt2String(cla.nCmdFlags));
- TTRACE1("%s: %s", GfaTfuStrError(nRet), GfaTfuCmdOpt2String(cla.nCmdFlags));
- }
- else // Another error occured
- {
- TRACE0("Error: %s!\n", GfaTfuStrError(nRet));
- TTRACE1("%s", GfaTfuStrError(nRet));
- }
- TTRACEEXIT("%d", nRet);
- return nRet;
- }
- // At this point all command line options have been parsed and validated and the cla structure
- // contains all necessary parameters for the requested command.
- // Dump an overview of the provided command and the explicitly set options.
- GfaTfuCmdOptDumpOptions(&cla);
- /////////////////////////////////////////////////////////////////////////
- // configure signal handling
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = _SigHandler;
- sigaction(SIGHUP, &sa, NULL); // handle user's terminal disconnect
- sigaction(SIGQUIT, &sa, NULL); // handle Ctrl + '\'
- sigaction(SIGTERM, &sa, NULL); // handle normal termination
- sigaction(SIGABRT, &sa, NULL); // handle abnormal termination (i.e. abort())
- sigaction(SIGINT, &sa, NULL); // handle Ctrl + 'C'
- sa.sa_handler = SIG_IGN;
- sigaction(SIGTSTP, &sa, NULL); // ignore Ctrl + 'Z'
- sigaction(SIGSTOP, &sa, NULL); // ignore Stop
- sigaction(SIGCONT, &sa, NULL); // ignore Continue
- sigaction(SIGCHLD, &sa, NULL); // ignore child process termination
- sigaction(0, &sa, NULL); // ignore shell termination
- /////////////////////////////////////////////////////////////////////////
- do
- {
- GFA_BLM_CFG_PARAMS blmcp; // bootloader master configuration struct
- memset(&blmcp, 0, sizeof(blmcp));
- if(cla.bNeedImgFile) // If the given command requires an image file, open it.
- { // This also performs some basic validations on the file.
- GFA_IMG_INFO ii;
- TRACE3("Opening image file %s.\n", cla.pszImgFile);
- TTRACE3("Opening image file %s", cla.pszImgFile);
- if(!(hIf = GfaTfuImageFileOpen(cla.pszImgFile, cla.nStartAddr, true)))
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno)); // Something is wrong with the file
- TTRACE1(GfaTfuStrError(errno));
- break;
- }
- GfaTfuImageFileGetInfo(hIf, &ii);
- TTRACE(PLUGIN_TAG_IMG_LENGTH_FILE, "%u", ii.nImgLength);
- TTRACE(PLUGIN_TAG_IMG_CRC32_FILE, "%u", ii.nImgCRC32);
- TTRACE(PLUGIN_TAG_IMG_MATERIAL_FILE, "%s", ii.szImgMaterialNum);
- TTRACE(PLUGIN_TAG_IMG_BUILD_FILE, "%s", ii.szImgNameBuild);
- if(cla.bShowFileImgInfo) // If only the file's image information was requested, dump it and exit.
- {
- GfaTfuDumpImageInfo(cla.pszImgFile, &ii);
- break;
- }
- }
- // As of this point we require a connection to the target.
- // In our case we request the serial device interface,
- // which is in turn used by the abstract mininet device
- if(GfaSerialGetDeviceInterface(&blmcp.mmcp.devcfg.itf))
- {
- GFA_SER_CFG_PARAMS scp; // serial device configuration parameters
- memset(&scp, 0, sizeof(scp));
- /////////////////////////////////////////////////////////////////
- // serial device configuration
- scp.baud = cla.nInitBaudrate; // open with default bootloader baud-rate
- scp.data = 8; // always use 8 data bits
- scp.stop = 1; // always use 1 stop bit
- scp.parity = 'N'; // open with mininet default
- #ifdef _TARGET_BUILD
- scp.bHandleTxEcho = true; // On GfA Sitara targets we have to handle transmit echo!
- scp.bIsRS485 = true; // Interface is a RS485
- #endif // _TARGET_BUILD
- /////////////////////////////////////////////////////////////////
- // mininet master device configuration
- // since the mininet master handles the opening and closing of the
- // mininet device, which is the abstraction layer of our physical
- // device and in turn handles our serial device, we provide the
- // appropriate parameters.
- blmcp.mmcp.devcfg.pszDeviceName = cla.pszDevName; // name of the interface, i.e. "/dev/ttyO4"
- blmcp.mmcp.devcfg.pDevParams = &scp; // pointer to the serial device configuration parameters
- blmcp.mmcp.devcfg.nSizeDevParams = sizeof(scp); // size of the serial device configuration parameters
- /////////////////////////////////////////////////////////////////
- // bootloader master configuration
- blmcp.pfnDlProgress = _OnUploadProgress; // progress output function for the image upload
- blmcp.pUserParam = &cla; // will be passed to the progress function
- /////////////////////////////////////////////////////////////////
- // open a bootloader master instance
- TRACE3("Opening bootloader master.\n");
- TTRACE3("Opening bootloader master");
- if((hBlm = GfaBlmOpen(&blmcp)))
- {
- // At this point the bootloader master, the mininet master and the mininet device
- // have been opened and initialized successfully
- GFA_BLM_EXEC_CONTEXT ctx;
- bool bModbusAppDetected = false;
- GfaBlmSetVerbosity(hBlm, cla.nVerbosity); // Set the verbosity of the bootloader master and it's descendants
- TRACE3("Connecting to target.\n");
- TTRACE3("Connecting to target");
- if(!_AutoBaud(hBlm, &cla)) // Try to detect the mininet baudrate and parity
- {
- // If no mininet connection could be detected, try to scan for a modbus connection, given that
- // a valid modbus slave-id has been provided.
- if( !MODBUS_IS_VALID_SLAVE_ID(cla.nModbusSlvID) ||
- !(bModbusAppDetected = _ModbusAutobaud(hBlm, &cla)))
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- break;
- }
- }
- if(bModbusAppDetected)
- {
- // A modbus application is running on the target
- ctx = GfaBlmCtx_ModB;
- // Most (but not all) of the commands require the bootloader to be started implicitly, especially when a modbus application is running,
- // which is not capable of any command that even a minintet application could handle
- if(cla.bUploadImg || cla.bShowDevImgInfo || cla.bValidateImg || cla.bShowMatSer || cla.bSetMatSer)
- {
- if((nRet = _ModbusStartBootloader(hIf, hBlm, &cla, ctx)) != 0)
- break;
- ctx = GfaBlmCtx_Boot;
- }
- else if(!cla.bPing && !cla.bStartBoot) // Ping works with a modbus application as well, so there's no need to start the bootloader.
- { // --start-boot is an explicit command on it's own and is handled later.
- TRACE2("Nothing to do.\n"); // At this point either a --reset-boot or --revive-boot command was given. Both commands make no sense when any
- TTRACE2("Nothing to do"); // kind of application is running, so just exit.
- break;
- }
- }
- else
- {
- // No modbus application was detected, so we are dealing either with a mininet application or the bootloader itself. Find out what ...
- TRACE3("Detecting running image.\n");
- TTRACE3("Detecting running image");
- ctx = GfaBlmGetExecutionContext(hBlm, cla.nNodeAddr);
- if((ctx == GfaBlmCtx_Err) || (ctx == GfaBlmCtx_Boot))
- {
- // Either an error was returned, or the bootloader is running.
- // In the latter case, we don't know yet, if it is in a responsive state, because the detection
- // involved mininet communication only! We force the bootloader into a working state preventively.
- // If the bootloader has already been working correctly, nothing will happen.
- if((nRet = _ReviveBootloader(hIf, hBlm, &cla, ctx, true)) != 0)
- {
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- break;
- }
- ctx = GfaBlmCtx_Boot;
- }
- TRACE3("Currently running: %s.\n", (ctx == GfaBlmCtx_App) ? "Application" : "Bootloader");
- TTRACE3("Currently running: %s", (ctx == GfaBlmCtx_App) ? "Application" : "Bootloader");
- }
- // handle the commands
- if(cla.bUploadImg)
- nRet = _UploadImg(hIf, hBlm, &cla, ctx); // handle --upload-img
- else if(cla.bValidateImg)
- nRet = _ValidateImg(hIf, hBlm, &cla, ctx); // handle --validate-img
- else if(cla.bShowDevImgInfo)
- nRet = _ShowDevImgInfo(hIf, hBlm, &cla, ctx); // handle --show-dev-img-info
- else if(cla.bShowMatSer)
- nRet = _ShowMatSer(hIf, hBlm, &cla, ctx); // handle --show-mat-ser
- else if(cla.bSetMatSer)
- nRet = _SetMatSer(hIf, hBlm, &cla, ctx); // handle --set-mat-ser
- else if(cla.bPing)
- nRet = _Ping(hIf, hBlm, &cla, ctx); // handle --ping-target
- else if(cla.bStartBoot)
- nRet = _StartBootloader(hIf, hBlm, &cla, ctx); // handle --start-boot
- else if(cla.bResetBoot)
- nRet = _ResetBootloader(hIf, hBlm, &cla, ctx); // handle --reset-boot
- else if(cla.bReviveBoot)
- nRet = _ReviveBootloader(hIf, hBlm, &cla, ctx, false); // handle --revive-boot
- }
- else
- { // GfaBlmOpen failed
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- break;
- }
- }
- else
- { // GfaSerialGetDeviceInterface failed
- TRACE1("Error: %s!\n", GfaTfuStrError(errno));
- TTRACE1(GfaTfuStrError(errno));
- break;
- }
- }
- while(false);
- if(hBlm)
- {
- TRACE3("Closing bootloader master.\n");
- TTRACE3("Closing bootloader master");
- GfaBlmClose(hBlm);
- }
- if(hIf)
- {
- TRACE3("Closing image file.\n");
- TTRACE3("Closing image file");
- GfaTfuImageFileClose(hIf);
- }
- TTRACEEXIT("%d", nRet);
- return nRet;
- }
|