|
@@ -1,5 +1,6 @@
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <string.h>
|
|
|
|
+#include <malloc.h>
|
|
#include <ctype.h>
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <unistd.h>
|
|
@@ -8,10 +9,1431 @@
|
|
#include <byteswap.h>
|
|
#include <byteswap.h>
|
|
#include "bl_commands.h"
|
|
#include "bl_commands.h"
|
|
#include "gfabootlmast.h"
|
|
#include "gfabootlmast.h"
|
|
|
|
+#include "dbghlp.h"
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+#define _dword_offset(m) (offsetof(GFA_APP_IMG_HEADER, m) / sizeof(uint32_t) - 2)
|
|
|
|
+
|
|
|
|
+#ifdef _DEBUG
|
|
|
|
+#define _EXEC_CALLBACK(pfn, ...) if(pfn) (*pfn)(__FILE__, __LINE__, __VA_ARGS__)
|
|
|
|
+#else // _DEBUG
|
|
|
|
+#define _EXEC_CALLBACK(pfn, ...) if(pfn) (*pfn)(__VA_ARGS__)
|
|
|
|
+#endif // _DEBUG
|
|
|
|
+
|
|
|
|
+#define _BOOTLOADER_EXEC_WAIT_TIME 250
|
|
|
|
+#define _GFA_MAX_DUMP_DWORDS 16
|
|
|
|
+#define _MAX_SEND_DATA_BLOCK_SIZE 76
|
|
|
|
+#define _DEF_SEND_DATA_BLOCK_SIZE 64
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+typedef struct _GFA_BLM
|
|
|
|
+{
|
|
|
|
+ HGFAMINEMST hMst;
|
|
|
|
+ PFN_BU_CMD_DOWNLOAD_STATUS pfnBuCmdDownloadStatus;
|
|
|
|
+ PFN_BU_CMD_SEND_DATA_STATUS pfnBuCmdSendDataStatus;
|
|
|
|
+ int nVerbosity;
|
|
|
|
+}GFA_BLM, *LPGFA_BLM;
|
|
|
|
+typedef const GFA_BLM *LPCGFA_BLM;
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+#define GFA_APP_BOOTLOADER_START_ADDRESS ((uint32_t)0x00000000)
|
|
|
|
+#define GFA_APP_APPLICATION_START_ADDRESS ((uint32_t)0x00002000)
|
|
|
|
+#define GFA_APP_IMG_HEADER_PREFIX_0 ((uint32_t)0xFF01FF02)
|
|
|
|
+#define GFA_APP_IMG_HEADER_PREFIX_1 ((uint32_t)0xFF03FF04)
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+typedef struct _GFA_APP_IMG_HEADER
|
|
|
|
+{
|
|
|
|
+ const uint32_t nPrefix0;
|
|
|
|
+ const uint32_t nPrefix1;
|
|
|
|
+ const uint32_t nImgLength;
|
|
|
|
+ const uint32_t nImgCRC32;
|
|
|
|
+ const uint32_t nReserved[4];
|
|
|
|
+ union
|
|
|
|
+ {
|
|
|
|
+ struct
|
|
|
|
+ {
|
|
|
|
+ const char * const pszImgMaterialNum;
|
|
|
|
+ const char * const pszImgNameBuild;
|
|
|
|
+ }app;
|
|
|
|
+ struct
|
|
|
|
+ {
|
|
|
|
+ const char szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH];
|
|
|
|
+ const char szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH];
|
|
|
|
+ }bl;
|
|
|
|
+ };
|
|
|
|
+}GFA_APP_IMG_HEADER, *LPGFA_APP_IMG_HEADER;
|
|
|
|
+typedef const GFA_APP_IMG_HEADER *LPCGFA_APP_IMG_HEADER;
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+HGFABLM GfaBlmOpen(LPCGFA_BLM_CFG_PARAMS pblmcfg)
|
|
|
|
+{
|
|
|
|
+ if(pblmcfg)
|
|
|
|
+ {
|
|
|
|
+ HGFAMINEMST hMst = GfaMininetMasterOpen(&pblmcfg->mmcp);
|
|
|
|
+
|
|
|
|
+ if(hMst)
|
|
|
|
+ {
|
|
|
|
+ LPGFA_BLM pBlm = malloc(sizeof(GFA_BLM));
|
|
|
|
+ memset(pBlm, 0, sizeof(GFA_BLM));
|
|
|
|
+ pBlm->hMst = hMst;
|
|
|
|
+ pBlm->pfnBuCmdDownloadStatus = pblmcfg->pfnBuCmdDownloadStatus;
|
|
|
|
+ pBlm->pfnBuCmdSendDataStatus = pblmcfg->pfnBuCmdSendDataStatus;
|
|
|
|
+ return (HGFABLM)pBlm;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+void GfaBlmClose(HGFABLM hBlm)
|
|
|
|
+{
|
|
|
|
+ if(hBlm)
|
|
|
|
+ {
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ GfaMininetMasterClose(pBlm->hMst);
|
|
|
|
+ free(pBlm);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmResetSlaveIndex(HGFABLM hBlm, uint8_t nNodeAddr)
|
|
|
|
+{
|
|
|
|
+ if(hBlm)
|
|
|
|
+ {
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ return GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+ssize_t GfaBlmBUCmdPollData(HGFABLM hBlm, uint8_t nNodeAddr, void *pData, size_t nCbData, uint32_t nTimeoutMS)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pData && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ size_t s, nReceived = 0;
|
|
|
|
+ struct timeval tvRX;
|
|
|
|
+ ssize_t nLen, nRet = -1;
|
|
|
|
+ uint8_t cmd[32];
|
|
|
|
+ uint8_t txb[32];
|
|
|
|
+ uint8_t rxb[512];
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ uint8_t *pszData = (uint8_t*)pData;
|
|
|
|
+ tvRX.tv_sec = nTimeoutMS / 1000;
|
|
|
|
+ tvRX.tv_usec = (nTimeoutMS % 1000) * 1000;
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterSaveTimeouts(pBlm->hMst);
|
|
|
|
+ GfaMininetMasterSetTimeouts(pBlm->hMst, &tvRX, NULL);
|
|
|
|
+
|
|
|
|
+ while(nReceived < nCbData)
|
|
|
|
+ {
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BU", 0, NULL, 0, cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) <= 0)
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) > 0)
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, pszData, nCbData - nReceived)) > 0)
|
|
|
|
+ {
|
|
|
|
+ pszData += nRet;
|
|
|
|
+ nReceived += nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if(nTimeoutMS > 0)
|
|
|
|
+ {
|
|
|
|
+ if(nTimeoutMS >= 100)
|
|
|
|
+ {
|
|
|
|
+ usleep(100000);
|
|
|
|
+ nTimeoutMS -= 100;
|
|
|
|
+// TRACE("\nACK ...\n");
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ usleep(nTimeoutMS * 1000);
|
|
|
|
+ nTimeoutMS = 0;
|
|
|
|
+// TRACE("\nACK ...\n");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = ETIMEDOUT;
|
|
|
|
+ nReceived = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ nReceived = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ nReceived = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ nReceived = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterRestoreTimeouts(pBlm->hMst);
|
|
|
|
+ return nReceived;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdReset(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nTimeoutMS)
|
|
|
|
+{
|
|
|
|
+ if(hBlm)
|
|
|
|
+ {
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ uint8_t cmd = COMMAND_RESET;
|
|
|
|
+ uint8_t cmddata[16];
|
|
|
|
+ char txb[32], rxb[256], ack[2];
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaBlmBootloaderSetBaudrate(hBlm, nNodeAddr, 19200)) != 0)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BU", 0, &cmd, 1, cmddata, sizeof(cmddata), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmddata, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if(NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
|
|
|
|
+ (nRet == MINET_SLAVE_RESPONSE_ACK))
|
|
|
|
+ {
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if( (ack[0] == 0) &&
|
|
|
|
+ (ack[1] == COMMAND_ACK))
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ if(nTimeoutMS > _BOOTLOADER_EXEC_WAIT_TIME)
|
|
|
|
+ {
|
|
|
|
+ usleep(_BOOTLOADER_EXEC_WAIT_TIME * 1000);
|
|
|
|
+ nTimeoutMS -= _BOOTLOADER_EXEC_WAIT_TIME;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ usleep(nTimeoutMS * 1000);
|
|
|
|
+ nTimeoutMS = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr)) == 0)
|
|
|
|
+ break;
|
|
|
|
+ GfaMininetMasterPurgeDeviceRXBuffer(pBlm->hMst);
|
|
|
|
+ }
|
|
|
|
+ while(nTimeoutMS > 0);
|
|
|
|
+
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdPing(HGFABLM hBlm, uint8_t nNodeAddr)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ uint8_t nCmd = COMMAND_PING;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ char txb[32], rxb[32], cmd[8], ack[2];
|
|
|
|
+
|
|
|
|
+ size_t s = GfaBlmBuildCmdDataPacket("BU", 0, &nCmd, 1, cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) < nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
|
|
|
|
+ (nRet == MINET_SLAVE_RESPONSE_ACK))
|
|
|
|
+ {
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(ack[0] == 0)
|
|
|
|
+ {
|
|
|
|
+ return (ack[1] == COMMAND_ACK);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdGetStatus(HGFABLM hBlm, uint8_t nNodeAddr, uint8_t *pbStatus)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pbStatus && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ uint8_t nCmd = COMMAND_GET_STATUS;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ char txb[32], rxb[32], cmd[8], ack[3], stat[3];
|
|
|
|
+
|
|
|
|
+ size_t s = GfaBlmBuildCmdDataPacket("BU", 0, &nCmd, 1, cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) < nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if( (nRet == MINET_SLAVE_RESPONSE_SUCCESS) ||
|
|
|
|
+ (nRet == MINET_SLAVE_RESPONSE_ACK))
|
|
|
|
+ {
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 200)) != 2)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(ack[0] == 0)
|
|
|
|
+ {
|
|
|
|
+ if(ack[1] == COMMAND_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, stat, 3, 200)) != 3)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if((stat[0] == 3) && (stat[1] == stat[2]))
|
|
|
|
+ {
|
|
|
|
+ if(pbStatus)
|
|
|
|
+ *pbStatus = stat[2];
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BU\xCC", 3, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdDownload(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nFlashStartAddr, uint32_t nCbData, uint32_t nTimeoutMS)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ uint8_t nIndex, nStatus;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ uint32_t nAddr = bswap_32(nFlashStartAddr), nCount = bswap_32(nCbData);
|
|
|
|
+ uint8_t txb[32], rxb[32], cmd[16], data[9], ack[2];
|
|
|
|
+ data[0] = COMMAND_DOWNLOAD;
|
|
|
|
+ struct timeval tv;
|
|
|
|
+ memcpy(&data[1], &nAddr, sizeof(nAddr));
|
|
|
|
+ memcpy(&data[5], &nCount, sizeof(nCount));
|
|
|
|
+ tv.tv_sec = nTimeoutMS / 1000;
|
|
|
|
+ tv.tv_usec = (nTimeoutMS % 1000) * 1000;
|
|
|
|
+
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BU", 0, data, sizeof(data), cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterSaveTimeouts(pBlm->hMst);
|
|
|
|
+ GfaMininetMasterSetTimeouts(pBlm->hMst, &tv, NULL);
|
|
|
|
+
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 1, 0);
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ GfaMininetMasterRestoreTimeouts(pBlm->hMst);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ GfaMininetMasterRestoreTimeouts(pBlm->hMst);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 2, 0);
|
|
|
|
+ GfaMininetMasterRestoreTimeouts(pBlm->hMst);
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if(nStatus == COMMAND_RET_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 3, 0);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, nTimeoutMS)) != 2)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ if(nStatus == COMMAND_RET_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 3, 0);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdDownloadStatus, nNodeAddr, nFlashStartAddr, nCbData, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdSendDataBlock(HGFABLM hBlm, uint8_t nNodeAddr, const void *pDataBlock, size_t nCbDataBlock)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pDataBlock && nCbDataBlock && (nCbDataBlock <= 250) && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ ssize_t nRet;
|
|
|
|
+ struct timeval tv;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ tv.tv_sec = 0;
|
|
|
|
+ tv.tv_usec = 500000;
|
|
|
|
+ GfaMininetMasterSaveTimeouts(pBlm->hMst);
|
|
|
|
+ GfaMininetMasterSetTimeouts(pBlm->hMst, &tv, NULL);
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nLen;
|
|
|
|
+ uint8_t nIndex, nStatus;
|
|
|
|
+ uint8_t txb[512], rxb[32], cmd[256], data[256], ack[2];
|
|
|
|
+ data[0] = COMMAND_SEND_DATA;
|
|
|
|
+ memcpy(&data[1], pDataBlock, nCbDataBlock);
|
|
|
|
+
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BU", 0, data, nCbDataBlock + 1, cmd, sizeof(cmd), true);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, ack, 2)) != 2)
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if(nStatus != COMMAND_RET_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ errno = -nStatus;
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ nRet = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, ack, 2, 5000)) != 2)
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((ack[0] == 0) && (ack[1] == COMMAND_ACK))
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdGetStatus(hBlm, nNodeAddr, &nStatus)))
|
|
|
|
+ {
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if(nStatus != COMMAND_RET_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ errno = -nStatus;
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ nRet = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ nRet = -1;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ while(false);
|
|
|
|
+
|
|
|
|
+ GfaMininetMasterRestoreTimeouts(pBlm->hMst);
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdSendData(HGFABLM hBlm, uint8_t nNodeAddr, const void *pData, size_t nCbData, size_t nCbBlock)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pData && nCbData && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ int nRet;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ const uint8_t *pbData = (const uint8_t*)pData;
|
|
|
|
+ uint32_t nSent = 0;
|
|
|
|
+
|
|
|
|
+ if(!nCbBlock || nCbBlock < 4 || nCbBlock > _MAX_SEND_DATA_BLOCK_SIZE)
|
|
|
|
+ nCbBlock = _DEF_SEND_DATA_BLOCK_SIZE;
|
|
|
|
+ else
|
|
|
|
+ nCbBlock &= ~0x03;
|
|
|
|
+
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 1, 0);
|
|
|
|
+
|
|
|
|
+ while(nCbData >= nCbBlock)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdSendDataBlock(hBlm, nNodeAddr, pbData, nCbBlock)) != 0)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ nCbData -= nCbBlock;
|
|
|
|
+ pbData += nCbBlock;
|
|
|
|
+ nSent += nCbBlock;
|
|
|
|
+
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 2, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(nCbData)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdSendDataBlock(hBlm, nNodeAddr, pbData, nCbData)) != 0)
|
|
|
|
+ {
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 0, errno);
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ nSent += nCbData;
|
|
|
|
+ nCbData = 0;
|
|
|
|
+
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 2, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _EXEC_CALLBACK(pBlm->pfnBuCmdSendDataStatus, nNodeAddr, nCbBlock, nSent, 3, 0);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBUCmdSendDataFile(HGFABLM hBlm, uint8_t nNodeAddr, const char *pszFilename, uint32_t nFlashStartAddr, size_t nCbBlock, uint32_t nTimeoutMS)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pszFilename && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ int nRet = -1;
|
|
|
|
+ ssize_t nFileLen;
|
|
|
|
+ FILE *pf = NULL;
|
|
|
|
+ uint8_t *pBuf = NULL;
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ if(!(pf = fopen(pszFilename, "rb")))
|
|
|
|
+ break;
|
|
|
|
+ if(fseek(pf, 0, SEEK_END))
|
|
|
|
+ break;
|
|
|
|
+ if((nFileLen = ftell(pf)) < 0)
|
|
|
|
+ break;
|
|
|
|
+ if(fseek(pf, 0, SEEK_SET))
|
|
|
|
+ break;
|
|
|
|
+ if( (nFileLen > 0) &&
|
|
|
|
+ (pBuf = (uint8_t*)malloc(nFileLen)) &&
|
|
|
|
+ (fread(pBuf, 1, nFileLen, pf) == (size_t)nFileLen))
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdDownload(hBlm, nNodeAddr, nFlashStartAddr, nFileLen, nTimeoutMS)) == 0)
|
|
|
|
+ nRet = GfaBlmBUCmdSendData(hBlm, nNodeAddr, pBuf, nFileLen, nCbBlock);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ while(false);
|
|
|
|
+
|
|
|
|
+ if(pBuf)
|
|
|
|
+ free(pBuf);
|
|
|
|
+ if(pf)
|
|
|
|
+ fclose(pf);
|
|
|
|
+
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+GFA_BLM_EXEC_CONTEXT GfaBlmGetExecutionContext(HGFABLM hBlm, uint8_t nNodeAddr)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ char txb[32], rxb[32];
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BU", 2, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return GfaBlmCtx_Err;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) <= 0)
|
|
|
|
+ return GfaBlmCtx_Err;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ return GfaBlmCtx_Err;
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ return GfaBlmCtx_Boot;
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ return GfaBlmCtx_App;
|
|
|
|
+
|
|
|
|
+ return GfaBlmCtx_Err;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return GfaBlmCtx_Err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBootloaderExecute(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t *pnImgCRC32, uint32_t nTimeoutMS)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ uint32_t nImgCRC32;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ char txb[32], rxb[32];
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BE", 2, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, &nImgCRC32, sizeof(nImgCRC32))) == 4)
|
|
|
|
+ {
|
|
|
|
+ if(pnImgCRC32)
|
|
|
|
+ *pnImgCRC32 = bswap_32(nImgCRC32);
|
|
|
|
+
|
|
|
|
+ do
|
|
|
|
+ {
|
|
|
|
+ if(nTimeoutMS > _BOOTLOADER_EXEC_WAIT_TIME)
|
|
|
|
+ {
|
|
|
|
+ usleep(_BOOTLOADER_EXEC_WAIT_TIME * 1000);
|
|
|
|
+ nTimeoutMS -= _BOOTLOADER_EXEC_WAIT_TIME;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ usleep(nTimeoutMS * 1000);
|
|
|
|
+ nTimeoutMS = 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterResetSlaveIndex(pBlm->hMst, nNodeAddr)) == 0)
|
|
|
|
+ break;
|
|
|
|
+ GfaMininetMasterPurgeDeviceRXBuffer(pBlm->hMst);
|
|
|
|
+ }
|
|
|
|
+ while(nTimeoutMS > 0);
|
|
|
|
+
|
|
|
|
+ return nRet;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBootloaderSetBaudrate(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nBaudrate)
|
|
|
|
+{
|
|
|
|
+ if(hBlm)
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+
|
|
|
|
+ if(GfaMininetMasterIsValidBaudrate(pBlm->hMst, nBaudrate))
|
|
|
|
+ {
|
|
|
|
+ char txb[32], rxb[32], cmd[8];
|
|
|
|
+ uint32_t nBr = bswap_32(nBaudrate);
|
|
|
|
+
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BB", 0, &nBr, sizeof(nBr), cmd, sizeof(cmd), false);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if(NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ return GfaMininetMasterSetBaudrate(pBlm->hMst, nBaudrate);
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmBootloaderDump(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nAddress, uint32_t nCntDwords, void *pBuffer, size_t nCbBuffer)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pBuffer && nCntDwords && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ size_t s;
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ uint32_t i, dmp[_GFA_MAX_DUMP_DWORDS];
|
|
|
|
+ char txb[32], rxb[128], cmd[10];
|
|
|
|
+
|
|
|
|
+ if(nCntDwords > _GFA_MAX_DUMP_DWORDS)
|
|
|
|
+ nCntDwords = _GFA_MAX_DUMP_DWORDS;
|
|
|
|
+
|
|
|
|
+ if((nCntDwords * sizeof(uint32_t)) > nCbBuffer)
|
|
|
|
+ {
|
|
|
|
+ errno = ENOMEM;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ struct _MEM
|
|
|
|
+ {
|
|
|
|
+ uint32_t nAddr;
|
|
|
|
+ uint32_t nCount;
|
|
|
|
+ }mem = {bswap_32(nAddress), bswap_32(nCntDwords)};
|
|
|
|
+
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BD", 0, &mem, sizeof(mem), cmd, sizeof(cmd), false);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, dmp, sizeof(uint32_t) * nCntDwords)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
|
|
|
|
+ return -1;
|
|
|
|
+ for(i = 0; i < nCntDwords; ++i)
|
|
|
|
+ {
|
|
|
|
+ dmp[i] = bswap_32(dmp[i]);
|
|
|
|
+ }
|
|
|
|
+ memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, dmp, sizeof(uint32_t) * nCntDwords, 200)) != (ssize_t)(sizeof(uint32_t) * nCntDwords))
|
|
|
|
+ return -1;
|
|
|
|
+ for(i = 0; i < nCntDwords; ++i)
|
|
|
|
+ {
|
|
|
|
+ dmp[i] = bswap_32(dmp[i]);
|
|
|
|
+ }
|
|
|
|
+ memcpy(pBuffer, dmp, sizeof(uint32_t) * nCntDwords);
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int GfaBlmGetImgInfo(HGFABLM hBlm, uint8_t nNodeAddr, uint32_t nDumpAddr, bool bCtxIsApp, LPGFA_IMG_INFO pii)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pii && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ ssize_t nRet = 0;
|
|
|
|
+ uint32_t i, j, nPfx0Addr = 0;
|
|
|
|
+ int32_t nPfx0Index = -1, nPfx1Index = -1;
|
|
|
|
+ uint32_t aDump[_GFA_MAX_DUMP_DWORDS];
|
|
|
|
+ GFA_APP_IMG_HEADER aih;
|
|
|
|
+ memset(&aih, 0, sizeof(aih));
|
|
|
|
+ memset(pii, 0, sizeof(GFA_IMG_INFO));
|
|
|
|
+
|
|
|
|
+ for(i = 0; i < 257; i += _GFA_MAX_DUMP_DWORDS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDumpAddr, _GFA_MAX_DUMP_DWORDS, aDump, sizeof(aDump))) == 0)
|
|
|
|
+ {
|
|
|
|
+ for(j = 0; j < _GFA_MAX_DUMP_DWORDS; ++j, nDumpAddr += sizeof(uint32_t))
|
|
|
|
+ {
|
|
|
|
+ switch(aDump[j])
|
|
|
|
+ {
|
|
|
|
+ case GFA_APP_IMG_HEADER_PREFIX_0:
|
|
|
|
+ nPfx0Addr = nDumpAddr;
|
|
|
|
+ nPfx0Index = i + j;
|
|
|
|
+ continue;
|
|
|
|
+ case GFA_APP_IMG_HEADER_PREFIX_1:
|
|
|
|
+ nPfx1Index = i + j;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nPfx0Index >= 0) && (nPfx1Index == (nPfx0Index + 1)))
|
|
|
|
+ {
|
|
|
|
+ uint32_t nDmpStart = nPfx0Addr + 2 * sizeof(uint32_t), *pDwDst = ((uint32_t*)&aih) + 2;
|
|
|
|
+ uint32_t nCntDwAvail = 15 - j;
|
|
|
|
+
|
|
|
|
+ if(bCtxIsApp)
|
|
|
|
+ {
|
|
|
|
+ uint32_t nDwOffsImgMaterialNum = _dword_offset(app.pszImgMaterialNum);
|
|
|
|
+ uint32_t nDwOffsImgNameBuild = _dword_offset(app.pszImgNameBuild);
|
|
|
|
+ uint32_t nDwOffsImgCRC32 = _dword_offset(nImgCRC32);
|
|
|
|
+ size_t nSizeDst = (nDwOffsImgNameBuild + 1) * sizeof(uint32_t);
|
|
|
|
+ uint32_t nCntDwToDmp, nCntDwToCpy;
|
|
|
|
+
|
|
|
|
+ if(nCntDwAvail > nDwOffsImgNameBuild)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
|
|
|
|
+ // need nothing
|
|
|
|
+ nCntDwToCpy = nDwOffsImgNameBuild + 1;
|
|
|
|
+ nCntDwToDmp = 0;
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ }
|
|
|
|
+ else if(nCntDwAvail == nDwOffsImgNameBuild)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength, nImgCRC32, pszImgMaterialNum
|
|
|
|
+ // need pszImgNameBuild
|
|
|
|
+ nCntDwToCpy = nDwOffsImgNameBuild;
|
|
|
|
+ nCntDwToDmp = 1;
|
|
|
|
+ nDmpStart += nCntDwToCpy * sizeof(uint32_t);
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ pDwDst += nCntDwToCpy;
|
|
|
|
+ nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
|
|
|
|
+ }
|
|
|
|
+ else if(nCntDwAvail > nDwOffsImgCRC32)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength, nImgCRC32
|
|
|
|
+ // need pszImgMaterialNum, pszImgNameBuild
|
|
|
|
+ nCntDwToCpy = 2;
|
|
|
|
+ nCntDwToDmp = 2;
|
|
|
|
+ nDmpStart += nDwOffsImgMaterialNum * sizeof(uint32_t);
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ pDwDst += nDwOffsImgMaterialNum;
|
|
|
|
+ nSizeDst -= nDwOffsImgMaterialNum * sizeof(uint32_t);
|
|
|
|
+ }
|
|
|
|
+ else if(nCntDwAvail == nDwOffsImgCRC32)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength
|
|
|
|
+ // need nImgCRC32, pszImgMaterialNum, pszImgNameBuild
|
|
|
|
+ nCntDwToCpy = nDwOffsImgCRC32;
|
|
|
|
+ nCntDwToDmp = 7; // 1 + 4 + 2
|
|
|
|
+ nDmpStart += sizeof(uint32_t);
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ pDwDst += nCntDwToCpy;
|
|
|
|
+ nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // have nothing
|
|
|
|
+ // need nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
|
|
|
|
+ nCntDwToCpy = 0;
|
|
|
|
+ nCntDwToDmp = nDwOffsImgNameBuild + 1; // 2 + 4 + 2
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(nCntDwToDmp)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDmpStart, nCntDwToDmp, pDwDst, nSizeDst)) != 0)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pii->nImgLength = aih.nImgLength;
|
|
|
|
+ pii->nImgCRC32 = aih.nImgCRC32;
|
|
|
|
+ if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, (uint32_t)aih.app.pszImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH / sizeof(uint32_t), pii->szImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH)) != 0)
|
|
|
|
+ return -1;
|
|
|
|
+ if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, (uint32_t)aih.app.pszImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t), pii->szImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH)) != 0)
|
|
|
|
+ return -1;
|
|
|
|
+ pii->szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
|
|
|
|
+ pii->szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH - 1] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ uint32_t nDwOffsImgMaterialNum = _dword_offset(bl.szImgMaterialNum);
|
|
|
|
+ uint32_t nDwOffsImgNameBuild = _dword_offset(bl.szImgNameBuild);
|
|
|
|
+ uint32_t nDwOffsImgCRC32 = _dword_offset(nImgCRC32);
|
|
|
|
+ size_t nSizeDst = nDwOffsImgNameBuild * sizeof(uint32_t) + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH;
|
|
|
|
+ uint32_t nCntDwToDmp, nCntDwToCpy;
|
|
|
|
+
|
|
|
|
+ if(nCntDwAvail >= (nDwOffsImgNameBuild + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t)))
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength, nImgCRC32, szImgMaterialNum, szImgNameBuild
|
|
|
|
+ // need nothing
|
|
|
|
+ nCntDwToCpy = nDwOffsImgNameBuild + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH / sizeof(uint32_t);
|
|
|
|
+ nCntDwToDmp = 0;
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ }
|
|
|
|
+ else if(nCntDwAvail > nDwOffsImgMaterialNum)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength, nImgCRC32, szImgMaterialNum
|
|
|
|
+ // need szImgNameBuild
|
|
|
|
+ nCntDwToCpy = nCntDwAvail;
|
|
|
|
+ nCntDwToDmp = nSizeDst / sizeof(uint32_t) - nCntDwToCpy; // (1...3) + 6
|
|
|
|
+ nDmpStart += nCntDwToCpy * sizeof(uint32_t);
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ pDwDst += nCntDwToCpy;
|
|
|
|
+ nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
|
|
|
|
+ }
|
|
|
|
+ else if(nCntDwAvail > nDwOffsImgCRC32)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength, nImgCRC32
|
|
|
|
+ // need szImgMaterialNum, szImgNameBuild
|
|
|
|
+ nCntDwToCpy = 2;
|
|
|
|
+ nCntDwToDmp = (GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH + GFA_APP_MAX_IMG_NAME_BUILD_LENGTH) / sizeof(uint32_t); // 4 + 6
|
|
|
|
+ nDmpStart += nDwOffsImgMaterialNum * sizeof(uint32_t);
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ pDwDst += nDwOffsImgMaterialNum;
|
|
|
|
+ nSizeDst -= nDwOffsImgMaterialNum * sizeof(uint32_t);
|
|
|
|
+ }
|
|
|
|
+ else if(nCntDwAvail == nDwOffsImgCRC32)
|
|
|
|
+ {
|
|
|
|
+ // have nImgLength
|
|
|
|
+ // need nImgCRC32, szImgMaterialNum, szImgNameBuild
|
|
|
|
+ nCntDwToCpy = nDwOffsImgCRC32;
|
|
|
|
+ nCntDwToDmp = nSizeDst / sizeof(uint32_t) - nCntDwToCpy; // 1 + 4 + 4 + 6
|
|
|
|
+ nDmpStart += sizeof(uint32_t);
|
|
|
|
+ memcpy(pDwDst, &aDump[j + 1], nCntDwToCpy * sizeof(uint32_t));
|
|
|
|
+ pDwDst += nCntDwToCpy;
|
|
|
|
+ nSizeDst -= nCntDwToCpy * sizeof(uint32_t);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ // have nothing
|
|
|
|
+ // need nImgLength, nImgCRC32, pszImgMaterialNum, pszImgNameBuild
|
|
|
|
+ nCntDwToCpy = 0;
|
|
|
|
+ nCntDwToDmp = nSizeDst / sizeof(uint32_t); // 2 + 4 + 4 + 6
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(nCntDwToDmp)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBootloaderDump(hBlm, nNodeAddr, nDmpStart, nCntDwToDmp, pDwDst, nSizeDst)) != 0)
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pii->nImgLength = aih.nImgLength;
|
|
|
|
+ pii->nImgCRC32 = aih.nImgCRC32;
|
|
|
|
+ memcpy(pii->szImgMaterialNum, aih.bl.szImgMaterialNum, GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH);
|
|
|
|
+ memcpy(pii->szImgNameBuild, aih.bl.szImgNameBuild, GFA_APP_MAX_IMG_NAME_BUILD_LENGTH);
|
|
|
|
+ pii->szImgMaterialNum[GFA_APP_MAX_IMG_MATERIAL_NUM_LENGTH - 1] = '\0';
|
|
|
|
+ pii->szImgNameBuild[GFA_APP_MAX_IMG_NAME_BUILD_LENGTH - 1] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmGetInfoBD(HGFABLM hBlm, uint8_t nNodeAddr, LPGFA_BL_APP_IMG_INFO paii)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && paii && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ int nRet1, nRet2;
|
|
|
|
+
|
|
|
|
+ if((nRet1 = GfaBlmGetImgInfo(hBlm, nNodeAddr, GFA_APP_BOOTLOADER_START_ADDRESS, false, &paii->bl)) < 0)
|
|
|
|
+ {
|
|
|
|
+ memset(&paii->bl, 0, sizeof(paii->bl));
|
|
|
|
+ paii->bl.nImgLength = paii->bl.nImgCRC32 = 0xFFFFFFFF;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if((nRet2 = GfaBlmGetImgInfo(hBlm, nNodeAddr, GFA_APP_APPLICATION_START_ADDRESS, true, &paii->app)) < 0)
|
|
|
|
+ {
|
|
|
|
+ memset(&paii->app, 0, sizeof(paii->app));
|
|
|
|
+ paii->app.nImgLength = paii->app.nImgCRC32 = 0xFFFFFFFF;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nRet1 + nRet2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmGetInfoBI(HGFABLM hBlm, uint8_t nNodeAddr, LPGFA_BL_APP_IMG_INFO paii)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && paii && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[256];
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BI", 2, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, paii, sizeof(GFA_BL_APP_IMG_INFO))) == sizeof(GFA_BL_APP_IMG_INFO))
|
|
|
|
+ {
|
|
|
|
+ paii->bl.nImgLength = bswap_32(paii->bl.nImgLength);
|
|
|
|
+ paii->bl.nImgCRC32 = bswap_32(paii->bl.nImgCRC32);
|
|
|
|
+ paii->app.nImgLength = bswap_32(paii->app.nImgLength);
|
|
|
|
+ paii->app.nImgCRC32 = bswap_32(paii->app.nImgCRC32);
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ errno = EPROTO;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmReadMaterialAndSerialID(HGFABLM hBlm, uint8_t nNodeAddr, char *pszMaterial, size_t nCbMaterial, char *pszSerial, size_t nCbSerial)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pszMaterial && (nCbMaterial >= 16) && pszSerial && (nCbSerial >= 16) && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ char txb[32], rxb[64], data[32];
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, "BR", 2, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nLen = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nLen;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nLen, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaMininetMasterGetDataFromSlaveFrame(rxb, nLen, data, sizeof(data))) != 32)
|
|
|
|
+ return -1;
|
|
|
|
+ memcpy(pszMaterial, data, 16);
|
|
|
|
+ pszMaterial[15] = '\0';
|
|
|
|
+ memcpy(pszSerial, &data[16], 16);
|
|
|
|
+ pszSerial[15] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ if((nRet = GfaBlmBUCmdPollData(hBlm, nNodeAddr, data, sizeof(data), 200)) != (ssize_t)sizeof(data))
|
|
|
|
+ return -1;
|
|
|
|
+ memcpy(pszMaterial, data, 16);
|
|
|
|
+ pszMaterial[15] = '\0';
|
|
|
|
+ memcpy(pszSerial, &data[16], 16);
|
|
|
|
+ pszSerial[15] = '\0';
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
-uint8_t GfaBLM_BU_DataCheckSum(const void *pData, size_t nCbData)
|
|
|
|
|
|
+int GfaBlmWriteMaterialAndSerialID(HGFABLM hBlm, uint8_t nNodeAddr, const char *pszMaterial, const char *pszSerial)
|
|
|
|
+{
|
|
|
|
+ if(hBlm && pszMaterial && pszSerial && !NODE_IS_MULTICAST(nNodeAddr))
|
|
|
|
+ {
|
|
|
|
+ uint8_t nIndex;
|
|
|
|
+ size_t s;
|
|
|
|
+ ssize_t nRet, nLen;
|
|
|
|
+ size_t nLenMaterial, nLenSerial;
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+
|
|
|
|
+ struct _TS
|
|
|
|
+ {
|
|
|
|
+ char szMaterial[16];
|
|
|
|
+ char szSerial[16];
|
|
|
|
+ }ts;
|
|
|
|
+ char txb[64], rxb[32], cmd[64];
|
|
|
|
+
|
|
|
|
+ nLenMaterial = strlen(pszMaterial);
|
|
|
|
+ nLenSerial = strlen(pszSerial);
|
|
|
|
+
|
|
|
|
+ if((nLenMaterial > 15) || (nLenSerial > 15))
|
|
|
|
+ return -1;
|
|
|
|
+
|
|
|
|
+ memcpy(ts.szMaterial, pszMaterial, nLenMaterial);
|
|
|
|
+ if(nLenMaterial < 15)
|
|
|
|
+ memset(&ts.szMaterial[nLenMaterial], ' ', 15 - nLenMaterial);
|
|
|
|
+ ts.szMaterial[15] = '\0';
|
|
|
|
+
|
|
|
|
+ memcpy(ts.szSerial, pszSerial, nLenSerial);
|
|
|
|
+ if(nLenSerial < 15)
|
|
|
|
+ memset(&ts.szSerial[nLenSerial], ' ', 15 - nLenSerial);
|
|
|
|
+ ts.szSerial[15] = '\0';
|
|
|
|
+
|
|
|
|
+ s = GfaBlmBuildCmdDataPacket("BW", 0, &ts, sizeof(ts), cmd, sizeof(cmd), false);
|
|
|
|
+ nLen = GfaMininetMasterBuildFrame(pBlm->hMst, nNodeAddr, 0, cmd, s, txb, sizeof(txb));
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterTransmitFrame(pBlm->hMst, txb, nLen)) != nLen)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ if((nRet = GfaMininetMasterReceiveFrame(pBlm->hMst, rxb, sizeof(rxb), true)) < 0)
|
|
|
|
+ return nRet;
|
|
|
|
+
|
|
|
|
+ nRet = GfaMininetMasterEvaluateSlaveResponse(pBlm->hMst, nNodeAddr, rxb, nRet, true, &nIndex);
|
|
|
|
+
|
|
|
|
+ if(nRet == MINET_SLAVE_RESPONSE_SUCCESS)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_ACK)
|
|
|
|
+ {
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ else if(nRet == MINET_SLAVE_RESPONSE_INDEX_IS_STATUS_CODE)
|
|
|
|
+ {
|
|
|
|
+ errno = -(int)nIndex;
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+HGFAMINEMST GfaBlmGetMininetMasterHandle(HGFABLM hBlm)
|
|
|
|
+{
|
|
|
|
+ if(hBlm)
|
|
|
|
+ {
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ return pBlm->hMst;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return NULL;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+int GfaBlmSetVerbosity(HGFABLM hBlm, int nVerbosity)
|
|
|
|
+{
|
|
|
|
+ if(hBlm)
|
|
|
|
+ {
|
|
|
|
+ LPGFA_BLM pBlm = (LPGFA_BLM)hBlm;
|
|
|
|
+ if(nVerbosity < 0)
|
|
|
|
+ nVerbosity = 0;
|
|
|
|
+ else if(nVerbosity > 4)
|
|
|
|
+ nVerbosity = 4;
|
|
|
|
+ pBlm->nVerbosity = nVerbosity;
|
|
|
|
+ return GfaMininetMasterSetVerbosity(pBlm->hMst, pBlm->nVerbosity);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ errno = EINVAL;
|
|
|
|
+ return -1;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/////////////////////////////////////////////////////////////////////////////
|
|
|
|
+
|
|
|
|
+uint8_t GfaBlmDataCheckSum(const void *pData, size_t nCbData)
|
|
{
|
|
{
|
|
uint8_t chk = 0;
|
|
uint8_t chk = 0;
|
|
const uint8_t *pbData = (const uint8_t*)pData;
|
|
const uint8_t *pbData = (const uint8_t*)pData;
|
|
@@ -23,11 +1445,12 @@ uint8_t GfaBLM_BU_DataCheckSum(const void *pData, size_t nCbData)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
-size_t GfaBLM_BuildCmdDataPacket(const char *pszCmd, const void *pCmdData, size_t nCbCmdData, void *pPacket, size_t nCbPacket, bool bAddLenAndCheck)
|
|
|
|
|
|
+size_t GfaBlmBuildCmdDataPacket(const char *pszCmd, uint8_t tiCmd, const void *pCmdData, size_t nCbCmdData, void *pPacket, size_t nCbPacket, bool bAddLenAndCheck)
|
|
{
|
|
{
|
|
size_t nLen = strlen(pszCmd);
|
|
size_t nLen = strlen(pszCmd);
|
|
uint8_t *pbPacket = (uint8_t*)pPacket;
|
|
uint8_t *pbPacket = (uint8_t*)pPacket;
|
|
-
|
|
|
|
|
|
+ tiCmd = tiCmd; // not yet used
|
|
|
|
+
|
|
if(nCbPacket < (nLen + nCbCmdData + ((pCmdData && nCbCmdData && bAddLenAndCheck) ? 2 : 0)))
|
|
if(nCbPacket < (nLen + nCbCmdData + ((pCmdData && nCbCmdData && bAddLenAndCheck) ? 2 : 0)))
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
@@ -39,7 +1462,7 @@ size_t GfaBLM_BuildCmdDataPacket(const char *pszCmd, const void *pCmdData, size_
|
|
if(bAddLenAndCheck)
|
|
if(bAddLenAndCheck)
|
|
{
|
|
{
|
|
*pbPacket++ = nCbCmdData + 2;
|
|
*pbPacket++ = nCbCmdData + 2;
|
|
- *pbPacket++ = GfaBLM_BU_DataCheckSum(pCmdData, nCbCmdData);
|
|
|
|
|
|
+ *pbPacket++ = GfaBlmDataCheckSum(pCmdData, nCbCmdData);
|
|
nLen += 2;
|
|
nLen += 2;
|
|
}
|
|
}
|
|
memcpy(pbPacket, pCmdData, nCbCmdData);
|
|
memcpy(pbPacket, pCmdData, nCbCmdData);
|
|
@@ -48,3 +1471,22 @@ size_t GfaBLM_BuildCmdDataPacket(const char *pszCmd, const void *pCmdData, size_
|
|
|
|
|
|
return nLen;
|
|
return nLen;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+const char* GfaBlmStrError(int nErrorCode)
|
|
|
|
+{
|
|
|
|
+ switch(nErrorCode)
|
|
|
|
+ {
|
|
|
|
+ case -COMMAND_RET_UNKNOWN_CMD:
|
|
|
|
+ return "Unknown Bootloader command";
|
|
|
|
+ case -COMMAND_RET_INVALID_CMD:
|
|
|
|
+ return "Invalid Bootloader command";
|
|
|
|
+ case -COMMAND_RET_INVALID_ADR:
|
|
|
|
+ return "Invalid Flash address";
|
|
|
|
+ case -COMMAND_RET_FLASH_FAIL:
|
|
|
|
+ return "Bootloader failed to erase flash";
|
|
|
|
+ case -COMMAND_RET_CRC_FAIL:
|
|
|
|
+ return "Invalid Image CRC32";
|
|
|
|
+ default:
|
|
|
|
+ return GfaMininetMasterStrError(nErrorCode);
|
|
|
|
+ }
|
|
|
|
+}
|