有没有人获得 TIRTOS7 NVS 热项补丁? 或者也可以是 能够在 Zigbee 3.0 (仅限)网络上获得合理性能的 APSME_SearchTCLinkKeyEntry 的修改版本。 处理 Zigbee 3.0 ZStack 时非常慢、NVS 占用了大量时间。
相关:
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
有没有人获得 TIRTOS7 NVS 热项补丁? 或者也可以是 能够在 Zigbee 3.0 (仅限)网络上获得合理性能的 APSME_SearchTCLinkKeyEntry 的修改版本。 处理 Zigbee 3.0 ZStack 时非常慢、NVS 占用了大量时间。
相关:
您好、Mathew:
鉴于 TI SDK 不实施其实现的 NVS 热项功能、您需要就此主题咨询 Aries Lord。
https://e2e.ti.com/f/1/t/1057307
https://e2e.ti.com/f/1/t/1200442
此致、
Ryan
对于我的问题的第一部分、我尝试了以下解决方案:
diff --git a/znp_CC26X2R1_LAUNCHXL_tirtos_ccs/Application/Services/nvocmp.c b/znp_CC26X2R1_LAUNCHXL_tirtos_ccs/Application/Services/nvocmp.c
index 802442d..9908941 100644
--- a/znp_CC26X2R1_LAUNCHXL_tirtos_ccs/Application/Services/nvocmp.c
+++ b/znp_CC26X2R1_LAUNCHXL_tirtos_ccs/Application/Services/nvocmp.c
@@ -207,6 +207,9 @@ Requires API's in a crc.h to implement CRC functionality.
#include "nv_linux.h"
#endif
+
+#include "zcomdef.h"
+
//*****************************************************************************
// Constants and Definitions
//*****************************************************************************
@@ -521,6 +524,13 @@ typedef struct
uint8_t hpage; // Header page
} NVOCMP_itemHdr_t;
+typedef struct {
+ uint32_t cmpid; // Compressed ID
+ uint16_t subid; // Sub ID
+ uint16_t itemid; // Item ID
+ uint8_t sysid; // System ID
+} NVOCMP_hotItem_t;
+
// Length (bytes) of compressed header
#define NVOCMP_ITEMHDRLEN 7
@@ -638,6 +648,34 @@ typedef struct
NVOCMP_compactInfo_t compactInfo;
NVOCMP_pageInfo_t pageInfo[NVOCMP_NVPAGES];
} NVOCMP_nvHandle_t;
+
+typedef struct
+{
+ bool vail;
+ uint8_t pg;
+ uint16_t ofs;
+} NVOCMP_hotNv_t;
+
+#define NVOCMP_HOT_IDS_ARRAY { \
+ {NVOCMP_CMPRID(NVINTF_SYSID_ZSTACK,ZCD_NV_EX_LEGACY,ZCD_NV_NWKKEY), {false, 0xFF, 0xFFFF}}, \
+ {NVOCMP_CMPRID(NVINTF_SYSID_ZSTACK,ZCD_NV_EX_LEGACY,ZCD_NV_NWK_ACTIVE_KEY_INFO), {false, 0xFF, 0xFFFF}}, \
+ {NVOCMP_CMPRID(NVINTF_SYSID_ZSTACK,ZCD_NV_EX_LEGACY,ZCD_NV_NWK_ALTERN_KEY_INFO), {false, 0xFF, 0xFFFF}}, \
+ {NVOCMP_CMPRID(NVINTF_SYSID_ZSTACK,ZCD_NV_EX_LEGACY,ZCD_NV_TCLK_SEED), {false, 0xFF, 0xFFFF}}, \
+ }
+
+typedef struct
+{
+ uint32_t cid;
+ NVOCMP_hotNv_t nv;
+} NVOCMP_hotId_t;
+
+
+
+NVOCMP_hotId_t NVOCMP_hotIdArray[] = NVOCMP_HOT_IDS_ARRAY;
+
+
+
+
//*****************************************************************************
// Local variables
//*****************************************************************************
@@ -695,6 +733,11 @@ static uint16_t NVOCMP_badCRCCount = 0;
NVOCMP_initAction_t gAction;
uint8_t NVOCMP_size;
+NVOCMP_hotNv_t* (*pfn_nvocmp_hotItemMatch)(NVOCMP_hotItem_t hotItem) = NULL;
+void (*pfn_nvocmp_hotItemUpdate)(uint8_t pg, uint16_t ofs, NVOCMP_hotItem_t hotItem) = NULL;
+NVOCMP_hotNv_t* (*pfn_nvocmp_hotItemMatchCont)(uint8_t sysid, uint16_t itemid, void *cBuf, uint16_t clength, uint16_t coff) = NULL;
+void (*pfn_nvocmp_hotItemUpdateCont)(NVOCMP_hotItem_t hotItem, void *cBuf, uint16_t clength, uint16_t coff) = NULL;
+
//*****************************************************************************
// NV API Function Prototypes
//*****************************************************************************
@@ -777,6 +820,11 @@ static void NVOCMP_migratePage(NVOCMP_nvHandle_t *pNvHandle, uint8_t page)
static void NVOCMP_copyItem(uint8_t srcPg, uint8_t dstPg, uint16_t sOfs, uint16_t dOfs, uint16_t len);
#endif
+static NVOCMP_hotNv_t* NVOCMP_hotItemMatch(NVOCMP_hotItem_t hotItem);
+static void NVOCMP_hotItemUpdate(uint8_t pg, uint16_t ofs, NVOCMP_hotItem_t hotItem);
+static bool NVOCMP_hotItemMatchCont(uint8_t sysid, uint16_t itemid, NVOCMP_itemInfo_t *pInfo, NVOCMP_itemHdr_t* pHdr);
+static void NVOCMP_hotItemUpdateCont(NVOCMP_hotItem_t hotItem, void *cBuf, uint16_t clength, uint16_t coff);
+
//*****************************************************************************
// Load Pointer Functions (These are declared in nvoctp.h)
//*****************************************************************************
@@ -3156,6 +3204,14 @@ static void NVOCMP_writeItem(NVOCMP_nvHandle_t *pNvHandle, NVOCMP_itemHdr_t *pHd
dLen = pHdr->len;
hOfs = dstOff + dLen;
+ // update hot ids, luoyiming 2020-05-22
+ NVOCMP_hotItem_t hotItem = {.subid = pHdr->subid, .itemid = pHdr->itemid, .sysid = pHdr->sysid};
+ hotItem.cmpid = pHdr->cmpid;
+ NVOCMP_hotItemUpdate(dstPg, dstOff, hotItem);
+
+ // update cont hot id, luoyiming 2021-11-29
+ NVOCMP_hotItemUpdateCont(hotItem, pBuf, pHdr->len, 0);
+
if (iLen <= NVOCMP_SMALLITEM)
{
// Construct item in one buffer
@@ -3649,6 +3705,51 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
#ifdef NVOCMP_GPRAM
NVOCMP_disableCache(&vm);
#endif
+ // find hot id first, luoyiming 2020-05-21
+ if( (flag & NVOCMP_FINDLMASK) == NVOCMP_FINDSTRICT )
+ {
+ NVOCMP_hotItem_t hotItem = {.subid = pHdr->subid, .itemid = pHdr->itemid, .sysid = pHdr->sysid};
+ hotItem.cmpid = cid;
+ NVOCMP_hotNv_t* pHotNv = NVOCMP_hotItemMatch(hotItem);
+ if( pHotNv )
+ {
+ NVOCMP_itemHdr_t iHdr;
+ NVOCMP_readHeader(pHotNv->pg, pHotNv->ofs, &iHdr, false);
+ if((iHdr.stats & NVOCMP_ACTIVEIDBIT) &&
+ !(iHdr.stats & NVOCMP_VALIDIDBIT))
+ {
+ if( iHdr.cmpid == cid )
+ {
+ memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t));
+#ifdef NVOCMP_GPRAM
+ NVOCMP_restoreCache(vm);
+#endif
+ return(NVINTF_SUCCESS);
+ }
+ }
+ }
+ }
+ else if((pInfo) && ((flag & NVOCMP_FINDHMASK) == NVOCMP_FINDCONTENT))
+ {
+ if( pHdr->subid == 0 )
+ {
+ NVOCMP_itemHdr_t iHdr;
+ if(true == NVOCMP_hotItemMatchCont(pHdr->sysid, pHdr->itemid, pInfo, &iHdr))
+ {
+ if(!NVOCMP_readItem(&iHdr, 0, pInfo->rlength, pInfo->rBuf, false))
+ {
+ if(!memcmp((uint8_t *)pInfo->rBuf + pInfo->coff, pInfo->cBuf, pInfo->clength))
+ {
+ memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t));
+#ifdef NVOCMP_GPRAM
+ NVOCMP_restoreCache(vm);
+#endif
+ return(NVINTF_SUCCESS);
+ }
+ }
+ }
+ }
+ }
for(p = pg; nvSearched < NVOCMP_NVSIZE; p = NVOCMP_DECPAGE(p), ofs = pNvHandle->pageInfo[p].offset)
{
@@ -3659,7 +3760,7 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
continue;
}
#endif
- NVOCMP_read(pg, 0, (uint8_t *)pTBuffer, FLASH_PAGE_SIZE);
+ NVOCMP_read(p, 0, (uint8_t *)pTBuffer, FLASH_PAGE_SIZE);
while(ofs >= (NVOCMP_PGDATAOFS + NVOCMP_ITEMHDRLEN))
{
@@ -3687,6 +3788,9 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
if (cid == iHdr.cmpid)
{
found = true;
+ NVOCMP_hotItem_t hotItem = {.subid = iHdr.subid, .itemid = iHdr.itemid, .sysid = iHdr.sysid};
+ hotItem.cmpid = iHdr.cmpid;
+ NVOCMP_hotItemUpdate(p, ofs, hotItem);
}
break;
case NVOCMP_FINDSYSID:
@@ -3719,8 +3823,14 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
{
if(!NVOCMP_readItem(&iHdr, 0, pInfo->rlength, pInfo->rBuf, false))
{
+ // update hot item when read item success.
+ NVOCMP_hotItem_t hotItem = {.subid = iHdr.subid, .itemid = iHdr.itemid, .sysid = iHdr.sysid};
+ hotItem.cmpid = iHdr.cmpid;
+ NVOCMP_hotItemUpdate(p, ofs, hotItem);
+
if(!memcmp((uint8_t *)pInfo->rBuf + pInfo->coff, pInfo->cBuf, pInfo->clength))
{
+ NVOCMP_hotItemUpdateCont(hotItem, pInfo->cBuf, pInfo->clength, pInfo->coff);
memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t));
#ifdef NVOCMP_GPRAM
NVOCMP_restoreCache(vm);
@@ -3797,6 +3907,46 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
uint16_t items = 0;
uint32_t cid = NVOCMP_CMPRID(pHdr->sysid,pHdr->itemid,pHdr->subid);
+ // find hot id first, luoyiming 2020-05-21
+ if( (flag & NVOCMP_FINDLMASK) == NVOCMP_FINDSTRICT )
+ {
+ NVOCMP_hotItem_t hotItem = {.subid = pHdr->subid, .itemid = pHdr->itemid, .sysid = pHdr->sysid};
+ hotItem.cmpid = cid;
+ NVOCMP_hotNv_t* pHotNv = NVOCMP_hotItemMatch(hotItem);
+ if( pHotNv )
+ {
+ NVOCMP_itemHdr_t iHdr;
+ NVOCMP_readHeader(pHotNv->pg, pHotNv->ofs, &iHdr, false);
+ if((iHdr.stats & NVOCMP_ACTIVEIDBIT) &&
+ !(iHdr.stats & NVOCMP_VALIDIDBIT))
+ {
+ if( iHdr.cmpid == cid )
+ {
+ memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t));
+ return(NVINTF_SUCCESS);
+ }
+ }
+ }
+ }
+ else if((pInfo) && ((flag & NVOCMP_FINDHMASK) == NVOCMP_FINDCONTENT))
+ {
+ if( pHdr->subid == 0 )
+ {
+ NVOCMP_itemHdr_t iHdr;
+ if(true == NVOCMP_hotItemMatchCont(pHdr->sysid, pHdr->itemid, pInfo, &iHdr))
+ {
+ if(!NVOCMP_readItem(&iHdr, 0, pInfo->rlength, pInfo->rBuf, false))
+ {
+ if(!memcmp((uint8_t *)pInfo->rBuf + pInfo->coff, pInfo->cBuf, pInfo->clength))
+ {
+ memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t));
+ return(NVINTF_SUCCESS);
+ }
+ }
+ }
+ }
+ }
+
#if (NVOCMP_NVPAGES > NVOCMP_NVTWOP)
uint16_t nvSearched = 0;
for(p = pg; nvSearched < NVOCMP_NVSIZE; p = NVOCMP_DECPAGE(p), ofs = pNvHandle->pageInfo[p].offset)
@@ -3833,6 +3983,9 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
if (cid == iHdr.cmpid)
{
found = true;
+ NVOCMP_hotItem_t hotItem = {.subid = iHdr.subid, .itemid = iHdr.itemid, .sysid = iHdr.sysid};
+ hotItem.cmpid = iHdr.cmpid;
+ NVOCMP_hotItemUpdate(p, ofs, hotItem);
}
break;
case NVOCMP_FINDSYSID:
@@ -3862,8 +4015,14 @@ static int8_t NVOCMP_findItem(NVOCMP_nvHandle_t *pNvHandle, uint8_t pg, uint16_t
{
if(!NVOCMP_readItem(&iHdr, 0, pInfo->rlength, pInfo->rBuf, false))
{
+ // update hot item when read item success.
+ NVOCMP_hotItem_t hotItem = {.subid = iHdr.subid, .itemid = iHdr.itemid, .sysid = iHdr.sysid};
+ hotItem.cmpid = iHdr.cmpid;
+ NVOCMP_hotItemUpdate(p, ofs, hotItem);
+
if(!memcmp((uint8_t *)pInfo->rBuf + pInfo->coff, pInfo->cBuf, pInfo->clength))
{
+ NVOCMP_hotItemUpdateCont(hotItem, pInfo->cBuf, pInfo->clength, pInfo->coff);
memcpy(pHdr, &iHdr, sizeof(NVOCMP_itemHdr_t));
return(NVINTF_SUCCESS);
}
@@ -5028,6 +5187,119 @@ static uint8_t NVOCMP_verifyCRC(uint16_t iOfs, uint16_t len, uint8_t crc, uint8_
return(newCRC == crc ? NVINTF_SUCCESS : NVINTF_CORRUPT);
}
+/*********************************************************************
+ * @fn hotItemMatch
+ *
+ * @brief Look for the parameter 'id' in the hot items array.
+ *
+ * @param hotItem - A valid NV item.
+ *
+ * @return A valid index into the hot items if the item is hot; OSAL_NV_MAX_HOT if not.
+ */
+static NVOCMP_hotNv_t* NVOCMP_hotItemMatch(NVOCMP_hotItem_t hotItem)
+{
+ uint8_t nvNum = sizeof(NVOCMP_hotIdArray)/sizeof(NVOCMP_hotId_t);
+ uint8_t n;
+ for ( n=0; n<nvNum; n++ )
+ {
+ if( (hotItem.cmpid == NVOCMP_hotIdArray[n].cid) && (NVOCMP_hotIdArray[n].nv.vail == true) )
+ {
+ return &NVOCMP_hotIdArray[n].nv;
+ }
+ }
+
+ if( pfn_nvocmp_hotItemMatch )
+ {
+ return pfn_nvocmp_hotItemMatch(hotItem);
+ }
+ return NULL;
+}
+
+/*********************************************************************
+ * @fn hotItemUpdate
+ *
+ * @brief If the parameter 'id' is a hot item, update the corresponding hot item data.
+ *
+ * @param pg - The new NV page corresponding to the hot item.
+ * @param off - The new NV page offset corresponding to the hot item.
+ * @param hotItem - A valid NV item.
+ *
+ * @return none
+ */
+static void NVOCMP_hotItemUpdate(uint8_t pg, uint16_t ofs, NVOCMP_hotItem_t hotItem)
+{
+ uint8_t nvNum = sizeof(NVOCMP_hotIdArray)/sizeof(NVOCMP_hotId_t);
+ uint8_t n;
+ for ( n=0; n<nvNum; n++ )
+ {
+ if( hotItem.cmpid == NVOCMP_hotIdArray[n].cid )
+ {
+ NVOCMP_hotIdArray[n].nv.pg = pg;
+ NVOCMP_hotIdArray[n].nv.ofs = ofs;
+ NVOCMP_hotIdArray[n].nv.vail = true;
+ return;
+ }
+ }
+
+ if( pfn_nvocmp_hotItemUpdate )
+ {
+ pfn_nvocmp_hotItemUpdate(pg, ofs, hotItem);
+ }
+}
+
+/*********************************************************************
+ * @fn NVOCMP_hotItemMatchCont
+ *
+ * @brief lookup NV in hot item when comparing content.
+ *
+ * @param sysid - The sysid of item.
+ * @param itemid - The itemid of hot item.
+ * @param pInfo - pointer to item info.
+ * @param pHdr - pointer to item header
+ *
+ * @return none
+ */
+static bool NVOCMP_hotItemMatchCont(uint8_t sysid, uint16_t itemid, NVOCMP_itemInfo_t *pInfo, NVOCMP_itemHdr_t* pHdr)
+{
+ NVOCMP_hotNv_t* hotNv = NULL;
+ if( pfn_nvocmp_hotItemMatchCont )
+ {
+ hotNv = pfn_nvocmp_hotItemMatchCont(sysid, itemid, pInfo->cBuf, pInfo->clength, pInfo->coff);
+ if( hotNv )
+ {
+ NVOCMP_readHeader(hotNv->pg, hotNv->ofs, pHdr, false);
+ if((pHdr->stats & NVOCMP_ACTIVEIDBIT) && !(pHdr->stats & NVOCMP_VALIDIDBIT))
+ {
+ if((pHdr->sysid == sysid) && (pHdr->itemid == itemid))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/*********************************************************************
+ * @fn NVOCMP_hotItemUpdateCont
+ *
+ * @brief Update hot item that it can be lookup faster when comparing content.
+ *
+ * @param hotItem - The hot item.
+ * @param cBuf - pointer to caller's read data buffer
+ * @param clen - length of NV data to return
+ * @param coff - offset of content in data
+ *
+ * @return none
+ */
+static void NVOCMP_hotItemUpdateCont(NVOCMP_hotItem_t hotItem, void *cBuf, uint16_t clength, uint16_t coff)
+{
+ if( pfn_nvocmp_hotItemUpdateCont )
+ {
+ pfn_nvocmp_hotItemUpdateCont(hotItem, cBuf, clength, coff);
+ }
+}
+
#ifdef ENABLE_SANITY_CHECK
/******************************************************************************
* @fn NVOCMP_sanityCheckApi
@@ -5054,7 +5326,16 @@ static uint32_t NVOCMP_sanityCheckApi (void)
uint8_t srcPg;
uint32_t ret = NVINTF_SUCCESS;
uint32_t aItem=0;
+#ifdef NVOCMP_GPRAM
+ uint32_t vm;
+ uint8_t *pTBuffer = RAM_BUFFER_ADDRESS;
+#else
+ uint8_t *pTBuffer = (uint8_t *)tBuffer;
+#endif
+#ifndef NVOCMP_GPRAM
+ memset(tBuffer, 0, sizeof(tBuffer));
+#endif
// Reset Flash erase/write fail indicator
NVOCMP_failW = NVINTF_SUCCESS;
@@ -5075,6 +5356,9 @@ static uint32_t NVOCMP_sanityCheckApi (void)
NVOCMP_ALERT(false, "Sanity Check")
+#ifdef NVOCMP_GPRAM
+ NVOCMP_disableCache(&vm);
+#endif
while(srcOff > endOff)
{
if(NVOCMP_failW == NVINTF_SUCCESS)
@@ -5144,6 +5428,12 @@ static uint32_t NVOCMP_sanityCheckApi (void)
{
if(!needSkip)
{
+ // Get block of bytes from source page
+#if NVOCMP_COMPR
+ NVOCMP_read(srcPg, crcOff, (uint8_t *)(pTBuffer + dstOff), itemSize);
+#else
+ NVOCMP_read(srcPg, crcOff, (uint8_t *)(pTBuffer + FLASH_PAGE_SIZE - dstOff - itemSize), itemSize);
+#endif
dstOff += itemSize;
aItem++;
}
@@ -5153,6 +5443,9 @@ static uint32_t NVOCMP_sanityCheckApi (void)
}
else
{
+#ifdef NVOCMP_GPRAM
+ NVOCMP_restoreCache(vm);
+#endif
// Failure during item xfer makes next findItem() unreliable
NVOCMP_ASSERT(false, "SANITY CHECK FAILURE")
ret |= (1 << NVINTF_FAILURE);
@@ -5161,11 +5454,18 @@ static uint32_t NVOCMP_sanityCheckApi (void)
if(NVOCMP_failW != NVINTF_SUCCESS)
{
+#ifdef NVOCMP_GPRAM
+ NVOCMP_restoreCache(vm);
+#endif
// Something bad happened when scanning the page
NVOCMP_ASSERT(false, "SANITY CHECK FAILURE")
ret |= (1 << NVINTF_FAILURE);
}
+#ifdef NVOCMP_GPRAM
+ NVOCMP_restoreCache(vm);
+#endif
+
return(ret);
}
#endif
如果有人尝试了第二部分(TCLK 表内存缓存)、我欢迎您的贡献。